pytorch基础知识-运算(上)

2019-11-17 23:03:25 浏览数 (1)

本节主要讲解pytorch中,tensor和矩阵的各类数学运算。

首先从最基本的加减乘除开始

.add (相加)

.sub (相减)

.mul (相乘)

.div (相除)

代码语言:javascript复制
import torch
a = torch.rand(2, 3)
b = torch.rand(3)
c = torch.add(a, b)
d = torch.sub(a, b)
e = torch.mul(a, b)
f = torch.div(a, b)
print('c, d, e, f=', c, 'n', d, 'n', e, 'n', f)

输出为

代码语言:javascript复制
c, d, e, f= tensor([[0.8616, 0.8815, 0.5835],
        [1.3956, 1.0337, 0.9400]]) 
 tensor([[-0.7527,  0.0045,  0.2063],
        [-0.2186,  0.1567,  0.5628]]) 
 tensor([[0.0440, 0.1943, 0.0745],
        [0.4750, 0.2610, 0.1417]]) 
 tensor([[0.0675, 1.0102, 2.0935],
        [0.7291, 1.3573, 3.9837]])

而在tensor的乘法运算中,*又分为element_wise(元素相乘) 和 martix_matmul(矩阵形式相乘)两种。而按矩阵形式相乘有三种表达形式:

(1)torch.mm (只适用于 2D矩阵,不推荐使用)

(2)torch.matmal (适用于2D和3D矩阵相乘,推荐使用)

(3)@ 与torch.matmal原理相同,是matmal的另外一种写法

举例

代码语言:javascript复制
a = torch.rand(2, 2)
# print(a)
b = torch.rand(2, 3)
c = torch.mm(a, b)
d = torch.matmul(a, b)
e = a@b
print('c, b, e = ', c, 'n', d, 'n', e)

输出

代码语言:javascript复制
c, b, e =  tensor([[1.0027, 0.2992, 0.3707],
        [1.0420, 0.2906, 0.3730]]) 
 tensor([[1.0027, 0.2992, 0.3707],
        [1.0420, 0.2906, 0.3730]]) 
 tensor([[1.0027, 0.2992, 0.3707],
        [1.0420, 0.2906, 0.3730]])

为更直观的了解其用法,下面以一个具体的例子进行讲解

代码语言:javascript复制
a = torch.rand(4, 784)
# 物理意义为4张图片,全部打平为28*28的数据
# 在图片处理中经常需要使用降维操作,本例考虑将[4, 784]降维成[4, 512]
# 因此按照以上思路,考虑需要构建一个新矩阵,使得[4, 784] * [784, 512] = [4, 512]
# 上面的[784, 512]即为考虑构建的新矩阵
# 下面开始构建
w = torch.rand(784, 512)
out = torch.matmul(a, w)
print(out.shape)

输出为

代码语言:javascript复制
torch.Size([4, 512])

而在对高于2维的矩阵进行运算时,使用torch.mm时会报错

代码语言:javascript复制
# 对于4维矩阵运算,在使用torch.mm时会报错
a = torch.rand(4, 1, 64, 32)
b = torch.rand(4, 3, 32, 64)
print(torch.mm(a, b).shape)

输出

代码语言:javascript复制
RuntimeError: matrices expected, got 4D, 4D tensors at ..atensrcTH/generic/THTensorMath.cpp:956

因此该改用torch.matmul进行计算

代码语言:javascript复制
# 高于2维的矩阵运算,应使用torch.matmul函数
a = torch.rand(4, 1, 64, 32)
b = torch.rand(4, 3, 32, 64)
print(torch.matmul(a, b).shape)

输出

代码语言:javascript复制
torch.Size([4, 3, 64, 64])

这里注意,四维计算时前两个维度和后两个维度分别进行计算,因此(4, 1)被broadcasting成(4, 3),32*32被消掉,后面变成了(64, 64)。

在此之上,我们更改b,再进行计算

代码语言:javascript复制
a = torch.rand(4, 3, 64, 32)
b = torch.rand(4, 64, 32)
print(torch.matmul(a, b).shape)

输出会报错

代码语言:javascript复制
RuntimeError: The size of tensor a (3) must match the size of tensor b (4) at non-singleton dimension 1

报错原因在于b会broadcasting成[1, 4, 64, 32],但与a相乘时,dim=1位置上的3和4不相同,无法进行运算。因此矩阵在进行乘法运算时,要么就相同dim位置上的数值相同,要么就为1,以方便进行broadcasting。

0 人点赞