()
torch.mul(input, other, *, out=None)
输入:两个张量矩阵;输出:他们的点乘运算结果
用途:
①实现两个张量矩阵的点乘运算,可以实现广播功能(具体见案例代码)。
②实现矩阵的数值乘法(一个常数k与矩阵做乘法,对应于广播机制)
注意:
- 若输入的两个矩阵形状不一致,则会通过广播功能进行数据扩充,然后再进行点乘
- 整数矩阵与浮点数矩阵做点乘,结果是浮点数矩阵
案例代码:
①普通点乘
import torch
a=torch.tensor([[1,2,3],[4,5,6]])
b=torch.tensor([[2,3,4],[5,6,7]])
c=torch.mul(a,b)
print('a:',a)
print('b:',b)
print('c:',c)
输出
a: tensor([[1, 2, 3],
[4, 5, 6]])
b: tensor([[2, 3, 4],
[5, 6, 7]])
c: tensor([[ 2, 6, 12],# 第一行对应点相乘
[20, 30, 42]])# 第二行对应点相乘
②若矩阵大小不一致,则会通过广播机制进行扩充
import torch
a=torch.tensor([[1,2,3],[4,5,6]])
b=torch.tensor([2,3,4])
c=torch.mul(a,b)
print('a:',a)
print('b:',b)
print('c:',c)
输出:
a: tensor([[1, 2, 3],
[4, 5, 6]])
b: tensor([2, 3, 4])
c: tensor([[ 2, 6, 12],# b上的元素同时与a里面两个元素做点乘
[ 8, 15, 24]])
再看一个例子:
import torch
mat_1=t.arange(8*512*14*14).reshape((8,512,14,14))
mat_2=t.arange(14*14).reshape(14,14)
mat_3=torch.mul(mat_1,mat_2)
print(mat_1.shape)
print(mat_2.shape)
print(mat_3)
print(mat_3.shape)
输出:
torch.Size([8, 512, 14, 14])
torch.Size([14, 14])
torch.Size([8, 512, 14, 14])
注:广播机制相当于做了一个复制扩充处理,如上个案例中的mat_2从两维扩充到了四维,并且在第一维度复制了8次,第二维度复制了512次,然后再与mat_1做点乘运算。
广播机制条件:
①两个数组的维数不相等,但是它们的后缘维度的轴长相符(从末尾开始算起的维度)(即上个案例)
②两个矩阵中对应的(从后向前对应)维度的尺寸大小相等(mat_1与mat_2在后两个维度大小均是14),若不相等,则必须有一方在该维度上尺寸大小是1。(比如上个案例中,若mat_2尺寸为[1,14,14],则仍可以通过广播机制进行扩充运算,结果与上述案例相同)
案例:
import torch
mat_1=t.arange(8*512*14*14).reshape((8,512,14,14))
mat_2=t.arange(2*14*14).reshape(2,14,14)
mat_3=torch.mul(mat_1,mat_2)
报错:
RuntimeError: The size of tensor a (512) must match the size of tensor b (2) at non-singleton dimension 1
原因:2与512尺寸大小不同,并且尺寸都不是1
在计算机视觉领域中,常用于特征图与注意力图的相乘,特征图相当于上述案例的mat_1(batch_size=4,512张14×14的特征图),注意力图相当于上述案例的mat_2(14×14)。先将注意力图复制512次,和原来每个批次中特征图尺寸相匹配,再整体复制4次,对应4组特征图,最后做点乘运算。
官方文档
()l:/docs/stable/generated/?highlight=mul#
点个赞支持一下吧