Объект «Тензор» не имеет атрибута «assign_add»

Я столкнулся с ошибкой «Тензорный объект» не имеет атрибута «assign_add», когда я пытаюсь использовать функцию assign_add или assign_sub. Код показан ниже:

Я определил два тензора t1 и t2 с одинаковой формой и одним и тем же типом данных.

>>> t1 = tf.Variable(tf.ones([2,3,4],tf.int32))
>>> t2 = tf.Variable(tf.zeros([2,3,4],tf.int32))
>>> t1
<tf.Variable 'Variable_4:0' shape=(2, 3, 4) dtype=int32_ref>
>>> t2
<tf.Variable 'Variable_5:0' shape=(2, 3, 4) dtype=int32_ref>

затем я использую assign_add для t1 и t2 для создания t3

>>> t3 = tf.assign_add(t1,t2)
>>> t3
<tf.Tensor 'AssignAdd_4:0' shape=(2, 3, 4) dtype=int32_ref>

затем я пытаюсь создать новый тензор t4, используя t1[1] и t2[1], которые являются тензорами той же формы и того же типа данных.

>>> t1[1]   
<tf.Tensor 'strided_slice_23:0' shape=(3, 4) dtype=int32>
>>> t2[1]
<tf.Tensor 'strided_slice_24:0' shape=(3, 4) dtype=int32>
>>> t4 = tf.assign_add(t1[1],t2[1])

но получил ошибку,

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/admin/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/state_ops.py", line 245, in assign_add
return ref.assign_add(value)
AttributeError: 'Tensor' object has no attribute 'assign_add'

такая же ошибка при использовании assign_sub

>>> t4 = tf.assign_sub(t1[1],t2[1])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/admin/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/state_ops.py", line 217, in assign_sub
return ref.assign_sub(value)
AttributeError: 'Tensor' object has no attribute 'assign_sub'

Любая идея, где не так? Спасибо.


person X. L    schedule 03.05.2018    source источник


Ответы (4)


Ошибка заключается в том, что t1 является объектом tf.Variable, а t1[1] является tf.Tensor. (вы можете увидеть это в выводах ваших операторов печати.). То же самое для t2 и t[[2]]

Как это бывает, tf.Tensor не может быть изменен (он только для чтения), тогда как tf.Variable может быть (чтение, а также запись), см. здесь. Поскольку tf.scatter_add выполняет дополнение на месте, оно не работает с t1[1] и t2[1 ] в качестве входных данных, в то время как с t1 и t2 в качестве входных данных такой проблемы нет.

person Kanchan Kumar    schedule 17.07.2018

То, что вы пытаетесь сделать здесь, немного сбивает с толку. Я не думаю, что вы можете обновлять срезы и создавать новый тензор одновременно.

Если вы хотите обновить срезы перед созданием t4, используйте tf.scatter_add() (или tf.scatter_sub() или tf.scatter_update() соответственно), как предложено здесь. Например:

sa = tf.scatter_add(t1, [1], t2[1:2])

Затем, если вы хотите получить новый тензор t4, используя новые t1[1] и t2[1], вы можете сделать:

with tf.control_dependencies([sa]):
    t4 = tf.add(t1[1],t2[1])
person Y. Luo    schedule 03.05.2018

Вот несколько примеров использования tf.scatter_add и tf.scatter_sub

>>> t1 = tf.Variable(tf.ones([2,3,4],tf.int32))
>>> t2 = tf.Variable(tf.zeros([2,3,4],tf.int32))
>>> init = tf.global_variables_initializer()
>>> sess.run(init)
>>> t1.eval()
array([[[1, 1, 1, 1],
    [1, 1, 1, 1],
    [1, 1, 1, 1]],

   [[1, 1, 1, 1],
    [1, 1, 1, 1],
    [1, 1, 1, 1]]], dtype=int32)
