Переменные и константы TensorFlow
Я новичок в tensorflow, я не могу понять разницу в переменной и константе, я понимаю, что мы используем переменные для уравнений и констант для прямых значений, но почему код № 1 работает только и почему не код # 2 и № 3, и, пожалуйста, объясните, в каких случаях мы должны сначала запустить наш график (а), а затем нашу переменную (b), т.е.
(a) session.run(model)
(b) print(session.run(y))
и в этом случае я могу непосредственно выполнить эту команду
iee
print(session.run(y))
Код №1:
x = tf.constant(35, name='x')
y = tf.Variable(x + 5, name='y')
model = tf.global_variables_initializer()
with tf.Session() as session:
session.run(model)
print(session.run(y))
Код №2:
x = tf.Variable(35, name='x')
y = tf.Variable(x + 5, name='y')
model = tf.global_variables_initializer()
with tf.Session() as session:
session.run(model)
print(session.run(y))
Код № 3:
x = tf.constant(35, name='x')
y = tf.constant(x + 5, name='y')
model = tf.global_variables_initializer()
with tf.Session() as session:
session.run(model)
print(session.run(y))
Ответы
Ответ 1
В TensorFlow различия между константами и переменными заключаются в том, что когда вы объявляете некоторую константу, ее значение не может быть изменено в будущем (также инициализация должна быть со значением, а не с операцией).
Тем не менее, когда вы объявляете переменную, вы можете изменить ее значение в будущем с помощью метода tf.assign() (и инициализация может быть достигнута с помощью значения или операции).
Функция tf.global_variables_initializer() инициализирует все переменные в вашем коде значением, переданным в качестве параметра, но работает в асинхронном режиме, поэтому не работает должным образом, когда существуют зависимости между переменными.
Ваш первый код (# 1) работает правильно, потому что нет никакой зависимости от инициализации переменной, а константа создается со значением.
Второй код (# 2) не работает из-за асинхронного поведения tf.global_variables_initializer()
. Вы можете исправить это с помощью tf.variables_initializer() следующим образом:
x = tf.Variable(35, name='x')
model_x = tf.variables_initializer([x])
y = tf.Variable(x + 5, name='y')
model_y = tf.variables_initializer([y])
with tf.Session() as session:
session.run(model_x)
session.run(model_y)
print(session.run(y))
Третий код (# 3) не работает должным образом, потому что вы пытаетесь инициализировать константу с помощью операции, что невозможно. Для ее решения подходящей стратегией является (# 1).
Относительно вашего последнего вопроса. Вам нужно запустить (a) session.run(model)
когда в вашем графике расчетов есть переменные (b) print(session.run(y))
.
Ответ 2
Я укажу разницу при использовании нетерпеливого исполнения.
Начиная с Tensorflow 2.0.b1, Variables
и Constant
вызывают различные tf.GradientTape
поведения при использовании tf.GradientTape
. Как ни странно, официальный документ недостаточно устен об этом.
Давайте посмотрим на пример кода в https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/GradientTape
x = tf.constant(3.0)
with tf.GradientTape(persistent=True) as g:
g.watch(x)
y = x * x
z = y * y
dz_dx = g.gradient(z, x) # 108.0 (4*x^3 at x = 3)
dy_dx = g.gradient(y, x) # 6.0
del g # Drop the reference to the tape
Вы должны были смотреть x
который является Constant
. GradientTape
НЕ автоматически отслеживает константы в контексте. Кроме того, он может смотреть только один тензор на GradientTape
. Если вы хотите получить градиенты нескольких Constant
, вам нужно вложить GradientTape
s. Например,
x = tf.constant(3.0)
x2 = tf.constant(3.0)
with tf.GradientTape(persistent=True) as g:
g.watch(x)
with tf.GradientTape(persistent=True) as g2:
g2.watch(x2)
y = x * x
y2 = y * x2
dy_dx = g.gradient(y, x) # 6
dy2_dx2 = g2.gradient(y2, x2) # 9
del g, g2 # Drop the reference to the tape
С другой стороны, Variable
автоматически отслеживается GradientTape
.
По умолчанию GradientTape будет автоматически отслеживать любые обучаемые переменные, доступ к которым осуществляется внутри контекста. Источник: https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/GradientTape
Таким образом, выше будет выглядеть,
x = tf.Variable(3.0)
x2 = tf.Variable(3.0)
with tf.GradientTape(persistent=True) as g:
y = x * x
y2 = y * x2
dy_dx = g.gradient(y, x) # 6
dy2_dx2 = g.gradient(y2, x2) # 9
del g # Drop the reference to the tape
print(dy_dx)
print(dy2_dx2)
Конечно, вы можете отключить автоматическое наблюдение, передавая watch_accessed_variables=False
. Примеры могут быть не очень практичными, но я надеюсь, что это устранит путаницу.