Pytorch基本语法
Pytorch的基本操作
张量的创建
Tensor张量:张量的概念类似于Numpy中的ndarray数据结构,最大的区别在于Tensor可以利用GPU的加速功能。
在使用Pytorch时,需要先引入模块:
1 |
|
下面是Pytorch中创建张量的基本语法:
- torch.tensor 根据指定数据创建张量
- torch.Tensor 根据形状创建张量, 其也可用来创建指定数据的张量
- torch.IntTensor、torch.FloatTensor、torch.DoubleTensor 创建指定类型的张量
1 |
|
创建线性和随机张量:
- torch.arange 和 torch.linspace 创建线性张量
- torch.random.init_seed 和 torch.random.manual_seed 随机种子设置
- torch.randn 创建随机张量
- rand和randn:
- torch.rand(): 这个函数生成一个张量,其中的值是在 $[0, 1)$ 区间内均匀分布的随机数。你可以通过指定张量的形状来生成不同形状的张量。
- torch.randn(): 这个函数生成一个张量,其中的值是从标准正态分布(均值为0,标准差为1)中随机采样得到的。你同样可以通过指定张量的形状来生成不同形状的张量。
Pytorch的基本运算操作
1 |
|
创建01张量
- torch.ones 和 torch.ones_like 创建全1张量
- torch.zeros 和 torch.zeros_like 创建全0张量
- torch.full 和 torch.full_like 创建全为指定值张量
1 |
|
张量元素类型转换
- tensor.type(torch.DoubleTensor)
- torch.double()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import torch
def test():
data = torch.full([2, 3], 10)
# 将 data 元素类型转换为 float64 类型
# 1. 第一种方法
data = data.type(torch.DoubleTensor)
# 转换为其他类型
# data = data.type(torch.ShortTensor)
# data = data.type(torch.IntTensor)
# data = data.type(torch.LongTensor)
# data = data.type(torch.FloatTensor)
# 2. 第二种方法
data = data.double()
# 转换为其他类型
# data = data.short()
# data = data.int()
# data = data.long()
# data = data.float()
张量的基本运算
基本运算中,包括 add、sub、mul、div、neg 等函数,以及这些函数的 in-place 版本。
注意:所有的in-place的操作函数都有一个下划线的后缀,如x.copy_(y),都会直接改变x的值
阿达玛积指的是矩阵对应位置的元素相乘,用 * 表示。
点积运算指一般意义上的矩阵乘法,要求矩阵可乘,用运算符 @ 表示。
torch.matmul 对进行点乘运算的两矩阵形状没有限定,利用广播机制进行。
1 |
|
对于PyTorch的四则运算会优先进行元素级别的操作,即两个张量之间对应位置元素进行运算。这就要求张量满足同型或满足广播规则。
和一个常数进行运算时,会将张量中的每一个元素都进行运算,可以看作将常数广播为同型张量。
- 广播规则:
广播规则是指在进行张量运算时,PyTorch会自动调整张量的形状,使得它们能够进行元素级别的操作。
具体来说,当两个张量的形状不完全匹配时,PyTorch会根据一组规则对它们进行扩展,使它们的形状能够对齐,从而进行运算。
广播规则的基本思想是,如果两个张量的形状在某个维度上相同,或者其中一个张量在某个维度上的长度为1,那么可以在该维度上进行广播。广播操作会在这些维度上复制张量,使其形状与另一个张量相匹配,从而进行运算。
具体来说,广播规则包括以下几点:
维度数增加:如果两个张量的维度数不同,会在较小的张量的前面添加一个或多个维度,直到两个张量的维度数相同。
维度长度为1的扩展:对于每个维度,如果两个张量在该维度上的长度不同,且其中一个张量在该维度上的长度为1,可以在该维度上对该张量进行扩展,使其长度与另一个张量相同。
扩展之后形状相同:经过广播之后,两个张量的形状必须是相同的才能进行元素级别的操作。
1 |
|
指定运算设备
将张量移动到 GPU 上有两种方法:
- 使用 cuda 方法
- 直接在 GPU 上创建张量
- 使用 to 方法指定设备
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import torch
# 1. 使用 cuda 方法
def test01():
data = torch.tensor([10, 20 ,30])
data = data.cuda()
# 2. 直接将张量创建在 GPU 上
def test02():
data = torch.tensor([10, 20, 30], device='cuda:0')
# 使用 cpu 函数将张量移动到 cpu 上
data = data.cpu()
# 3. 使用 to 方法
def test03():
data = torch.tensor([10, 20, 30])
data = data.to('cuda:0')
张量类型转换
- 使用 Tensor.numpy 函数可以将张量转换为 ndarray 数组,但是共享内存,可以使用 copy 函数避免共享。
- 使用 from_numpy 可以将 ndarray 数组转换为 Tensor,默认共享内存,使用 copy 函数避免共享。
- 使用 torch.tensor 可以将 ndarray 数组转换为 Tensor,默认不共享内存。
- 对于只有一个元素的张量,使用 item 方法将该值从张量中提取出来。
张量拼接操作
torch.cat 函数可以将两个张量根据指定的维度拼接起来。
1
2
3
4
5
6
7
8
9
10import torch
# 生成形状为3,5,4的三维张量
# 第0维(也就是维度索引为0的维度)是大小为3,通常表示这个张量中包含3个样本或者批次。
# 第1维(维度索引为1的维度)是大小为5,代表每个样本中的特征数量。
# 第2维(维度索引为2的维度)是大小为4,代表每个特征的维度或者特征向量的长度。
data1 = torch.randint(0, 10, [3, 5, 4])
data2 = torch.randint(0, 10, [3, 5, 4])
# 按第0维拼接
new_data = torch.cat([data1, data2], dim=0)torch.stack 函数可以将两个张量根据指定的维度叠加起来,会增加新的维度。
两个[2, 2] 的张量堆叠,产生大小为 [2, 2, 2] 的张量。
张量索引操作
简单行、列索引
1
2
3
4
5
6
7import torch
data = torch.randint(0, 10, [4, 5])
data[0] # 第一行
data[:, 0] # 第一列
data[0, 1] # 返回(0, 1) 位置即第一行第二列的元素,返回一个张量
data[[[0], [1]], [1, 2]] # 返回 0、1 行的 1、2 列共4个元素范围索引
1
2
3
4# 前3行的前2列数据
data[:3, :2]
# 第2行到最后的前2列数据
data[2:, :2]布尔索引
1
2
3
4# 第三列大于5的行数据,输出整行
data[data[:, 2] > 5]
# 第二行大于5的列数据
data[:, data[1] > 5]
张量形状操作
reshape 函数可以在保证张量数据不变的前提下改变数据的维度,将其转换成指定的形状,前提是数据个数不变。
ranspose 函数可以实现交换张量形状的指定维度, 例如: 一个张量的形状为 (2, 3, 4) 可以通过 transpose 函数把 3 和 4 进行交换, 将张量的形状变为 (2, 4, 3)
squeeze 函数用删除 shape 为 1 的维度,unsqueeze 在每个维度添加 1, 以增加数据的形状。
1 |
|
输出:
1 |
|