Переменные и константы 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. Примеры могут быть не очень практичными, но я надеюсь, что это устранит путаницу.