Обновление тензора в тензорном потоке

Я определил неконтролируемую проблему в тензорном потоке, мне нужно обновлять мой B и мой tfZ с каждой итерацией, но я не знаю, как обновить мой tfZ используя сеанс tenorflow.

tfY = tf.placeholder(shape=(15, 15), dtype=tf.float32)

with tf.variable_scope('test'):
    B = tf.Variable(tf.zeros([]))
    tfZ = tf.convert_to_tensor(Z, dtype=tf.float32)

def loss(tfY):
    r = tf.reduce_sum(tfZ*tfZ, 1)
    r = tf.reshape(r, [-1, 1])
    D = tf.sqrt(r - 2*tf.matmul(tfZ, tf.transpose(tfZ)) + tf.transpose(r) + 1e-9)
    return tf.reduce_sum(tfY*tf.log(tf.sigmoid(D+B))+(1-tfY)*tf.log(1-tf.sigmoid(D+B)))

LOSS = loss(Y)
GRADIENT = tf.gradients(LOSS, [B, tfZ])

sess = tf.Session()
sess.run(tf.global_variables_initializer())

tot_loss = sess.run(LOSS, feed_dict={tfY: Y})

loss_grad = sess.run(GRADIENT, feed_dict={tfY: Y})

learning_rate = 1e-4
for i in range(1000):
    sess.run(B.assign(B - learning_rate * loss_grad[0]))
    print(tfZ)
    sess.run(tfZ.assign(tfZ - learning_rate * loss_grad[1]))

    tot_loss = sess.run(LOSS, feed_dict={tfY: Y})
    if i%10==0:
        print(tot_loss)

Этот код печатает следующее:

Tensor("test_18/Const:0", shape=(15, 2), dtype=float32)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-35-74ddafc0bf3a> in <module>()
     25     sess.run(B.assign(B - learning_rate * loss_grad[0]))
     26     print(tfZ)
---> 27     sess.run(tfZ.assign(tfZ - learning_rate * loss_grad[1]))
     28 
     29     tot_loss = sess.run(LOSS, feed_dict={tfY: Y})

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

Тензорный объект правильно не имеет атрибута assign, но я не могу найти никакой другой функции, прикрепленной к объекту, которая могла бы сделать это. Как правильно обновить мой тензор?

1 ответ

Решение

В отличие от tf.Variable, tf.Tensor не обеспечивает assign Способ; если тензор изменчив, вы должны позвонить tf.assign функция явно:

tf.assign(tfZ, tfZ - learning_rate * loss_grad[1])

Обновление: не все тензоры являются изменяемыми, например, ваш tfZ нет. На данный момент изменяемые тензоры - это только те, которые соответствуют переменным, как объяснено в этом ответе (по крайней мере, в тензорном потоке 1.x это может быть расширено в будущем). Обычные тензоры являются дескрипторами результата операции, т.е. они связаны с этой операцией и ее входами. Чтобы изменить неизменное значение тензора, нужно изменить исходные тензоры (заполнители или переменные). В вашем конкретном случае было бы легче сделать tfZ переменная также.

Кстати, tf.Variable.assign() это просто обертка над tf.assign и нужно запустить результат op в сеансе, чтобы фактически выполнить назначение.

Обратите внимание, что в обоих случаях создается новый узел на графике. Если вы вызываете его в цикле (как в вашем фрагменте), график будет раздуваться на тысячу узлов. Делать это в реальном производственном коде - плохая практика, потому что это может легко вызвать OOM.

Другие вопросы по тегам