Недавно я перешел на Python 3.5 и заметил, что новый оператор умножения матриц (@) иногда ведет себя иначе, чем оператор numpy dot . Например, для трехмерных массивов:
import numpy as np
a = np.random.rand(8,13,13)
b = np.random.rand(8,13,13)
c = a @ b # Python 3.5+
d = np.dot(a, b)
@
Оператор возвращает массив формы:
c.shape
(8, 13, 13)
пока np.dot()
функция возвращает:
d.shape
(8, 13, 8, 13)
Как я могу воспроизвести тот же результат с помощью numpy dot? Есть ли другие существенные отличия?
python
numpy
matrix-multiplication
python-3.5
полыхать
источник
источник
matmul
функцию много лет назад?@
как инфиксный оператор является новым, но функция работает так же хорошо и без него.Ответы:
@
Оператор называет массива в__matmul__
метод, а неdot
. Этот метод также присутствует в API как функцияnp.matmul
.Из документации:
Последний пункт становится ясно , что
dot
иmatmul
методы ведут себя по- разному при передаче 3D (или многомерные) массивов. Еще цитата из документации:Для
matmul
:Для
np.dot
:источник
Ответ @ajcr объясняет, чем отличаются
dot
иmatmul
(вызываемые@
символом). Глядя на простой пример, можно ясно увидеть, как они по-разному ведут себя при работе со «стопками матриц» или тензорами.Чтобы прояснить различия, возьмите массив 4x4 и верните
dot
продукт иmatmul
продукт со стеком матриц 3x4x2 или тензором.Ниже представлены продукты каждой операции. Обратите внимание на то, как выглядит скалярное произведение,
и как матричный продукт формируется путем совместного распространения матрицы.
источник
a = np.arange(24).reshape(3, 4, 2)
создать массив размером 3x4x2.Просто FYI
@
и его многочисленные эквиваленты,dot
иmatmul
все они примерно одинаково быстры. (Сюжет создан с помощью моего проекта perfplot .)Код для воспроизведения сюжета:
источник
В математике я думаю, что точка в numpy имеет больше смысла
поскольку он дает скалярное произведение, когда a и b - векторы, или умножение матриц, когда a и b - матрицы
Что касается операции matmul в numpy, она состоит из частей результата точки , и ее можно определить как
> matmul (a, b) _ {i, j, k, c} =
Итак, вы можете видеть, что matmul (a, b) возвращает массив небольшой формы, который потребляет меньше памяти и имеет больше смысла в приложениях. В частности, совмещая с трансляцией , можно получить
например.
Из двух приведенных выше определений вы можете увидеть требования для использования этих двух операций. Предположим, что a.shape = (s1, s2, s3, s4) и b.shape = (t1, t2, t3, t4)
Чтобы использовать точку (a, b), вам нужно
Для использования matmul (a, b) вам необходимо
Используйте следующий фрагмент кода, чтобы убедить себя.
Пример кода
источник
np.matmul
также дает скалярное произведение векторов и матричное произведение матриц.Вот сравнение,
np.einsum
чтобы показать, как прогнозируются индексыисточник
Мой опыт работы с MATMUL и DOT
Я постоянно получал «ValueError: форма переданных значений (200, 1), индексы подразумевают (200, 3)» при попытке использовать MATMUL. Я хотел найти быстрое решение и обнаружил, что DOT предоставляет ту же функциональность. Я не получаю ошибок при использовании DOT. Я получаю правильный ответ
с MATMUL
с DOT
источник