张量数值计算
一.前言
前面我们介绍了一下pytorch还有张量的创建,而本章节我们就来介绍一下张量的计算,类型转换以及操作,这个是十分重要的,我们的学习目标是:掌握张量基本运算、掌握阿达玛积、点积运算 掌握PyTorch指定运算设备。
PyTorch 计算的数据都是以张量形式存在, 我们需要掌握张量各种运算. 并且, 我们可以在 CPU 中运算, 也可 以在 GPU 中运算.
二.张量基本运算
基本运算中,包括 add、sub、mul、div、neg 等函数, 以及这些函数的带下划线的版本 add、sub、mul、 div、neg_,其中带下划线的版本为修改原数据。
import numpy as np
import torchdef test():data = torch.randint(0, 10, [2, 3])print(data)print('-' * 50)# 1. 不修改原数据new_data = data.add(10) # 等价 new_data = data + 10print(new_data)print('-' * 50)# 2. 直接修改原数据# 注意: 带下划线的函数为修改原数据本身data.add_(10) # 等价 data += 10print(data)# 3. 其他函数print(data.sub(100))print(data.mul(100))print(data.div(100))print(data.neg())if __name__ == '__main__':test()
结果展示,大家对着结果就能理解每个函数的意思了。
tensor([[3, 2, 4],
[5, 2, 6]])
--------------------------------------------------
tensor([[13, 12, 14],
[15, 12, 16]])
--------------------------------------------------
tensor([[13, 12, 14],
[15, 12, 16]])
tensor([[-87, -88, -86],
[-85, -88, -84]])
tensor([[1300, 1200, 1400],
[1500, 1200, 1600]])
tensor([[0.1300, 0.1200, 0.1400],
[0.1500, 0.1200, 0.1600]])
tensor([[-13, -12, -14],
[-15, -12, -16]])
三.阿达玛积
阿达玛积指的是矩阵对应位置的元素相乘.
import numpy as np
import torchdef test():data1 = torch.tensor([[1, 2], [3, 4]])data2 = torch.tensor([[5, 6], [7, 8]])# 第⼀种⽅式data = torch.mul(data1, data2)print(data)print('-' * 50)# 第⼆种⽅式data = data1 * data2print(data)print('-' * 50)if __name__ == '__main__':test()
结果展示:
tensor([[ 5, 12],
[21, 32]])
--------------------------------------------------
tensor([[ 5, 12],
[21, 32]])
--------------------------------------------------
四.点积运算
点积运算要求第⼀个矩阵 shape: (n, m),第⼆个矩阵 shape: (m, p), 两个矩阵点积运算 shape 为: (n, p)。
1. 运算符 @ ⽤于进⾏两个矩阵的点乘运算
2. torch.mm ⽤于进⾏两个矩阵点乘运算, 要求输⼊的矩阵为2维
3. torch.bmm ⽤于批量进⾏矩阵点乘运算, 要求输⼊的矩阵为3维
4. torch.matmul 对进⾏点乘运算的两矩阵形状没有限定.
1. 对于输⼊都是⼆维的张量相当于 mm 运算.
2. 对于输⼊都是三维的张量相当于 bmm 运算
3. 对数输⼊的 shape 不同的张量, 对应的最后⼏个维度必须符合矩阵运算规则
import numpy as np
import torch# 1. 点积运算
def test01():data1 = torch.tensor([[1, 2], [3, 4], [5, 6]])data2 = torch.tensor([[5, 6], [7, 8]])# 第⼀种⽅式data = data1 @ data2print(data)print('-' * 50)# 第⼆种⽅式data = torch.mm(data1, data2)print(data)print('-' * 50)# 第三种⽅式data = torch.matmul(data1, data2)print(data)print('-' * 50)# 2. torch.mm 和 torch.matmull 的区别
def test02():# matmul 可以两个维度可以不同# 第⼀个张量: (3, 4, 5)# 第⼆个张量: (5, 4)# torch.mm 不可以相乘,⽽ matmul 则可以相乘print(torch.matmul(torch.randn(3, 4, 5), torch.randn(5, 4)).shape)print(torch.matmul(torch.randn(5, 4), torch.randn(3, 4, 5)).shape)# 3. torch.mm 函数的⽤法def test03():# 批量点积运算# 第⼀个维度为 batch_size# 矩阵的⼆三维要满⾜矩阵乘法规则data1 = torch.randn(3, 4, 5)data2 = torch.randn(3, 5, 8)data = torch.bmm(data1, data2)print(data.shape)if __name__ == '__main__':test01()test02()test03()
结果展示:
tensor([[19, 22],
[43, 50],
[67, 78]])
--------------------------------------------------
tensor([[19, 22],
[43, 50],
[67, 78]])
--------------------------------------------------
tensor([[19, 22],
[43, 50],
[67, 78]])
--------------------------------------------------
torch.Size([3, 4, 4])
torch.Size([3, 5, 5])
torch.Size([3, 4, 8])
五.指定设备运算
PyTorch 默认会将张量创建在 CPU 控制的内存中, 即: 默认的运算设备为 CPU。我们也可以将张量创建在 GPU 上, 能够利⽤对于矩阵计算的优势加快模型训练。将张量移动到 GPU 上有两种⽅法:
1. 使⽤ cuda ⽅法
2. 直接在 GPU 上创建张量
3. 使⽤ to ⽅法指定设备
import torch# 1. 使⽤ cuda ⽅法
def test01():data = torch.tensor([10, 20, 30])print('存储设备:', data.device)# 如果安装的不是 gpu 版本的 PyTorch# 或电脑本身没有 NVIDIA 卡的计算环境# 下⾯代码可能会报错data = data.cuda()print('存储设备:', data.device)# 使⽤ cpu 函数将张量移动到 cpu 上data = data.cpu()print('存储设备:', data.device)# 输出结果:# 存储设备: cpu# 存储设备: cuda:0# 存储设备: cpu# 2. 直接将张量创建在 GPU 上
def test02():data = torch.tensor([10, 20, 30], device='cuda:0')print('存储设备:', data.device)# 使⽤ cpu 函数将张量移动到 cpu 上data = data.cpu()print('存储设备:', data.device)# 输出结果:# 存储设备: cuda:0# 存储设备: cpu# 3. 使⽤ to ⽅法
def test03():data = torch.tensor([10, 20, 30])print('存储设备:', data.device)data = data.to('cuda:0')print('存储设备:', data.device)# 输出结果:# 存储设备: cpu# 存储设备: cuda:0# 4. 存储在不同设备的张量不能运算def test04():data1 = torch.tensor([10, 20, 30], device='cuda:0')data2 = torch.tensor([10, 20, 30])print(data1.device, data2.device)# RuntimeError: Expected all tensors to be on the same device,# but found at least two devices, cuda:0 and cpu!data = data1 + data2print(data)if __name__ == '__main__':test03()
六.总结
在本⼩节中,我们主要学习的主要内容如下:
1. 张量基本运算函数 add、sub、mul、div、neg 等函数, add、sub、mul、div、neg_ 等 inplace 函数
2. 张量的阿达玛积运算 mul 和运算符 * 的⽤法
3. 点积运算:
1. 运算符 @ ⽤于进⾏两个矩阵的点乘运算
2. torch.mm ⽤于进⾏两个矩阵点乘运算, 要求输⼊的矩阵为2维
3. torch.bmm ⽤于批量进⾏矩阵点乘运算, 要求输⼊的矩阵为3维
4. torch.matmul 对进⾏点乘运算的两矩阵形状没有限定.
1. 对于输⼊都是⼆维的张量相当于 mm 运算.
2. 对于输⼊都是三维的张量相当于 bmm 运算
3. 对数输⼊的 shape 不同的张量, 对应的最后⼏个维度必须符合矩阵运算规则
4. 将变量移动到 GPU 设备的⽅法,例如: cuda ⽅法、直接在 GPU 上创建张量、使⽤ to ⽅法指定设备