У меня есть два тензора A
с формой (25, 1010, 7, 512)
и B
с формой (10, 7
).
Я хотел бы добавить B
к первым 10 фрагментам, используя второе измерение A
так, как это можно сделать в Numpy, как:
A[:, :10, :, :] += B[np.newaxis, :, :, np.newaxis]
(Не важно, чтобы исходный тензор обновлялся, меня бы устроило либо обновление на месте, либо создание нового тензора).
Конечно, это нельзя сделать непосредственно в тензорном потоке, и tf.tensor_scatter_nd_add
, похоже, не работает в этом случае, потому что срезы не относятся к конечному размеру тензора, который нужно обновить. Есть ли способ сделать это редко, или мне нужно увеличить B
в 100 раз?
Обновлено: я испортил пример numpy при преобразовании его из обновления на месте в дополнение.
Обновлено: поскольку OP пытается выполнить назначение элемента , которое недоступно в TensorFlow (но доступно в PyTorch!!), вы можете использовать tf.concat
для добавления по оси 1 оставшегося тензора после суммы.
Пожалуйста, посмотрите мой обновленный код -
import tensorflow as tf
#tf.__version__ = '2.3.1'
#numpy arrays with your shapes
a = np.random.random((25, 1010, 7, 512))
b = np.random.random((10, 7))
#convert to tensors
A = tf.convert_to_tensor(a)
B = tf.convert_to_tensor(b)
#Broadcasted sum >> concat with remaining array over axis 1
A = tf.concat([A[:,:10,:,:] + B[None, :, :, None], A[:,10:,:,:]], axis=1)
A.shape
TensorShape([25, 1010, 7, 512])
Просто чтобы убедиться, что вы получаете тот же ответ, что и при назначении элемента в NumPy, вы можете сделать это:
#Item assigment sum over numpy arrays
a[:,:10,:,:] += b[None,:,:,None]
#Convert a to tensor and check against A from above.
tf.reduce_all(tf.convert_to_tensor(a) == A)
<tf.Tensor: shape=(), dtype=bool, numpy=True>
не знал о tf.newaxis
. Спасибо за эту информацию!
Ах, я на самом деле испортил пример numpy, позвольте мне переписать то, что я хочу.
Вы хотите, чтобы он суммировался по каждому из блоков по 10 из 1010 элементов?
Ключевым моментом является то, что я хотел бы, чтобы конечный результат имел форму (25, 1010, 7, 512) с обновленными первыми 10 фрагментами.
так что вы НЕ хотите, чтобы он транслировал сумму по оси = 1, но хотите, чтобы она транслировалась по оси = 0 и оси = 3?
Назначение элемента, к сожалению, не разрешено в tensorflow (хотя оно доступно в pytorch :( проверьте это). Я обновил код с решением, которое должно быть проще, чем иметь дело с tf.tensor_scatter_nd_add
.
Добавлена проверка, чтобы вы могли быть уверены, что она дает ожидаемое решение. Дайте мне знать, если это решит вашу проблему.
@AkshaySehgal На самом деле это то, что я реализовал в своем коде, поэтому я принял это как ответ. Я надеялся, что есть какой-то способ использовать разброс.
Scatter требует сложных меш-сеток и всего остального, я мог бы помочь вам реализовать это, но оно того не стоит, поверьте мне.
Это был хороший вопрос, однако, я не сталкивался с подобной ситуацией раньше!
Я не удивлюсь, если вы можете буквально использовать
np.newaxis
, поскольку, насколько мне известно, это всего лишь псевдоним дляNone
. Также естьtf.newaxis
, чтобы сделать его более явным, хотя я также предпочитаюNone
просто потому, что он короче.