Introduzione alle variabili

Visualizza su TensorFlow.org Esegui in Google Colab Visualizza l'origine su GitHub Scarica quaderno

Una variabile TensorFlow è il modo consigliato per rappresentare lo stato condiviso e persistente manipolato dal programma. Questa guida spiega come creare, aggiornare e gestire istanze di tf.Variable in TensorFlow.

Le variabili vengono create e tracciate tramite la classe tf.Variable . Una tf.Variable rappresenta un tensore il cui valore può essere modificato eseguendo operazioni su di esso. Ops specifici consentono di leggere e modificare i valori di questo tensore. Le librerie di livello superiore come tf.keras usano tf.Variable per memorizzare i parametri del modello.

Impostare

Questo quaderno discute il posizionamento delle variabili. Se vuoi vedere su quale dispositivo sono posizionate le tue variabili, decommenta questa riga.

import tensorflow as tf

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

Crea una variabile

Per creare una variabile, fornire un valore iniziale. La tf.Variable avrà lo stesso dtype del valore di inizializzazione.

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])

Una variabile appare e agisce come un tensore e, in effetti, è una struttura di dati supportata da un tf.Tensor . Come i tensori, hanno un dtype e una forma e possono essere esportati in 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 maggior parte delle operazioni sui tensori funzionano sulle variabili come previsto, sebbene le variabili non possano essere rimodellate.

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)

Come notato sopra, le variabili sono supportate da tensori. Puoi riassegnare il tensore usando tf.Variable.assign . Chiamare assign non (di solito) alloca un nuovo tensore; viene invece riutilizzata la memoria del tensore esistente.

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

Se usi una variabile come un tensore nelle operazioni, di solito opererai sul tensore di supporto.

La creazione di nuove variabili da variabili esistenti duplica i tensori di supporto. Due variabili non condivideranno la stessa memoria.

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.]

Cicli di vita, denominazione e visualizzazione

In TensorFlow basato su Python, l'istanza tf.Variable ha lo stesso ciclo di vita di altri oggetti Python. Quando non ci sono riferimenti a una variabile, questa viene automaticamente deallocata.

È anche possibile nominare variabili che possono aiutarti a tracciarle ed eseguirne il debug. È possibile assegnare lo stesso nome a due variabili.

# 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)

I nomi delle variabili vengono mantenuti durante il salvataggio e il caricamento dei modelli. Per impostazione predefinita, le variabili nei modelli acquisiranno automaticamente nomi di variabili univoci, quindi non è necessario assegnarli da soli a meno che non lo si desideri.

Sebbene le variabili siano importanti per la differenziazione, alcune variabili non dovranno essere differenziate. Puoi disattivare i gradienti per una variabile impostando trainable su false al momento della creazione. Un esempio di una variabile che non avrebbe bisogno di gradienti è un contatore di passi di addestramento.

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

Posizionamento di variabili e tensori

Per prestazioni migliori, TensorFlow tenterà di posizionare tensori e variabili sul dispositivo più veloce compatibile con il suo dtype . Ciò significa che la maggior parte delle variabili vengono posizionate su una GPU, se disponibile.

Tuttavia, puoi ignorarlo. In questo frammento di codice, posiziona un tensore float e una variabile sulla CPU, anche se è disponibile una GPU. Attivando la registrazione del posizionamento del dispositivo (vedi Configurazione ), puoi vedere dove è posizionata la variabile.

Se esegui questo notebook su backend diversi con e senza GPU, vedrai una registrazione diversa. Tieni presente che il posizionamento del dispositivo di registrazione deve essere attivato all'inizio della sessione.

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)

È possibile impostare la posizione di una variabile o di un tensore su un dispositivo ed eseguire il calcolo su un altro dispositivo. Ciò introdurrà un ritardo, poiché i dati devono essere copiati tra i dispositivi.

Potresti farlo, tuttavia, se avessi più lavoratori GPU ma desideri solo una copia delle variabili.

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)

Per ulteriori informazioni sulla formazione distribuita, consulta la nostra guida .

Prossimi passi

Per capire come vengono utilizzate tipicamente le variabili, consulta la nostra guida sulla differenziazione automatica .