Различные умножения в pytorch

PyTorch

Мало знаний, большой вызов! Эта статья участвует в "Необходимые знания для программистов«Творческая деятельность.

Там так много умножений, и я, честно говоря, до сих пор их тщательно не прочесала, поэтому делаю все сразу.


Сначала объявите вектор и 2D-матрицу

import torch
vec = torch.arange(4)
mtx = torch.arange(12).reshape(4,3)
print(vec, mtx,sep='\n')

Выходной результат:

>> 
tensor([0, 1, 2, 3])
tensor([[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8],
        [ 9, 10, 11]])

По местоположению*

это*В pytorch он умножается на позицию, и есть механизм трансляции.

import torch
vec = torch.arange(4)
mtx = torch.arange(12).reshape(4,3)
print(vec*vec)
print(mtx*mtx)
>>
tensor([0, 1, 4, 9])
tensor([[  0,   1,   4],
        [  9,  16,  25],
        [ 36,  49,  64],
        [ 81, 100, 121]])

Но следует отметить, что хотя во многих местах упоминается, что вектор по умолчанию является вектором-столбцом, вОдномерные тензоры в pytorch не имеют этого аргумента. Даже если вы умножите тензор 3 × 4 на тензор 4 × 1, результатом должен быть тензор 3 × 1, но поскольку это одномерный тензор, он станет значением по умолчанию 3 (а не 1 × 3).

в исполняемом состоянииprint(mtx*vec)иprint(vec*mtx)Результат точно такой же.

Но в приведенном выше примере, если вы выполнитеprint(mtx*vec)илиprint(vec*mtx)сообщит об ошибке. Поскольку по умолчанию одномерные тензоры и матрицы выполняют*При работе количество элементов в одномерном тензоре должно совпадать с количеством столбцов в двумерной матрице, иначе функция трансляции не сработает.

Конечно, вы также можете использоватьreshap()Добавьте к нему размер. Но есть некоторые правила измерения, которым необходимо следовать после добавления размеров.

import torch
vec = torch.arange(4).reshape(4,1) # 增加维度
mtx = torch.arange(12).reshape(4,3)
print(vec*mtx)
print(mtx*vec)
>>
tensor([[ 0,  0,  0],
        [ 3,  4,  5],
        [12, 14, 16],
        [27, 30, 33]])
tensor([[ 0,  0,  0],
        [ 3,  4,  5],
        [12, 14, 16],
        [27, 30, 33]])

Например, матрица выше имеет размер 4×3.

Для второй строки кода вы можете использовать

  • vec = torch.arange(4).reshape(4,1)
  • vec = torch.arange(3).reshape(1,3)

Другими словами, количество элементов должно оставаться одинаковым в строке или столбце.

Умножить torch.mul

torch.mul(input, value, out=None)

со скалярным значениемvalueумножить вводinputкаждый элемент , и возвращает новый тензор результата. является произведением тензоров.

import torch
vec = torch.arange(4)
mtx = torch.arange(12).reshape(3,4)
print(torch.mul(vec,2))
print(torch.mul(mtx,2))
>>
tensor([0, 2, 4, 6])
tensor([[ 0,  2,  4,  6],
        [ 8, 10, 12, 14],
        [16, 18, 20, 22]])

умножение матрицы на вектор torch.mv

torch.mv(mat, vec, out=None) → Tensor

парная матрицаmatи векторvecУмножить. еслиmat- тензор размера n × m,vecявляется m-арным одномерным тензором, который выводит n-арный одномерный тензор.

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

import torch
vec = torch.arange(4)
mtx = torch.arange(12).reshape(3,4)
print(torch.mv(mtx,vec))
>>
tensor([14, 38, 62])

факел умножения матриц.мм

torch.mm(mat1, mat2, out=None) → Tensor

парная матрицаmat1иmat2Умножить. еслиmat1- тензор размера n × m,mat2является тензором m × p и выводит тензор n × pout.

Это матричное умножение нашей средней школы генерации строк, и размеры должны быть правильными.

import torch
mtx = torch.arange(12)
m1 = mtx.reshape(3,4)
m2 = mtx.reshape(4,3)
print(torch.mm(m1, m2))
>>
tensor([[ 42,  48,  54],
        [114, 136, 158],
        [186, 224, 262]])

точечный продукт факел.точка

torch.dot(tensor1, tensor2) → float

Вычисляет скалярное произведение (внутреннее произведение) двух тензоров, оба из которых являются одномерными векторами.

import torch
vec = torch.arange(4)
print(torch.dot(vec, vec))
>>
tensor(14)

Черная технология@

Есть и черная технология@, также строго в соответствии с тем, чтобы количество столбцов первого параметра было равно количеству строк второго параметра.

import torch
vec = torch.arange(4)
mtx = torch.arange(12)
m1 = mtx.reshape(4,3)
m2 = mtx.reshape(3,4)

print(vec @ vec)
print(vec @ m1)
print(m2 @ vec)
print(m1 @ m2)
>>
tensor(14)
tensor([42, 48, 54])
tensor([14, 38, 62])
tensor([[ 20,  23,  26,  29],
        [ 56,  68,  80,  92],
        [ 92, 113, 134, 155],
        [128, 158, 188, 218]])

Приведенные выше результаты могут быть не интуитивно понятными, поэтому взгляните ниже:

import torch
vec = torch.arange(4)
mtx = torch.arange(12)
m1 = mtx.reshape(4,3)
m2 = mtx.reshape(3,4)

print(vec @ vec==torch.dot(vec,vec))
print(vec @ m1) # 本句直接使用torch.mv()无法执行。
print(m2 @ vec==torch.mv(m2,vec))
print(m1 @ m2==torch.mm(m1,m2))

Используйте @, чтобы заменить три функции выше.

  • Выполнение операции @ над одномерным тензором
  • Выполнение операций над одномерными и двумерными тензорами — это mv
  • Выполнение операции @ на двумерном тензоре мм
>>
tensor(True)
tensor([42, 48, 54])
tensor([True, True, True])
tensor([[True, True, True, True],
        [True, True, True, True],
        [True, True, True, True],
        [True, True, True, True]])

А как насчет второго, который нельзя заменить? Чтобы удовлетворить обсессивно-компульсивное расстройство, вы можете:

import torch
vec = torch.arange(4)
mtx = torch.arange(12).reshape(4,3)

print(vec @ mtx) # 本句直接使用torch.mv()无法执行。
print(torch.mm(vec.reshape(1,4),mtx))

print(vec @ mtx==torch.mm(vec.reshape(1,4),mtx))
>>
tensor([42, 48, 54])
tensor([[42, 48, 54]])
tensor([[True, True, True]])

Добавьте еще один факел.matmul

vec = torch.arange(3)
mtx = torch.arange(12).reshape(3,4)
print(torch.matmul(vec,mtx))
print(torch.matmul(vec,vec))
print(torch.matmul(mtx.T,mtx))
print(torch.matmul(mtx.T,vec))
>>
tensor([20, 23, 26, 29])
tensor(5)
tensor([[ 80,  92, 104, 116],
        [ 92, 107, 122, 137],
        [104, 122, 140, 158],
        [116, 137, 158, 179]])
tensor([20, 23, 26, 29])

и@Выглядит похоже, и это может быть:

  • Выполнение операции над одномерным тензором точечно
  • Выполнение операций над одномерными и двумерными тензорами — это mv
  • Выполнение операции над двумерным тензором мм

Но разница между ними в том, что матмуль не ограничивается одним и двумя измерениями и может выполнять умножение многомерных тензоров.