Объект 'Tensor' не имеет атрибута assign_add - PullRequest
0 голосов
/ 03 мая 2018

Я столкнулся с ошибкой, объект Tensor не имеет атрибута 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'

Есть идеи, где не так? Благодаря.

Ответы [ 4 ]

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

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

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

0 голосов
/ 04 мая 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]]
0 голосов
/ 07 мая 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]]]

по желанию.

0 голосов
/ 03 мая 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])
...