>>> t2.eval()
array([[[0, 0, 0, 0],
    [0, 0, 0, 0],
    [0, 0, 0, 0]],

   [[0, 0, 0, 0],
    [0, 0, 0, 0],
    [0, 0, 0, 0]]], dtype=int32)


>>> t3 = tf.scatter_add(t1,[0],[[[2,2,2,2],[2,2,2,2],[2,2,2,2]]])
>>> sess.run(t3)
array([[[3, 3, 3, 3],
    [3, 3, 3, 3],
    [3, 3, 3, 3]],

   [[1, 1, 1, 1],
    [1, 1, 1, 1],
    [1, 1, 1, 1]]], dtype=int32)

>>>t4 = tf.scatter_sub(t1,[0,0,0],[t1[1],t1[1],t1[1]])

Ниже приведен еще один пример, который можно найти по адресу https://blog.csdn.net/efforever/article/details/77073103

Поскольку в Интернете можно найти несколько примеров, иллюстрирующих scatter_xxx, я привожу их ниже для справки.

import tensorflow as tf 
import numpy as np 


with tf.Session() as sess1:


c = tf.Variable([[1,2,0],[2,3,4]], dtype=tf.float32, name='biases') 
cc = tf.Variable([[1,2,0],[2,3,4]], dtype=tf.float32, name='biases1') 
ccc = tf.Variable([0,1], dtype=tf.int32, name='biases2') 

#对应label的centers-diff[0--]
centers = tf.scatter_sub(c,ccc,cc)
#centers = tf.scatter_sub(c,[0,1],cc)  
#centers = tf.scatter_sub(c,[0,1],[[1,2,0],[2,3,4]])
#centers = tf.scatter_sub(c,[0,0,0],[[1,2,0],[2,3,4],[1,1,1]])
#即c[0]-[1,2,0] \ c[0]-[2,3,4]\ c[0]-[1,1,1],updates要减完:indices与updates元素个数相同

a = tf.Variable(initial_value=[[0, 0, 0, 0],[0, 0, 0, 0]])  
b = tf.scatter_update(a, [0, 1], [[1, 1, 0, 0], [1, 0, 4, 0]])  
#b = tf.scatter_update(a, [0, 1,0], [[1, 1, 0, 0], [1, 0, 4, 0],[1, 1, 0, 1]]) 

init = tf.global_variables_initializer() 
sess1.run(init)

print(sess1.run(centers))
print(sess1.run(b))


[[ 0.  0.  0.]
 [ 0.  0.  0.]]
[[1 1 0 0]
 [1 0 4 0]]


[[-3. -4. -5.]
 [ 2.  3.  4.]]
[[1 1 0 1]
 [1 0 4 0]]
person X. L    schedule 04.05.2018

Вы также можете использовать tf.assign() в качестве обходного пути в качестве нарезного назначения был реализован для него, в отличие от tf.assign_add() или tf.assign_sub(), начиная с TensorFlow версии 1.8. Обратите внимание, что вы можете выполнить только одну операцию нарезки (нарезка на срез не будет работать), а также это не атомарно, поэтому, если есть несколько потоков, читающих и записывающих одну и ту же переменную, вы не знаете, какая операция будет последний, который нужно написать, если вы явно не кодируете его. tf.assign_add() и tf.assign_sub() гарантированно потокобезопасны. Тем не менее, это лучше, чем ничего: рассмотрим этот код (проверено):

import tensorflow as tf

t1 = tf.Variable(tf.zeros([2,3,4],tf.int32))
t2 = tf.Variable(tf.ones([2,3,4],tf.int32))

assign_op = tf.assign( t1[ 1 ], t1[ 1 ] + t2[ 1 ] )

init_op = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run( init_op )
    res = sess.run( assign_op )
    print( res )

выведет:

[[[0 0 0 0]
[0 0 0 0]
[0 0 0 0]]

[[1 1 1 1]
[1 1 1 1]
[1 1 1 1]]]

по желанию.

person Peter Szoldan    schedule 06.05.2018