Wprowadzenie do zmiennych

Zobacz na TensorFlow.org Uruchom w Google Colab Wyświetl źródło na GitHub Pobierz notatnik

Zmienna TensorFlow jest zalecanym sposobem reprezentowania współdzielonego, trwałego stanu, którym manipuluje program. Ten przewodnik opisuje, jak tworzyć, aktualizować i zarządzać instancjami tf.Variable w TensorFlow.

Zmienne są tworzone i śledzone za pośrednictwem klasy tf.Variable . tf.Variable reprezentuje tensor, którego wartość można zmienić, uruchamiając na nim operacje. Poszczególne operacje umożliwiają odczytywanie i modyfikowanie wartości tego tensora. Biblioteki wyższego poziomu, takie jak tf.keras używają tf.Variable do przechowywania parametrów modelu.

Ustawiać

W tym notatniku omówiono zmienne rozmieszczenie. Jeśli chcesz zobaczyć, na jakim urządzeniu są umieszczone Twoje zmienne, odkomentuj tę linię.

import tensorflow as tf

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

Utwórz zmienną

Aby utworzyć zmienną, podaj wartość początkową. tf.Variable będzie miała taki sam dtype jak wartość inicjująca.

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

Zmienna wygląda i zachowuje się jak tensor i w rzeczywistości jest strukturą danych wspieraną przez tf.Tensor . Podobnie jak tensory mają dtype i kształt i mogą być eksportowane do 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.]]

Większość operacji tensorowych działa na zmiennych zgodnie z oczekiwaniami, chociaż zmiennych nie można zmieniać.

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)

Jak wspomniano powyżej, zmienne są wspierane przez tensory. Możesz ponownie przypisać tensor za pomocą tf.Variable.assign . Wywołanie assign nie przydziela (zwykle) nowego tensora; zamiast tego używana jest ponownie istniejąca pamięć tensora.

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

Jeśli używasz zmiennej, takiej jak tensor w operacjach, zwykle będziesz operować na tensorze zapasowym.

Tworzenie nowych zmiennych z istniejących zmiennych duplikuje tensory zapasowe. Dwie zmienne nie będą współdzielić tej samej pamięci.

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

Cykle życia, nazewnictwo i oglądanie

W TensorFlow opartym na Pythonie instancja tf.Variable ma taki sam cykl życia jak inne obiekty Pythona. Gdy nie ma odwołań do zmiennej, jest ona automatycznie zwalniana.

Zmienne można również nazywać, co może pomóc w ich śledzeniu i debugowaniu. Możesz nadać dwóm zmiennym tę samą nazwę.

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

Nazwy zmiennych są zachowywane podczas zapisywania i ładowania modeli. Domyślnie zmienne w modelach automatycznie uzyskują unikalne nazwy zmiennych, więc nie musisz przypisywać ich samodzielnie, chyba że chcesz.

Chociaż zmienne są ważne dla różnicowania, niektóre zmienne nie będą musiały być różnicowane. Gradienty można wyłączyć dla zmiennej, ustawiając podczas tworzenia wartość do trainable na fałsz. Przykładem zmiennej, która nie wymagałaby gradientów, jest treningowy licznik kroków.

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

Umieszczanie zmiennych i tensorów

Aby uzyskać lepszą wydajność, TensorFlow spróbuje umieścić tensory i zmienne na najszybszym urządzeniu zgodnym z jego dtype . Oznacza to, że większość zmiennych jest umieszczana na GPU, jeśli jest dostępna.

Możesz to jednak zmienić. W tym fragmencie umieść tensor zmiennoprzecinkowy i zmienną na procesorze, nawet jeśli dostępny jest procesor graficzny. Włączając rejestrowanie rozmieszczenia urządzeń (patrz Konfiguracja ), możesz zobaczyć, gdzie znajduje się zmienna.

Jeśli uruchomisz ten notatnik na różnych backendach z procesorem graficznym i bez, zobaczysz inne rejestrowanie. Należy pamiętać, że umieszczenie urządzenia rejestrującego musi być włączone na początku sesji.

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)

Możliwe jest ustawienie lokalizacji zmiennej lub tensora na jednym urządzeniu i wykonanie obliczeń na innym urządzeniu. Wprowadzi to opóźnienie, ponieważ dane muszą być kopiowane między urządzeniami.

Możesz to jednak zrobić, jeśli masz wielu procesów roboczych GPU, ale potrzebujesz tylko jednej kopii zmiennych.

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)

Więcej informacji na temat szkoleń rozproszonych znajdziesz w naszym przewodniku .

Następne kroki

Aby dowiedzieć się, jak zwykle używane są zmienne, zapoznaj się z naszym przewodnikiem po automatycznym różnicowaniu .