一文搞懂pytorch中的乘法

各种乘法运算中会多次涉及到广播机制。先说下numpy中的广播机制。了解的直接跳过看第二部分即可

一 numpy广播机制Broadcast

原理:python在进行numpy算术运算采用的是element-wise方式(逐元素操作的方式),此时要求两个数据的维度必须相同。

维度不同时,会触发广播操作使其维度相同。不满足广播操作的情况下会直接报错。

先理解下维度,便于理解broadcast,数据的维度指两个方面,维度的个数和维度的大小。

如:a = np.ones(4,3)维度个数是2,第一维大小是4,第二维大小是3

广播的执行过程:

1.如果维度个数不同,则在维度较少的左边补1,使得维度的个数相同。

2.各维度的维度大小不同时,如果有维度为1的,直接将该维拉伸至维度相同

#%%
import numpy as np
a = np.arange(12).reshape((3,1,4))
b = np.array([1,2,3,4]).reshape((4,1))
print(a.shape,b.shape)
print((a+b).shape)
#输出
(3, 1, 4) (4, 1)
(3, 4, 4)

二 pytorch中的乘法

1. torch.dot()

向量点乘,得到的结果是scale标量。对应元素相乘并相加

a = torch.tensor([1,2,3])
b = torch.tensor([4,5,6])
print(torch.sum(torch.mul(a,b)))
print(torch.dot(a,b))
tensor(32)
tensor(32)

2.torch.mul和*

使用element wise相乘方式,逐元素运算,维度不相同时执行广播机制

a = torch.tensor(list(range(12))).view(4,3)
b = torch.tensor([1,2,3])
c = torch.mul(a,b)
d = a * b
print(c.shape)
print(d.shape)
tensor(32)
tensor(32)

3.torch.mm()

矩阵相乘,

#torch.mm() 矩阵相乘
a = torch.randn(4,3)
b = torch.randn(3,5)
print(torch.mm(a,b).shape)
torch.Size([4, 5])

注意:矩阵乘法的维度必须满足mn x nk,不匹配会报错。不会进行广播机制。

a = torch.randn(4,3)
b = torch.randn(3,)
print(torch.mm(a,b).shape)

 维度不匹配会报错

---------------------------------------------------------------------------

IndexError                                Traceback (most recent call last)

<ipython-input-16-0ca53c83c1d7> in <module>
      2 a = torch.tensor(np.arange(12)).view(4,3)
      3 b = torch.tensor(np.arange(3)).view(3,)
----> 4 print(torch.mm(a,b).shape)
      5 
      6 

IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 1)

4 torch.bmm()

批量矩阵相乘。 

注意 bmm中两个矩阵的后两维度必须满足矩阵相乘的条件,mn nk

torch.mm(bmn, bnk) = bnk,不会进行广播机制,想使用广播机制可以用torch.matmul()

a = torch.randn(6,3,4)
b = torch.randn(6,4,5)
print(torch.matmul(a,b).shape)
torch.Size([6, 3, 5])

5 torch.matmul()

#两个tensor的矩阵乘法,具体操作取决于两个tensor的shape,按两个矩阵维度的不同可分为以下五种

1)如果两个矩阵都是1维,则执行向量点乘dot操作。

2)如果两个矩阵都是2维,这执行矩阵相乘mm操作。

3)第一个矩阵是1维,第二个是2维,行向量乘以矩阵。(线性代数矩阵和向量相乘),向量x矩阵相当于矩阵行向量的线性组合

4)第一个矩阵是2维,第二个是1维,矩阵乘以列向量。矩阵x向量,相当于矩阵列向量的线性组合

5)如果两个都至少是1维,并且至少一个维度大于2。会执行batch矩阵相乘torch.bmm。后两维进行矩阵相乘mm。

相当于将每个矩阵看做一个元素,然后逐元素进行矩阵乘法。例如a.shape=[j,k,m,n] b.shape=[k,n,k]。将每个矩阵看做一个element时,a.shape=[j,k],b.shape=[k]

然后按element-wise的方式进行mm矩阵乘法。element-wise方式要求维度个数和大小必须相同。不相同执行广播机制。

测试:

#情形1
a = torch.randn(3)
b = torch.randn(3)
torch.matmul(a,b).shape
#torch.Size([])

#情形2
a = torch.randn(3,4)
b = torch.randn(4,5)
torch.matmul(a,b).shape
#torch.Size([3, 5])

#情形3
a = torch.randn(3)
b = torch.randn(3,5)
torch.matmul(a,b).shape
#torch.Size([5])

#情形4
a = torch.randn(3,4)
b = torch.randn(4)
torch.matmul(a,b).shape
#torch.Size([3])

#情形5 
#5.1 batch 矩阵相乘
a = torch.randn(5,6,3,4)
b = torch.randn(5,6,4,5)
torch.matmul(a,b).shape
#torch.Size([5, 6, 3, 5])

#5.2 缺少的非-矩阵维度(不参与矩阵运算的维度)会进行广播
a = torch.randn(5,6,3,4)
b = torch.randn(6,4,5)
torch.matmul(a,b).shape
#torch.Size([5, 6, 3, 5])

#5.3 batch 行向量x矩阵 
a = torch.randn(3)
b = torch.randn(5,6,3,4)
torch.matmul(a,b).shape
#torch.Size([5, 6, 4])

#5.4 batch 矩阵x列向量
a = torch.randn(5,6,7,8)
b = torch.randn(8)
torch.matmul(a,b).shape
#torch.Size([5, 6, 7])

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值