Посмотреть на 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)
Подробнее о распределенном обучении см. в нашем руководстве .
Следующие шаги
Чтобы понять, как обычно используются переменные, ознакомьтесь с нашим руководством по автоматическому дифференцированию .