Как умножать партии изображений? N-D матричное умножение формы [размер, высота, ширина] (точечное произведение)

#python #numpy #machine-learning #math #deep-learning

Вопрос:

Предположим, у меня есть матрица с партией из 2 изображений или матрица из 2 предложений, в которых слова выделены для последнего измерения.

изображение = [batch, width, height, channel]

слова = [batch, no of words in each sentence, vector length of each word]

Каков наилучший способ умножения двух разных партий?

Я пробовал перестановки, как:

 X = np.random.randn(2,3,4)

y1 = np.random.randn(2,4,3)
y2 = np.random.randn(3,4,2)
y3 = np.random.randn(4,3)
y4 = np.random.randn(4)

np.dot(X,y1)
np.dot(X,y2)
np.dot(X,y3)
np.dot(X,y4)
 

Это единственные перестановки, которые сработали, но я, поскольку размер пакета равен 2, думаю y1 , что здесь больше смысла. Но является ли это правильным подходом? Возможно ли это?

Существует ли общая формула для умножения n-D матрицы. Например, вы можете умножать 2-D матрицы [MxN] @ [N,P] . Как мы можем умножить N-D матриц?

Комментарии:

1. Для batches того, чтобы посмотреть на использование np.matmul вместо np.dot . Или np.einsum если вы хотите еще большего контроля.

2. Можете ли вы привести мне пример?

Ответ №1:

Если я правильно понял ваш вопрос, вы хотите уменьшить два тензора фиксированных порядков, но произвольных форм, которые согласуются только в их первом измерении (размерность пакета).

Последовательным способом сделать это является запись суммирования Эйнштейна, которая реализована в виде эйнсума numpy.

Конкретно (используя простые числа для измерений, чтобы избежать двусмысленности):

 batch, width, height, num_channels, seq_len, vec_dim = 3, 5, 7, 11, 13, 17
image = np.random.randn(batch, width, height, num_channels)
sentence = np.random.randn(batch, seq_len, vec_dim)
out = np.einsum('bwhn,bsv->bwhnsv', image, sentence)
print(out.shape)
# (3, 5, 7, 11, 13, 17) 
 

Мы делаем следующее: (1) присваиваем каждому измерению каждого тензора символ, (2) разделяем размеры тензора запятой, (3) идентифицируем размеры сжатия (размеры, которые должны совпадать между тензорами), присваивая им одно и то же имя, и (4) указываем размерность вывода после стрелки. Этого достаточно для определения операций суммирования по элементам на фактических тензорах.

Следовательно:

  • image это "bwhn" для (batch, width, height, num_channels)
  • sentence это "bsv" для (batch, seq_len, vec_dim)
  • их сокращение "bwhnsv" (набор "b" тензоров формы "whnsv" , содержащий поэлементное произведение каждого пикселя "whn" с каждым словесным элементом "sv" ).

Примечание: Возможно, вы захотите рассмотреть пакет opt_einsum-он использует точно такие же обозначения и синтаксис, но намного дешевле и быстрее.