

PyTorch 中矩阵乘法介绍
source link: https://xujinzh.github.io/2022/08/08/pytorch-multiply-methods/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

torch 中 Tensor 的乘法有几种方法,如 *
、torch.mul
、torch.multiply
、torch.dot
、torch.mv
、torch.mm
、torch.matmul
、torch.einsum
等,它们之间有什么区别,都是做什么操作。本篇对其进行介绍。
逐元素乘法
逐元素(element-wise)乘法就是对于两个Tensor对象(如矩阵和矩阵、矩阵和实数等,向量也是矩阵的一种),分别按对应元素进行实数普通乘法。
*、torch.mul、torch.multiply
*
、torch.mul
、torch.multiply
三者操作含义是相同的。torch.multiply
是 torch.mul
的别名,*
是 torch.mul
的简写。
当相乘的两个张量,一方维度低、一方维度高时,将采用广播(broadcast)的形式。实数是 0 维张量、向量是 1 维张量、二维矩阵是 2 维张量等等。
广播,简而言之,如果两个对象维度不一样,那么它的张量参数可以自动扩展为相等大小(无需复制数据)。
import torch
矩阵和实数乘
x = torch.ones(2, 3)
x
tensor([[1., 1., 1.],
[1., 1., 1.]])
x * 2, torch.mul(x, 2), torch.multiply(x, 2)
(tensor([[2., 2., 2.],
[2., 2., 2.]]),
tensor([[2., 2., 2.],
[2., 2., 2.]]),
tensor([[2., 2., 2.],
[2., 2., 2.]]))
矩阵和向量(一维矩阵)乘
x = torch.ones(2, 3)
x
tensor([[1., 1., 1.],
[1., 1., 1.]])
y = torch.tensor([1, 2, 3], dtype=torch.float32)
y
tensor([1., 2., 3.])
x * y, torch.mul(x, y), torch.multiply(x, y)
(tensor([[1., 2., 3.],
[1., 2., 3.]]),
tensor([[1., 2., 3.],
[1., 2., 3.]]),
tensor([[1., 2., 3.],
[1., 2., 3.]]))
矩阵和矩阵乘
x = torch.ones(2, 3)
x
tensor([[1., 1., 1.],
[1., 1., 1.]])
y = torch.randn(2, 3)
y
tensor([[-0.7308, -1.9904, 0.0606],
[ 0.8398, -0.9562, 0.3506]])
x * y, torch.mul(x, y), torch.multiply(x, y)
(tensor([[-0.7308, -1.9904, 0.0606],
[ 0.8398, -0.9562, 0.3506]]),
tensor([[-0.7308, -1.9904, 0.0606],
[ 0.8398, -0.9562, 0.3506]]),
tensor([[-0.7308, -1.9904, 0.0606],
[ 0.8398, -0.9562, 0.3506]]))
向量和向量乘
x = torch.randn(4, 1)
x
tensor([[-0.3991],
[ 2.1165],
[-0.8744],
[-1.3571]])
y = torch.randn(1, 4)
y
tensor([[ 2.0050, -0.5762, 0.3147, -0.3944]])
x * y, torch.mul(x, y), torch.multiply(x, y)
(tensor([[-0.8002, 0.2299, -0.1256, 0.1574],
[ 4.2436, -1.2194, 0.6661, -0.8347],
[-1.7531, 0.5038, -0.2752, 0.3448],
[-2.7211, 0.7819, -0.4271, 0.5352]]),
tensor([[-0.8002, 0.2299, -0.1256, 0.1574],
[ 4.2436, -1.2194, 0.6661, -0.8347],
[-1.7531, 0.5038, -0.2752, 0.3448],
[-2.7211, 0.7819, -0.4271, 0.5352]]),
tensor([[-0.8002, 0.2299, -0.1256, 0.1574],
[ 4.2436, -1.2194, 0.6661, -0.8347],
[-1.7531, 0.5038, -0.2752, 0.3448],
[-2.7211, 0.7819, -0.4271, 0.5352]]))
二维矩阵和三维矩阵
x = torch.tensor([[1, 2], [2, 3]])
x
tensor([[1, 2],
[2, 3]])
y = torch.tensor([[[1, 2], [2, 3]], [[-1, -2], [-2, -3]]])
y
tensor([[[ 1, 2],
[ 2, 3]],
[[-1, -2],
[-2, -3]]])
x * y
tensor([[[ 1, 4],
[ 4, 9]],
[[-1, -4],
[-4, -9]]])
torch.mul(x, y)
tensor([[[ 1, 4],
[ 4, 9]],
[[-1, -4],
[-4, -9]]])
torch.multiply(x, y)
tensor([[[ 1, 4],
[ 4, 9]],
[[-1, -4],
[-4, -9]]])
torch.dot
计算两个一维张量的点积。即数学中,两个一维向量的内积,对应元素相乘然后再相加,得到一个实数。要求两个张量元素个数相同。
x = torch.tensor([2, 3])
x
tensor([2, 3])
y = torch.tensor([2, 1])
y
tensor([2, 1])
torch.dot(x, y)
tensor(7)
torch.mv
矩阵和向量乘积。对应高等代数(或线性代数)中一个矩阵和一个一维向量的点积(矩阵乘法)。但注意,这里和数学中唯一区别是,矩阵的列数和向量的列数保存一致,而不是矩阵的列数和向量的行数保存一致。这里默认把向量看作列向量。mv 表示矩阵(matrix)和向量(vector)的首字母。
mat = torch.ones(2, 3)
mat
tensor([[1., 1., 1.],
[1., 1., 1.]])
vec = torch.ones(3)
vec
tensor([1., 1., 1.])
torch.mv(mat, vec)
tensor([3., 3.])
torch.mm
矩阵和矩阵乘积。对应高等代数(或线性代数)中一个矩阵和另一个矩阵的点积(矩阵乘法)。要求第一个矩阵的列数和第二个矩阵的行数保存一致。mm 表示两个矩阵(matrix)的首字母。
mat1 = torch.randn(2, 3)
mat1
tensor([[ 0.1216, -1.0658, 0.4596],
[ 0.0281, -0.6817, 0.9793]])
mat2 = torch.randn(3, 3)
mat2
tensor([[-0.9294, -1.4270, 2.8876],
[-0.5021, 0.4515, 0.3465],
[ 0.5015, -0.9415, -0.3981]])
torch.mm(mat1, mat2)
tensor([[ 0.6526, -1.0874, -0.2011],
[ 0.8073, -1.2699, -0.5448]])
torch.matmul
矩阵点乘。对应数学中的矩阵(包括向量)的点乘运算。它包含了上面的两个向量的点积torch.dot
、矩阵和向量的乘积 torch.mv
、矩阵和矩阵的乘积 torch.mm
,能够用一个函数表示上面所有的运算。
x = torch.ones(3)
x
tensor([1., 1., 1.])
y = torch.ones(3)
y
tensor([1., 1., 1.])
torch.dot(x, y)
tensor(3.)
torch.matmul(x, y)
tensor(3.)
矩阵与向量相乘
x = torch.ones(3, 4)
x
tensor([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
y = torch.ones(4)
y
tensor([1., 1., 1., 1.])
torch.mv(x, y)
tensor([4., 4., 4.])
torch.matmul(x, y)
tensor([4., 4., 4.])
x = torch.ones(3, 4)
x
tensor([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
y = torch.ones(4, 2)
y
tensor([[1., 1.],
[1., 1.],
[1., 1.],
[1., 1.]])
torch.mm(x, y)
tensor([[4., 4.],
[4., 4.],
[4., 4.]])
torch.matmul(x, y)
tensor([[4., 4.],
[4., 4.],
[4., 4.]])
torch.bmm
bmm 是批量矩阵乘法。能够同时进行多个矩阵的点乘。bmm 分别表示 batch(批量)、matrix(矩阵)、matrix(矩阵) 的首字母。
input = torch.ones(2, 3, 2)
input
tensor([[[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.]]])
mat2 = torch.randn(2, 2, 3)
mat2
tensor([[[ 9.2534e-01, -1.7897e+00, -3.0873e-01],
[-1.5857e+00, 8.6526e-01, 5.2600e-02]],
[[ 3.9796e-01, 6.3333e-01, -1.0749e+00],
[ 2.4290e-05, 8.3245e-03, -1.4999e-01]]])
output = torch.bmm(input, mat2)
output
tensor([[[-0.6604, -0.9244, -0.2561],
[-0.6604, -0.9244, -0.2561],
[-0.6604, -0.9244, -0.2561]],
[[ 0.3980, 0.6417, -1.2249],
[ 0.3980, 0.6417, -1.2249],
[ 0.3980, 0.6417, -1.2249]]])
torch.einsum()
爱因斯坦求和约定函数。能够包含上面所有乘法运算。
x = torch.arange(6, dtype=torch.float32).reshape(2, 3)
x
tensor([[0., 1., 2.],
[3., 4., 5.]])
torch.einsum("ij->ji", x)
tensor([[0., 3.],
[1., 4.],
[2., 5.]])
矩阵元素和
torch.einsum("ij->", x)
tensor(15.)
torch.einsum("ij->j", x)
tensor([3., 5., 7.])
torch.einsum("ij->i", x)
tensor([ 3., 12.])
矩阵和向量相乘
x
tensor([[0., 1., 2.],
[3., 4., 5.]])
y = torch.ones(3)
y
tensor([1., 1., 1.])
torch.einsum("ij,j->i", x, y)
tensor([ 3., 12.])
torch.mv(x, y)
tensor([ 3., 12.])
x
tensor([[0., 1., 2.],
[3., 4., 5.]])
y = torch.ones(3, 2)
y
tensor([[1., 1.],
[1., 1.],
[1., 1.]])
torch.einsum("ij,jk->ik", x, y)
tensor([[ 3., 3.],
[12., 12.]])
torch.mm(x, y)
tensor([[ 3., 3.],
[12., 12.]])
逐元素乘积
x
tensor([[0., 1., 2.],
[3., 4., 5.]])
y = torch.ones(x.shape) * 3
y
tensor([[3., 3., 3.],
[3., 3., 3.]])
torch.einsum("ij,ij->ij", x, y)
tensor([[ 0., 3., 6.],
[ 9., 12., 15.]])
torch.mul(x, y)
tensor([[ 0., 3., 6.],
[ 9., 12., 15.]])
x * y
tensor([[ 0., 3., 6.],
[ 9., 12., 15.]])
torch.multiply(x, y)
tensor([[ 0., 3., 6.],
[ 9., 12., 15.]])
# 如果想要计算逐元素乘积后再累加求和,可以使用如下方法
torch.einsum("ij,ij->", x, y)
tensor(45.)
x = torch.ones(3)
x
tensor([1., 1., 1.])
y = torch.ones(3) * 2
y
tensor([2., 2., 2.])
torch.einsum("i,j->", x, y)
tensor(18.)
x
tensor([1., 1., 1.])
y
tensor([2., 2., 2.])
torch.einsum("i,j->ij", x, y)
tensor([[2., 2., 2.],
[2., 2., 2.],
[2., 2., 2.]])
batch 多矩阵相乘
input = torch.ones(2, 3, 2)
input
tensor([[[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.]]])
mat2 = torch.randn(2, 2, 3)
mat2
tensor([[[-1.4658, -1.3135, -0.0189],
[ 0.0271, -0.7247, -0.3334]],
[[ 0.4132, 0.8727, 2.3141],
[ 0.8487, -0.6309, -1.4993]]])
torch.einsum("ijk, ikl->ijl", input, mat2)
tensor([[[-1.4387, -2.0382, -0.3522],
[-1.4387, -2.0382, -0.3522],
[-1.4387, -2.0382, -0.3522]],
[[ 1.2619, 0.2417, 0.8148],
[ 1.2619, 0.2417, 0.8148],
[ 1.2619, 0.2417, 0.8148]]])
output = torch.bmm(input, mat2)
output
tensor([[[-1.4387, -2.0382, -0.3522],
[-1.4387, -2.0382, -0.3522],
[-1.4387, -2.0382, -0.3522]],
[[ 1.2619, 0.2417, 0.8148],
[ 1.2619, 0.2417, 0.8148],
[ 1.2619, 0.2417, 0.8148]]])
求矩阵的迹
# trace
torch.einsum("ii", torch.ones(4, 4))
tensor(4.)
求矩阵的对角向量
# diagonal
torch.einsum("ii->i", torch.ones(4, 4))
tensor([1., 1., 1., 1.])
求两个向量的外积
# outer product
x = torch.ones(5)
y = torch.ones(4)
torch.einsum("i,j->ij", x, y)
tensor([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
Recommend
-
114
-
16
以往我分析了一些AI加速器的设计,包括TPU,FSD,华为达芬奇等,无一例外都是从已经给出的设计出发,去分析其优缺点和应用范围。在之前的文章中,关于这些设计是如何完成的,其背后是否有一定设计原则和理念的内容均没有进行探讨。而这两...
-
7
见08年论文矩阵乘法。USACO 奶牛接力dp中涉及转移可以用邻接矩阵?我还是迷迷糊糊不太会扩展。//奶牛接力 #include <cstdio> #include <a...
-
7
使用CUDA实现一个简单的矩阵乘法 矩阵乘法可以说是高性能计算领域的新手村问题,同时也是很多重要应用的基石,它的基本算法相当简单,但是为了达到令人满意的速度,却需要花费相当大的精力来优化。下面,我们从最简单的实现开始...
-
1
← 浴中奇思:为什么洗澡的时候 会勃发奇思妙想majer @ 2022.10.07 , 19:53...
-
3
关于ChatGPT的一切;CUDA入门之矩阵乘;PyTorch 2.0发布|AI系统前沿动态 ...
-
6
1D Grid, 1D Block 向量加法#include <stdio.h>#include <math.h>#define N 100const double EPS = 1E-6;void __global__ add(const double *x, const double *y,...
-
7
AI算力碎片化:矩阵乘法的启示 ...
-
4
关于Matrix 我们先看看chatGpt是如何介绍矩阵的。 矩阵是数学中的一个概念,它是由数字按照矩形排列而成的矩形阵列。矩阵由行和列组成,行表示矩阵的水平方向,列表示矩阵的垂直方向。 一个矩阵可以用以下形式表示: A = [a11...
-
3
以3D视角洞悉矩阵乘法,这就是AI思考的样子 作者:机器之心 2023-10-04 09:36:58 本文首先会介绍可视化方法,通过可视化一些简单矩阵乘法和表达式来建立直觉,然后再深入一些扩展示例。 如果能以 3D 方式...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK