Мало знаний, большой вызов! Эта статья участвует в "Необходимые знания для программистов«Творческая деятельность.
Там так много умножений, и я, честно говоря, до сих пор их тщательно не прочесала, поэтому делаю все сразу.
Сначала объявите вектор и 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
- Выполнение операции над двумерным тензором мм
Но разница между ними в том, что матмуль не ограничивается одним и двумя измерениями и может выполнять умножение многомерных тензоров.