Использование numpy.einsum для тензорной точки срезов

У меня есть массив формы N, j, j и другой формы M, j, j. Я хочу рассчитать их тензорную точку, чтобы в конечном итоге получить матрицу, в которой запись i,j равна np.tensordot(arr1[i, :, :], arr2[j, :, :]) Я пробовал зацикливаться, но это смехотворно медленно, я читал о np.einsum, но, к сожалению, не могу понять, сколько бы я ни читал. Моя последняя попытка; np.einsum('ilk,ium->lu', arr1, arr2) Но я продолжаю получать ошибки, что формы не могут быть переданы. Буду признателен за любые указатели, спасибо!

пример кода:

  arr1 = np.zeros((5, 2, 2))
  arr2 = np.zeros((4, 2, 2))
  arr2[1,:,:][1,1] = 2
  arr1[1,:,:][1,1] = 3
  np.tensordot(arr1[1,:,:], arr2[1,:,:])

в этом случае тензорная точка даст мне 6. Это то, что меня интересует, для каждого i,j.

Не могли бы вы опубликовать пример кода, демонстрирующий проблему?

paisanco 13.12.2020 17:55

Поскольку N и M разные, первые индексы должны быть разными. `ilk,jkm->ijlm', с суммированием 'dot' по общему измерению 'k'. Поскольку последние 2 измерения одинаковы, порядок индексов может быть другим, но я предполагаю, что вы хотите обычно "последний из первого, 2-й до последнего из второго" "точка". Обратите внимание, что я сохраняю оба "i" и 'Дж'

hpaulj 13.12.2020 18:01

@paisanco Отредактировано с игрушечным примером

Omri. B 13.12.2020 18:01
tensordot с 2d-массивами (а не значениями осей) является обычным dot.
hpaulj 13.12.2020 18:02

@hpaulj Спасибо за ваш пример, я изменил его на ilk, jkm-> ij, так как хочу, чтобы на выходе была 2d-матрица. Теперь я получаю предупреждение iterator is too big, я сделал что-то не так?

Omri. B 13.12.2020 18:03

Хорошо, я ошибаюсь, что tensordot эквивалентно «kl, kl», суммируя оба последних 2 измерения. 'ikl,jkl->ij' (по умолчанию ось=2, двойное сжатие).

hpaulj 13.12.2020 18:11
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
6
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
In [41]: x=np.arange(2*3*3).reshape(2,3,3)
In [42]: y=np.arange(4*3*3).reshape(4,3,3)

двойное сокращение на последних 2 дим.:

In [43]: np.einsum('ikl,jkl->ij',x,y)
Out[43]: 
array([[ 204,  528,  852, 1176],
       [ 528, 1581, 2634, 3687]])

проверить одно значение:

In [44]: np.tensordot(x[0],y[0])
Out[44]: array(204)

Та же точка (и дополнительное измерение)

In [47]: np.dot(x.reshape(-1,9),y.reshape(-1,9,1))
Out[47]: 
array([[[ 204],
        [ 528],
        [ 852],
        [1176]],

       [[ 528],
        [1581],
        [2634],
        [3687]]])

np.tensordot с различными параметрами оси может быть немного сложно использовать. Так или иначе он изменяет форму и переставляет массивы, чтобы он мог вызывать np.dot. Затем он может сделать некоторые дальнейшие манипуляции.

Или используя широковещательную и многоосевую сумму:

In [48]: (x[:,None,:,:]*y[None,:,:,:]).sum(axis=(2,3))
Out[48]: 
array([[ 204,  528,  852, 1176],
       [ 528, 1581, 2634, 3687]])

и тензорд без цикла:

In [50]: np.tensordot(x,y,axes=((1,2),(1,2)))
Out[50]: 
array([[ 204,  528,  852, 1176],
       [ 528, 1581, 2634, 3687]])

Большое спасибо! Насколько я понимаю, 'ikl,jkl->ij перебирает первую ось и умножает две другие?

Omri. B 13.12.2020 18:23

Я добавил эквивалент умножения и суммы. и полный тензордот.

hpaulj 13.12.2020 18:30

Другие вопросы по теме