Введение в переменные

Посмотреть на TensorFlow.org Запустить в Google Colab Посмотреть исходный код на GitHub Скачать блокнот

Переменная TensorFlow — это рекомендуемый способ представления общего постоянного состояния, которым манипулирует ваша программа. В этом руководстве рассказывается, как создавать, обновлять и управлять экземплярами tf.Variable в TensorFlow.

Переменные создаются и отслеживаются с помощью класса tf.Variable . tf.Variable представляет собой тензор, значение которого можно изменить, запустив над ним операции. Конкретные операции позволяют читать и изменять значения этого тензора. Библиотеки более высокого уровня, такие как tf.keras используют tf.Variable для хранения параметров модели.

Настраивать

В этом блокноте обсуждается размещение переменных. Если вы хотите увидеть, на каком устройстве размещены ваши переменные, раскомментируйте эту строку.

import tensorflow as tf

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

Создать переменную

Чтобы создать переменную, укажите начальное значение. tf.Variable будет иметь тот же dtype , что и значение инициализации.

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

Переменная выглядит и действует как тензор и, по сути, является структурой данных, поддерживаемой tf.Tensor . Как и у тензоров, у них есть dtype и форма, и их можно экспортировать в 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.]]

Большинство тензорных операций работают с переменными, как и ожидалось, хотя переменные не могут быть изменены.

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)

Как отмечалось выше, переменные поддерживаются тензорами. Вы можете переназначить тензор, используя tf.Variable.assign . Вызов assign (обычно) не выделяет новый тензор; вместо этого повторно используется существующая память тензора.

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

Если вы используете переменную, такую ​​как тензор, в операциях, вы обычно будете оперировать тензором поддержки.

Создание новых переменных из существующих переменных дублирует резервные тензоры. Две переменные не будут использовать одну и ту же память.

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

Жизненные циклы, именование и просмотр

В TensorFlow на основе Python экземпляр tf.Variable имеет тот же жизненный цикл, что и другие объекты Python. Когда нет ссылок на переменную, она автоматически освобождается.

Переменные также могут быть названы, что может помочь вам отслеживать и отлаживать их. Вы можете дать двум переменным одно и то же имя.

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

Имена переменных сохраняются при сохранении и загрузке моделей. По умолчанию переменные в моделях автоматически получают уникальные имена переменных, поэтому вам не нужно назначать их самостоятельно, если вы этого не хотите.

Хотя переменные важны для дифференциации, некоторые переменные не нуждаются в дифференциации. Вы можете отключить градиенты для переменной, установив для trainable значение false при создании. Примером переменной, которой не нужны градиенты, является счетчик шагов обучения.

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

Размещение переменных и тензоров

Для повышения производительности TensorFlow попытается разместить тензоры и переменные на самом быстром устройстве, совместимом с его dtype . Это означает, что большинство переменных размещаются на графическом процессоре, если он доступен.

Однако вы можете переопределить это. В этом фрагменте поместите тензор с плавающей запятой и переменную в процессор, даже если доступен графический процессор. Включив ведение журнала размещения устройств (см. Настройка ), вы сможете увидеть, где находится переменная.

Если вы запустите этот блокнот на разных серверах с графическим процессором и без него, вы увидите разные журналы. Обратите внимание, что размещение регистрирующих устройств должно быть включено в начале сеанса.

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)

Можно установить местоположение переменной или тензора на одном устройстве и выполнить вычисления на другом устройстве. Это приведет к задержке, так как данные необходимо копировать между устройствами.

Однако вы можете сделать это, если у вас есть несколько рабочих процессов GPU, но вам нужна только одна копия переменных.

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)

Подробнее о распределенном обучении см. в нашем руководстве .

Следующие шаги

Чтобы понять, как обычно используются переменные, ознакомьтесь с нашим руководством по автоматическому дифференцированию .