Разница между v.assign (v + 1) и v = v + 1 в тензорном потоке - PullRequest
0 голосов
/ 04 июля 2018

Следующий код Tensorflow работает нормально, и v1 становится [1., 1., 1.]

v1 = tf.get_variable('v1', shape=[3], initializer=tf.zeros_initializer)
v1 = v1 + 1 

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print (v1.eval())

Следующий сегмент кода также дает нам тот же результат, что и выше. v1 становится [1., 1., 1.], если мы запускаем sess.run(inc_v1).

v1 = tf.get_variable('v1', shape=[3], initializer=tf.zeros_initializer)
inc_v1 = v1.assign(v1 + 1)


with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    sess.run(inc_v1)
    print (v1.eval())

Однако следующий код вызывает ошибку.

v1 = tf.get_variable('v1', shape=[3], initializer=tf.zeros_initializer)
v1 = v1 + 1 
inc_v1 = v1.assign(v1 + 1)


with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    sess.run(inc_v1)
    print (v1.eval())

Ошибка выглядит следующим образом:

AttributeError: 'Tensor' object has no attribute 'assign'

Не могли бы вы сказать мне, почему это вызывает ошибку?

1 Ответ

0 голосов
/ 04 июля 2018

Тензорные и переменные - это разные объекты в TensorFlow

import tensorflow as tf


def inspect(t):
    print('\n %s\n-------' % t.name)
    print(type(t))
    print(t.op.outputs)
    print('has assign method' if 'assign' in dir(t) else 'has no assign method')


v1 = tf.get_variable('v1', shape=[3], initializer=tf.zeros_initializer)
inspect(v1)
v2 = v1 + 1
inspect(v2)

дает

 v1:0
-------
<class 'tensorflow.python.ops.variables.Variable'>
[<tf.Tensor 'v1:0' shape=(3,) dtype=float32_ref>]
has assign method

 add:0
-------
<class 'tensorflow.python.framework.ops.Tensor'>
[<tf.Tensor 'add:0' shape=(3,) dtype=float32>]
has no assign method

Следовательно, v1:0 действительно является самой переменной, а v1 имеет метод assign. Это имеет смысл, потому что это просто ссылка на значение с плавающей точкой. С другой стороны, v2 = v1 + 1 приводит к выводу операции add. Так что v2 больше не является переменной, и вы не можете присвоить новое значение v2. Какой операнд add вы ожидаете обновить в этом случае? Всякий раз, когда вы используете v1, вспомните об операции read_value() из v1:

v1 = tf.get_variable('v1', shape=[3], initializer=tf.zeros_initializer)
inspect(v1)
w = v1.read_value()
inspect(w)
v2 = v1.read_value() + 1
inspect(v2)

дает

 v1:0
-------
<class 'tensorflow.python.ops.variables.Variable'>
[<tf.Tensor 'v1:0' shape=(3,) dtype=float32_ref>]
has assign method

 read:0
-------
<class 'tensorflow.python.framework.ops.Tensor'>
[<tf.Tensor 'read:0' shape=(3,) dtype=float32>]
has no assign method

 add:0
-------
<class 'tensorflow.python.framework.ops.Tensor'>
[<tf.Tensor 'add:0' shape=(3,) dtype=float32>]
has no assign method
...