PyTorch 计算的数据都是以张量形式存在, 我们需要掌握张量各种运算. 并且, 我们可以在 CPU 中运算, 也可以在 GPU 中运算.
- 基本运算
- 阿达玛积
- 点积运算
- 指定运算设备
1. 基本运算
基本运算中,包括 add、sub、mul、div、neg 等函数, 以及这些函数的带下划线的版本 add_、sub_、mul_、div_、neg_,其中带下划线的版本为修改原数据。
import numpy as np import torch def test(): data = torch.randint(0, 10, [2, 3]) print(data) print('-' * 50) # 1. 不修改原数据 new_data = data.add(10) # 等价 new_data = data + 10 print(new_data) print('-' * 50) # 2. 直接修改原数据 # 注意: 带下划线的函数为修改原数据本身 data.add_(10) # 等价 data += 10 print(data) # 3. 其他函数 print(data.sub(100)) print(data.mul(100)) print(data.div(100)) print(data.neg()) if __name__ == '__main__': test()
2. 阿达玛积
阿达玛积指的是矩阵对应位置的元素相乘.
import numpy as np import torch def 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 * data2 print(data) print('-' * 50) if __name__ == '__main__': test()
3. 点积运算
点积运算要求第一个矩阵 shape: (n, m),第二个矩阵 shape: (m, p), 两个矩阵点积运算 shape 为: (n, p)。
- 运算符 @ 用于进行两个矩阵的点乘运算
- torch.mm 用于进行两个矩阵点乘运算, 要求输入的矩阵为2维
- torch.bmm 用于批量进行矩阵点乘运算, 要求输入的矩阵为3维
- torch.matmul 对进行点乘运算的两矩阵形状没有限定.
- 对于输入都是二维的张量相当于 mm 运算
- 对于输入都是三维的张量相当于 bmm 运算
- 对数输入的 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 @ data2 print(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) # 第二个张量: (6, 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) print(torch.matmul(torch.randn(3, 5, 4), torch.randn(3, 4, 5)).shape) # 3. torch.bmm 函数的用法 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__': test02()
4. 指定运算设备
PyTorch 默认会将张量创建在 CPU 控制的内存中, 即: 默认的运算设备为 CPU。我们也可以将张量创建在 GPU 上, 能够利用对于矩阵计算的优势加快模型训练。将张量移动到 GPU 上有两种方法:
- 使用 cuda 方法
- 直接在 GPU 上创建张量
- 使用 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(): # 判断 GPU 设备是否存在 device = 'cuda:0' if torch.cuda.is_available() else 'cpu' data1 = torch.tensor([10, 20, 30], device=device) 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 + data2 print(data) if __name__ == '__main__': test04()
至此,本篇文章完毕.