Introduction aux variables

Voir sur TensorFlow.org Exécuter dans Google Colab Voir la source sur GitHub Télécharger le cahier

Une variable TensorFlow est la méthode recommandée pour représenter l'état partagé et persistant manipulé par votre programme. Ce guide explique comment créer, mettre à jour et gérer des instances de tf.Variable dans TensorFlow.

Les variables sont créées et suivies via la classe tf.Variable . Un tf.Variable représente un tenseur dont la valeur peut être modifiée en exécutant ops dessus. Des opérations spécifiques permettent de lire et de modifier les valeurs de ce tenseur. Les bibliothèques de niveau supérieur telles que tf.keras utilisent tf.Variable pour stocker les paramètres du modèle.

Installer

Ce bloc-notes traite du placement des variables. Si vous voulez voir sur quel appareil vos variables sont placées, décommentez cette ligne.

import tensorflow as tf

# Uncomment to see where your variables get placed (see below)
# tf.debugging.set_log_device_placement(True)

Créer une variable

Pour créer une variable, fournissez une valeur initiale. La tf.Variable aura le même dtype que la valeur d'initialisation.

my_tensor = tf.constant([[1.0, 2.0], [3.0, 4.0]])
my_variable = tf.Variable(my_tensor)

# Variables can be all kinds of types, just like tensors
bool_variable = tf.Variable([False, False, False, True])
complex_variable = tf.Variable([5 + 4j, 6 + 1j])

Une variable ressemble et agit comme un tenseur, et, en fait, est une structure de données soutenue par un tf.Tensor . Comme les tenseurs, ils ont un dtype et une forme, et peuvent être exportés vers NumPy.

print("Shape: ", my_variable.shape)
print("DType: ", my_variable.dtype)
print("As NumPy: ", my_variable.numpy())
Shape:  (2, 2)
DType:  <dtype: 'float32'>
As NumPy:  [[1. 2.]
 [3. 4.]]

La plupart des opérations tensorielles fonctionnent sur les variables comme prévu, bien que les variables ne puissent pas être remodelées.

print("A variable:", my_variable)
print("\nViewed as a tensor:", tf.convert_to_tensor(my_variable))
print("\nIndex of highest value:", tf.argmax(my_variable))

# This creates a new tensor; it does not reshape the variable.
print("\nCopying and reshaping: ", tf.reshape(my_variable, [1,4]))
A variable: <tf.Variable 'Variable:0' shape=(2, 2) dtype=float32, numpy=
array([[1., 2.],
       [3., 4.]], dtype=float32)>

Viewed as a tensor: tf.Tensor(
[[1. 2.]
 [3. 4.]], shape=(2, 2), dtype=float32)

Index of highest value: tf.Tensor([1 1], shape=(2,), dtype=int64)

Copying and reshaping:  tf.Tensor([[1. 2. 3. 4.]], shape=(1, 4), dtype=float32)

Comme indiqué ci-dessus, les variables sont soutenues par des tenseurs. Vous pouvez réaffecter le tenseur à l'aide tf.Variable.assign . Appeler assign n'alloue pas (généralement) un nouveau tenseur ; à la place, la mémoire du tenseur existant est réutilisée.

a = tf.Variable([2.0, 3.0])
# This will keep the same dtype, float32
a.assign([1, 2]) 
# Not allowed as it resizes the variable: 
try:
  a.assign([1.0, 2.0, 3.0])
except Exception as e:
  print(f"{type(e).__name__}: {e}")
ValueError: Cannot assign to variable Variable:0 due to variable shape (2,) and value shape (3,) are incompatible

Si vous utilisez une variable comme un tenseur dans les opérations, vous opérerez généralement sur le tenseur de support.

La création de nouvelles variables à partir de variables existantes duplique les tenseurs de support. Deux variables ne partageront pas la même mémoire.

a = tf.Variable([2.0, 3.0])
# Create b based on the value of a
b = tf.Variable(a)
a.assign([5, 6])

# a and b are different
print(a.numpy())
print(b.numpy())

# There are other versions of assign
print(a.assign_add([2,3]).numpy())  # [7. 9.]
print(a.assign_sub([7,9]).numpy())  # [0. 0.]
[5. 6.]
[2. 3.]
[7. 9.]
[0. 0.]

Cycles de vie, dénomination et surveillance

Dans TensorFlow basé sur Python, l'instance tf.Variable a le même cycle de vie que les autres objets Python. Lorsqu'il n'y a aucune référence à une variable, elle est automatiquement désallouée.

Les variables peuvent également être nommées, ce qui peut vous aider à les suivre et à les déboguer. Vous pouvez donner le même nom à deux variables.

# Create a and b; they will have the same name but will be backed by
# different tensors.
a = tf.Variable(my_tensor, name="Mark")
# A new variable with the same name, but different value
# Note that the scalar add is broadcast
b = tf.Variable(my_tensor + 1, name="Mark")

# These are elementwise-unequal, despite having the same name
print(a == b)
tf.Tensor(
[[False False]
 [False False]], shape=(2, 2), dtype=bool)

Les noms de variables sont conservés lors de l'enregistrement et du chargement des modèles. Par défaut, les variables des modèles acquerront automatiquement des noms de variables uniques, vous n'avez donc pas besoin de les affecter vous-même, sauf si vous le souhaitez.

Bien que les variables soient importantes pour la différenciation, certaines variables n'auront pas besoin d'être différenciées. Vous pouvez désactiver les gradients pour une variable en définissant trainable sur false lors de la création. Un exemple de variable qui n'aurait pas besoin de gradients est un compteur de pas d'entraînement.

step_counter = tf.Variable(1, trainable=False)

Placer des variables et des tenseurs

Pour de meilleures performances, TensorFlow tentera de placer des Tensors et des variables sur l'appareil le plus rapide compatible avec son dtype . Cela signifie que la plupart des variables sont placées sur un GPU s'il en existe un.

Cependant, vous pouvez remplacer cela. Dans cet extrait, placez un tenseur flottant et une variable sur le CPU, même si un GPU est disponible. En activant la journalisation du placement de l'appareil (voir Configuration ), vous pouvez voir où la variable est placée.

Si vous exécutez ce notebook sur différents backends avec et sans GPU, vous verrez une journalisation différente. Notez que le placement du périphérique de journalisation doit être activé au début de la session.

with tf.device('CPU:0'):

  # Create some tensors
  a = tf.Variable([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
  b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
  c = tf.matmul(a, b)

print(c)
tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32)

Il est possible de définir l'emplacement d'une variable ou d'un tenseur sur un appareil et d'effectuer le calcul sur un autre appareil. Cela introduira un retard, car les données doivent être copiées entre les appareils.

Cependant, vous pouvez le faire si vous avez plusieurs nœuds de calcul GPU mais que vous ne souhaitez qu'une seule copie des variables.

with tf.device('CPU:0'):
  a = tf.Variable([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
  b = tf.Variable([[1.0, 2.0, 3.0]])

with tf.device('GPU:0'):
  # Element-wise multiply
  k = a * b

print(k)
tf.Tensor(
[[ 1.  4.  9.]
 [ 4. 10. 18.]], shape=(2, 3), dtype=float32)

Pour en savoir plus sur la formation distribuée, consultez notre guide .

Prochaines étapes

Pour comprendre comment les variables sont généralement utilisées, consultez notre guide sur la différenciation automatique .