Cette page a été traduite par l'API Cloud Translation.
Switch to English

Introduction aux variables

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

Une variable TensorFlow est le moyen recommandé pour représenter l'état partagé et persistant que votre programme manipule. 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 des opérations dessus. Des opérations spécifiques vous permettent de lire et de modifier les valeurs de ce tenseur. Les bibliothèques de niveau supérieur comme tf.keras utilisent tf.Variable pour stocker les paramètres du modèle.

Installer

Ce cahier 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, indiquez 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 de tf.Variable.assign . L'appel de 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: Shapes (2,) and (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 visualisation

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 pas de références à 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 variable sont conservés lors de l'enregistrement et du chargement des modèles. Par défaut, les variables des modèles acquièrent 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 dégradés 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'apprentissage.

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

Placer des variables et des tenseurs

Pour de meilleures performances, TensorFlow tentera de placer des tenseurs et des variables sur le périphérique 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 le remplacer. 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 des périphériques (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 des périphériques 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 .