B站我是土堆视频学习笔记,链接:https://www.bilibili.com/video/BV1hE411t7RN/?spm_id_from=333.999.0.0
1. Transforms
介绍
transforms在计算机视觉工具包torchvision下,包含了常用的图像预处理方法,可以数据扩增,提高模型的泛化能力,包括以下功能:
- 数据中心化
- 数据标准化
- 缩放
- 裁剪
- 旋转
- 翻转
- 填充
- 噪声添加
- 灰度变换
- 线性变换
- 仿射变换
- 亮度、饱和度及对比度变换
运行机制
采用transforms.Compose(),将一系列的transforms有序组合,实现时按照这些方法依次对图像操作。
train_transform = transforms.Compose([
transforms.Resize((32, 32)), # 缩放
transforms.RandomCrop(32, padding=4), # 随机裁剪
transforms.ToTensor(), # 图片转张量,同时归一化
transforms.Normalize(norm_mean, norm_std), # 标准化均值为0标准差为1
])
构建Dataset实例,DataLoder实例。
# 构建MyDataset实例
train_data = RMBDataset(data_dir=train_dir, transform=train_transform)
# 构建DataLoder
train_loader = DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
补充
__call__
:使实例能够像函数一样被调用,同时不影响实例本身的生命周期
2. torch.nn
官方文档链接:https://pytorch.org/docs/1.10/nn.html#
torch.nn是pytorch中自带的一个函数库,里面包含了神经网络中使用的一些常用函数。
Containers
Module
所有神经网络模块的基类。你的模型也应该继承这个类。模块还可以包含其他模块,允许将它们嵌套在树结构中。你可以将子模块赋值为普通属性:
import torch.nn as nn
import torch.nn.functional as F
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__() # 初始化父类,继承
# 一般把网络中具有可学习参数的层放在构造函数__init__()中
# 如全连接层、卷积层等
self.conv1 = nn.Conv2d(1, 20, 5)
self.conv2 = nn.Conv2d(20, 20, 5)
# forward()方法必须要重写
def forward(self, x):
# 一般把不具有可学习参数的层使用nn.functional放在构造函数中
# 如ReLU、dropout、BatchNormanation层
x = F.relu(self.conv1(x))
return F.relu(self.conv2(x))
Sequential
forward()会方便很多
一个时序容器。Modules 会以他们传入的顺序被添加到容器中。当然,也可以传入一个OrderedDict。
使用Sequential创建小型模型
当model
运行时,输入将首先传递给Conv2d(1,20,5)
;Conv2d(1,20,5)
的输出将被用作第一个ReLU
的输入;第一个ReLU
的输出将成为Conv2d(20,64,5)
的输入;最后,Conv2d(20,64,5)
的输出将被用作第二个ReLU
的输入。
model = nn.Sequential(
nn.Conv2d(1,20,5),
nn.ReLU(),
nn.Conv2d(20,64,5),
nn.ReLU()
)
# #在OSequentialrderedDict中使用。
model = nn.Sequential(OrderedDict([
('conv1', nn.Conv2d(1,20,5)),
('relu1', nn.ReLU()),
('conv2', nn.Conv2d(20,64,5)),
('relu2', nn.ReLU())
]))
使用案例
class MyModel (nn. Module):
def __init__(self):
super (MyModel, self).__init__()
self.model1 = Sequential (
Conv2d (3, 32,5, padding=2),
MaxPool2d (2),
Conv2d (32, 32, 5, padding=2),
MaxPool2d (2),
Conv2d (32, 64, 5, padding=2),
MaxPool2d (2),
Flatten(),
Linear (1024, 64),
Linear (64, 10)
)
def forward (self, x):
x = self.model1 (x)
return x
Convolution Layers(卷积层)
Conv2d的示例
torch.nn.Conv2d(in_channels, # 输入图像通道数
out_channels, # 卷积产生的通道数
kernel_size, # 卷积核尺寸
stride=1, # 卷积步长
padding=0, # 填充操作,控制padding_mode的数目
dilation=1, # 扩张操作(空洞卷积)
groups=1, # 分组卷积
bias=True, # 在输出中添加一个可学习的偏差
padding_mode='zeros', # padding模式
device=None,
dtype=None)
Pooling layers(池化层)
MaxPool2d的示例
torch.nn.MaxPool2d(
kernel_size, # 窗口大小
stride=None, # 窗口移动的步长,默认值是kernel_size
padding=0, # 填充大小
dilation=1, # 扩张操作(空洞卷积)
return_indices=False, # 返回最大索引以及输出
ceil_mode=False # 默认向下取整(保留不足kernel_size的最大值)
)
其他层
-
Non-linear Activations(非线性激活层)
- 常见的包括:ReLU、Sigmoid、Softmax、Threshold、Tanh
-
Normalization Layers(归一化层)
- 归一化可以加快神经网络的训练(梯度下降更快)
- BatchNorm2d(),输入主要是num_features(channel)
-
Recurrent Layers(循环层)
- 包括RNN、LSTM
-
Linear Layers(线性层)
- Linear(),对输入数据进行线性变换
y
=
x
A
T
+
b
y=xA^T+b
y=xAT+b ,参数列表:
- in_features:每个输入样本的大小
- out_features:每个输出样本的大小
- bias:默认学习偏置
- Linear(),对输入数据进行线性变换
y
=
x
A
T
+
b
y=xA^T+b
y=xAT+b ,参数列表:
-
- 防止过拟合
-
- Embedding,嵌入层,主要是存NLP中token的向量
-
Loss Functions(损失函数)
- 常见的包括:L1Loss、MSELoss、CrossEntropyLoss
3. 模型的使用
预训练模型加载
vgg16为例
vgg16 = torchvision.models.vgg16(pretrained=True)
模型修改
# 直接加到最后
vgg16.add_module('add_linear', nn.Linear(1000, 10))
# 加到某个模块的最后
vgg16.classifier.add_module('add_linear', nn.Linear(1000, 10))
# 修改某一层
vgg16.classifier[6] = nn.Linear(1000, 10)
模型的保存与加载
方式1:保存模型结构+参数
torch.save(vgg16, 'vgg16_save1.pth')
# 加载方式
model = torch.load('vgg16_save1.pth')
注意:如果是自己定义的模型,其实还是要把模型定义的部分import进来,不然加载的时候会不知道模型结构
方式2:只保存参数(官方推荐,内存小)
# 将其状态(参数)保存为字典格式
torch.save(vgg16.state_dict(), 'vgg16_save2.pth')
# 加载方式,还需要加载模型结构
vgg16 = torchvision.models.vgg16(pretrained=False)
vgg16.load_state_dict()
model = torch.load('vgg16_save2.pth')