- 初学Pytorch的时候都是从基本的语法开始学起的,当时看的是官网的60分钟入门。随着不断的学习,大部分时间都用于搭建网络啥的,对于一开始学的基操经常容易忘,在此整理下。
- 参考:deeplizard的pytorch教学,很好的视频教学,如有需要,可以去b站搜索。
- 后续也会更新我常用搭建网络的模板,一起加油努力!
1、Pytorch基本介绍
1.1 Pytorch常用的库
1、torch: 包含所有torch包和tensor库的顶级包
2、troch.nn: 是用于建立神经网络的包,它包含类和模块,如layer,weight和forward function
3、torch.autograd: 支持张量的导数运算,负责优化神经网络
4、torch.nn.function: 访问损失函数的API
5、torch.optim: 访问优化器 (SGD,ADAM...)
6、torch.utils: 包含数据集和数据加载器的实用程序类
7、torchvision: 访问流行的数据集、计算机视觉中的模型框架及图像转换
8、所有深度学习框架都有两个特性:张量库和计算导数的包(在pytorch中是torch和torch.autograd)
1.2 Pytorch的安装验证
import torch # 导入pytorch
print(torch.__version__) # 查看pytorch版本
print(torch.cuda.is_available()) # 判断Cuda在我目前设备上是否可用
print(torch.version.cuda) # 查看cuda的版本
[output]:
1.9.1
True
11.1
2、张量(tensor)
2.1 张量的属性(秩,轴,形状)
- 张量的秩:表示张量的维数,它的数值等于我们访问张量中某一个特定元素时所用的索引个数
- 张量的轴:张量的轴是张量的某一个特定的维度,轴的个数等于张量的值
- 张量的形状:张量的形状由每个轴的长度决定。(好好理解这句话)
import torch # 导入pytorch
t = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 创建张量,注意作为一个整体传入torch.tensor
print(t) # 打印张量
print(type(t)) # 打印张量的类型
print(t.shape) # 打印张量的形状
rank = len(t.shape) # 张量的秩等于张量形状的长度
print(rank) # 打印张量的秩
t1 = t.reshape(9, 1) # 通过reshape函数可以不改变张量的元素,根据指定的shape返回新的张量,原t张量不变
print(t1)
[output]:
tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
<class 'torch.Tensor'>
torch.Size([3, 3])
2
tensor([[1],
[2],
[3],
[4],
[5],
[6],
[7],
[8],
[9]])
2.2 Pytorch中的张量及其创建
2.2.1 pytorch中张量的属性
- 通过程序查看张量的属性(device属性用的较多)
import torch # 导入pytorch
t = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 创建张量,注意作为一个整体传入torch.tensor。
print(t.dtype)
print(t.device) # 查看设备,默认是在CPU上
t1 = t.to('cuda:0') # 复制一份到第一章显卡,t不变,返回值赋值给t1
print(t.device) # 查看t所在的设备
print(t1.device) # 查看t1所在的设备
[output]:
torch.int64
cpu
cpu
cuda:0
2.2.2 张量的创建
1、无数据的情况下创建张量
import torch # 导入pytorch
print(torch.eye(3, 3)) # 二维的单位张量
print(torch.zeros((3, 3))) # 二维的全0张量
print(torch.ones((3, 3))) # 二维的全1张量
print(torch.full((3, 3), 2)) # 创建全2张量
print(torch.rand((3, 3))) # 二维的随机张量
print(torch.arange(1, 11)) # 连续整数张量的创建
[output]:
tensor([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
tensor([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
tensor([[2, 2, 2],
[2, 2, 2],
[2, 2, 2]])
tensor([[0.4327, 0.7196, 0.9639],
[0.8271, 0.4033, 0.7611],
[0.7957, 0.3052, 0.7654]])
tensor([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
2、有数据的时候创建张量
- 四种方法
import torch # 导入pytorch
import numpy as np
t = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(torch.Tensor(t))
print(torch.tensor(t))
print(torch.as_tensor(t))
print(torch.from_numpy(t))
[output]:
tensor([[1., 2., 3.],
[4., 5., 6.],
[7., 8., 9.]])
tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
3、四种方法的区别和建议
- 1、数据类型不同
import torch # 导入pytorch
import numpy as np
t = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(torch.Tensor(t).dtype)
print(torch.tensor(t).dtype)
print(torch.as_tensor(t).dtype)
print(torch.from_numpy(t).dtype)
[output]:
torch.float32
torch.int64
torch.int64
torch.int64
第一种创建方式成为构造函数的方法,在构造一个张量的时候,采用的是全局缺省值,故而会造成数据的浮动。后面三种方法成为工厂函数的方法,会根据传入数据的类型来推断出张量的类型。(一般更加推荐工厂函数的方法)
- 工厂函数是可以指定数据类型的,但是构造函数不可以
import torch # 导入pytorch
import numpy as np
t = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(torch.tensor(t, dtype=torch.float32).dtype)
[output]:
torch.float32
- 2、数据分配内存不同
前两种方式是将数组直接拷贝到张量中,张量和数组之间互相无关。后两种是张量和数组共享数据,如果任何一方改动了数据,另一方的数据内容也会相应变化
- 3、建议
torch.tensor > torch.as_tensor > torch.from_numpy > torch.Tensor
2.2.4 张量的操作
2.2.4.1 缩减操作(得到的结果元素个数缩减了)
import torch # 导入pytorch
t = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=torch.float32)
print(t.sum()) # 返回所有元素的和
print(t.numel()) # 返回张量中的元素个数
print(t.prod()) # 返回张量中的元素的乘积。
print(t.mean()) # 均值
print(t.std()) # 方差
[output]:
tensor(45.)
9
tensor(362880.)
tensor(5.)
tensor(2.7386)
- 缩减操作可以指定对某个轴进行操作
import torch # 导入pytorch
t = torch.tensor([[1, 2, 3], [1, 2, 3], [1, 2, 3]], dtype=torch.float32)
print(t.sum(dim=0)) # 返回每一列的和
[output]:
tensor([3., 6., 9.])
其余的缩减操作也都一样
- 用的较多的argmax函数
import torch # 导入pytorch
t = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]], dtype=torch.float32)
print(t.argmax()) # 所有元素最大值的下标
print(t.argmax(dim=0)) # 返回每一列最大数的下标
print(t.argmax(dim=1)) # 返回每一行最大数的下标
[output]:
tensor(11)
tensor([3, 3, 3])
tensor([2, 2, 2, 2])
2.2.4.2 重塑操作
import torch # 导入pytorch
t = torch.tensor([[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3]], dtype=torch.float32)
print(t.shape)
print(t.flatten()) # 直接拉平成一维
print(t.flatten().shape)
print(t.reshape(1, 12)) # 重塑成新的二维是1 * 12
print(t.reshape(1, 12).shape)
print(t.reshape(1, 12).squeeze()) # 移除长度为有的轴 秩会减小
print(t.reshape(1, 12).squeeze().shape)
print(t.reshape(1, 12).squeeze().unsqueeze(dim=0)) # 添加长度为1的轴 秩会增加
print(t.reshape(1, 12).squeeze().unsqueeze(dim=0).shape)
print(t) # 这里表示以上所有操作都不改变原本的t,以上操作可以赋值给一个新的张量
[output]:
torch.Size([3, 4])
tensor([1., 1., 1., 1., 2., 2., 2., 2., 3., 3., 3., 3.])
torch.Size([12])
tensor([[1., 1., 1., 1., 2., 2., 2., 2., 3., 3., 3., 3.]])
torch.Size([1, 12])
tensor([1., 1., 1., 1., 2., 2., 2., 2., 3., 3., 3., 3.])
torch.Size([12])
tensor([[1., 1., 1., 1., 2., 2., 2., 2., 3., 3., 3., 3.]])
torch.Size([1, 12])
tensor([[1., 1., 1., 1.],
[2., 2., 2., 2.],
[3., 3., 3., 3.]])
- 对于flatten操作,常用的参数是第一个参数start_dim,表示从哪个维度开始拉平
一般在卷积层到全连接层直接,都会进行flatten操作,只保留batch_size维度,其余维度拉平
import torch # 导入pytorch
t1 = torch.tensor([
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]
])
t2 = 2 * t1
t3 = 3 * t1
print(t1.shape)
print(t2.shape)
print(t3.shape)
t = torch.stack((t1, t2, t3)) # 将三个张量合并,添加一个batch_size的维度
print(t.shape)
t = t.reshape((3, 1, 4, 4)) # 模拟一个3张通道数为1,高和宽是4的图片张量
# 在进入全连接层的时候,我们需要将后面的维度拉平,将flatten的起始维度设为1即可
t = t.flatten(start_dim=1)
print(t.shape)
[output]:
torch.Size([4, 4])
torch.Size([4, 4])
torch.Size([4, 4])
torch.Size([3, 4, 4])
torch.Size([3, 16])