Как сделать продукт матриц в PyTorch

В numpy я могу сделать простое матричное умножение следующим образом:

a = numpy.arange(2*3).reshape(3,2)
b = numpy.arange(2).reshape(2,1)
print(a)
print(b)
print(a.dot(b))

Однако, когда я пытаюсь это с помощью PyTorch Tensors, это не работает:

a = torch.Tensor([[1, 2, 3], [1, 2, 3]]).view(-1, 2)
b = torch.Tensor([[2, 1]]).view(2, -1)
print(a)
print(a.size())

print(b)
print(b.size())

print(torch.dot(a, b))

Этот код вызывает следующую ошибку:

RuntimeError: несогласованный размер тензора в /Users/soumith/code/builder/wheel/pytorch-src/torch/lib/TH/generic/THTensorMath.c:503

Любые идеи о том, как матричное умножение может быть проведено в PyTorch?

Ответы

Ответ 1

Ты ищешь

torch.mm(a,b)

Обратите внимание, что torch.dot() ведет себя по-разному с np.dot(). Там было какое-то обсуждение того, что было бы желательно здесь. В частности, torch.dot() рассматривает как a и b как 1D-векторы (независимо от их первоначальной формы) и вычисляет их внутренний продукт. Ошибка возникает, потому что такое поведение делает ваш вектор длиной 6 и ваш a b вектор длиной 2; поэтому их внутреннее произведение не может быть вычислено. Для матричного умножения в PyTorch используйте torch.mm(). Numpy np.dot() в отличие от этого более гибкая; он вычисляет скалярное произведение для 1D-массивов и выполняет матричное умножение для двумерных массивов.

Ответ 2

Если вы хотите сделать умножение матрицы (тензор 2 ранга), вы можете сделать это четырьмя эквивалентными способами:

AB = A.mm(B) # computes A.B (matrix multiplication)
# or
AB = torch.mm(A, B)
# or
AB = torch.matmul(A, B)
# or, even simpler
AB = A @ B # Python 3.5+

Есть несколько тонкостей. Из документации PyTorch:

torch.mm не транслируется. Для трансляции продуктов матрицы см. Torch.matmul().

Например, вы не можете умножить два одномерных вектора на torch.mm или умножить пакетные матрицы (ранг 3). Для этого вам следует использовать более универсальный torch.matmul. Для подробного списка поведения вещания torch.matmul, см. Документацию.

Для поэлементного умножения вы можете просто сделать (если A и B имеют одинаковую форму)

A * B # element-wise matrix multiplication (Hadamard product)

Ответ 3

Используйте torch.mm(a, b) или torch.matmul(a, b)
Оба одинаковы.

>>> torch.mm
<built-in method mm of type object at 0x11712a870>
>>> torch.matmul
<built-in method matmul of type object at 0x11712a870>

Есть еще один вариант, который может быть полезно знать. Это оператор @. @Симон Х.

>>> a = torch.randn(2, 3)
>>> b = torch.randn(3, 4)
>>> [email protected]
tensor([[ 0.6176, -0.6743,  0.5989, -0.1390],
        [ 0.8699, -0.3445,  1.4122, -0.5826]])
>>> a.mm(b)
tensor([[ 0.6176, -0.6743,  0.5989, -0.1390],
        [ 0.8699, -0.3445,  1.4122, -0.5826]])
>>> a.matmul(b)
tensor([[ 0.6176, -0.6743,  0.5989, -0.1390],
        [ 0.8699, -0.3445,  1.4122, -0.5826]])    

Три дают одинаковые результаты.

Ссылки по теме:
Матричный оператор умножения
PEP 465 - Специальный инфиксный оператор для умножения матриц