Отрегулируйте одно значение в Tensor TensorFlow

Мне неловко спрашивать об этом, но как настроить одно значение в тензоре? Предположим, вы хотите добавить «1» только к одному значению в вашем тензоре?

Сделать это путем индексации не получится:

TypeError: 'Tensor' object does not support item assignment

Один из подходов - построить тензор нулей одинаковой формы. А затем установите 1 в нужном вам положении. Затем вы должны сложить два тензора вместе. Здесь снова возникает та же проблема, что и раньше.

Я читал документацию по API несколько раз и, кажется, не могу понять, как это сделать. Заранее спасибо!


person LeavesBreathe    schedule 08.01.2016    source источник


Ответы (5)


ОБНОВЛЕНИЕ. TensorFlow 1.0 включает оператор tf.scatter_nd(), который можно использовать для создания delta ниже без создания tf.SparseTensor.


Это на самом деле удивительно сложно с существующими операциями! Возможно, кто-нибудь может предложить более приятный способ завершить следующее, но вот один из способов сделать это.

Допустим, у вас есть тензор tf.constant():

c = tf.constant([[0.0, 0.0, 0.0],
                 [0.0, 0.0, 0.0],
                 [0.0, 0.0, 0.0]])

... и вы хотите добавить 1.0 в ячейку [1, 1]. Один из способов сделать это - определить tf.SparseTensor , delta, представляющий изменение:

indices = [[1, 1]]  # A list of coordinates to update.

values = [1.0]  # A list of values corresponding to the respective
                # coordinate in indices.

shape = [3, 3]  # The shape of the corresponding dense tensor, same as `c`.

delta = tf.SparseTensor(indices, values, shape)

Затем вы можете использовать параметр tf.sparse_tensor_to_dense(), чтобы сделать плотный тензор из delta и добавьте его в c:

result = c + tf.sparse_tensor_to_dense(delta)

sess = tf.Session()
sess.run(result)
# ==> array([[ 0.,  0.,  0.],
#            [ 0.,  1.,  0.],
#            [ 0.,  0.,  0.]], dtype=float32)
person mrry    schedule 08.01.2016
comment
Большое вам спасибо. Я согласен с вами, что была бы полезна функция, которая может делать это внутренне с большей эффективностью! - person LeavesBreathe; 09.01.2016
comment
вы знаете, как это обрабатывает значения с одним и тем же индексом? - person dtracers; 06.07.2016
comment
nvm он вообще не так хорошо справляется ... Вы знаете, как это сделать в случае нескольких индексов с одним и тем же значением? - person dtracers; 07.07.2016
comment
@dtracers: я считаю, что эти два других вопроса актуальны: stackoverflow.com/questions/39157723/ и заголовок stackoverflow.com/questions/39045797/ - person Soravux; 30.08.2016
comment
Не могли бы вы переписать это, используя операцию scatter_nd? Было бы более эффективным в первую очередь использовать переменную для c? - person Mr_and_Mrs_D; 14.05.2017
comment
@mrry зачем тебе c? не tf.sparse_tensor_to_dense(delta) уже будет 1 в [1,1] и 0 везде? - person Nimrod Morag; 29.07.2018

Как насчет tf.scatter_update(ref, indices, updates) или tf.scatter_add(ref, indices, updates)?

ref[indices[...], :] = updates
ref[indices[...], :] += updates

См. это.

person Liping Liu    schedule 01.01.2017
comment
он действителен только в том случае, если ref является переменной. - person Sonal Gupta; 27.06.2017
comment
Это ограничение на самом деле более фундаментальное, чем кажется, если вы видите TF как ограниченную (с точки зрения доступных схем рекурсии) масштабируемую среду выполнения преимущественно чистого ленивого функционального языка. Затем вы можете видеть, что сложность эффективного обновления (чистого) тензора по существу такая же, как и при обновлении чисто функциональной структуры данных. Без такого уровня чистоты все было бы нелегко. - person mnish; 01.08.2017

Мне кажется, что тот факт, что функции tf.assign, tf.scatter_nd, tf.scatter_update работают только с tf.Variables, недостаточно подчеркнут. Итак, вот оно.

А в более поздних версиях TensorFlow (протестированных с 1.14) вы можете использовать индексирование tf.Variable для присвоения значений конкретным индексам (опять же, это работает только с tf.Variable объектами).

v = tf.Variable(tf.constant([[1,1],[2,3]]))
change_v = v[0,0].assign(4)
with tf.Session() as sess:
  tf.global_variables_initializer().run()
  print(sess.run(change_v))
person thushv89    schedule 09.10.2019

tf.scatter_update не назначен оператор градиентного спуска и будет генерировать ошибку при обучении как минимум с tf.train.GradientDescentOptimizer. Вы должны реализовать битовые манипуляции с функциями низкого уровня.

person johannes    schedule 02.05.2019

Если вы хотите заменить определенные индексы, я бы создал булеву тензорную маску и транслируемый тензор с новыми значениями в правильных позициях. Затем используйте

new_tensor = tf.where(boolen_tensor_mask, new_values_tensor, old_values_tensor)
person Patrick von Platen    schedule 27.02.2020