学习目标
🍀 掌握张量基本运算
🍀 掌握阿达玛积、点积运算
🍀 掌握PyTorch指定运算设备
PyTorch 计算的数据都是以张量形式存在, 我们需要掌握张量各种运算. 并且, 我们可以在 CPU 中运算, 也可以在 GPU 中运算.
🍔 张量的基本运算
基本运算中,包括 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()
程序输出结果:
tensor([[3, 7, 4], [0, 0, 6]]) -------------------------------------------------- tensor([[13, 17, 14], [10, 10, 16]]) -------------------------------------------------- tensor([[13, 17, 14], [10, 10, 16]]) tensor([[-87, -83, -86], [-90, -90, -84]]) tensor([[1300, 1700, 1400], [1000, 1000, 1600]]) tensor([[0.1300, 0.1700, 0.1400], [0.1000, 0.1000, 0.1600]]) tensor([[-13, -17, -14], [-10, -10, -16]])
🍔 什么是阿达玛积
阿达玛积指的是矩阵对应位置的元素相乘.
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()
程序输出结果:
tensor([[ 5, 12], [21, 32]]) -------------------------------------------------- tensor([[ 5, 12], [21, 32]]) --------------------------------------------------
🍔 点积运算要求
点积运算要求第一个矩阵 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)
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 + data2 print(data) if __name__ == '__main__': test04()
程序输出结果:
存储设备: cpu 存储设备: cuda:0 存储设备: cpu 存储设备: cuda:0 存储设备: cpu 存储设备: cpu 存储设备: cuda:0 cuda:0 cpu
🍔 小节
在本小节中,我们主要学习的主要内容如下:
- 张量基本运算函数 add、sub、mul、div、neg 等函数, add_、sub_、mul_、div_、neg_ 等 inplace 函数
- 张量的阿达玛积运算 mul 和运算符 * 的用法
- 点积运算:
- 运算符 @ 用于进行两个矩阵的点乘运算
- torch.mm 用于进行两个矩阵点乘运算, 要求输入的矩阵为2维
- torch.bmm 用于批量进行矩阵点乘运算, 要求输入的矩阵为3维
- torch.matmul 对进行点乘运算的两矩阵形状没有限定.
- 对于输入都是二维的张量相当于 mm 运算.
- 对于输入都是三维的张量相当于 bmm 运算
- 对数输入的 shape 不同的张量, 对应的最后几个维度必须符合矩阵运算规则
- 将变量移动到 GPU 设备的方法,例如: cuda 方法、直接在 GPU 上创建张量、使用 to 方法指定设备