总体流程
- 定义网络结构
- 定义数据变换
- 定义超参数,损失函数,优化方法,自适应学习率等…
读取训练集与测试集(自定义数据集,多种读入方式等..)
开始训练:训练一个Epoch
自适应学习率更新
循环:训练一个batch——从dataloader读取一个mini batch- 转换为cuda变量
- 梯度清0
FORWARD - 将数据输入模型得到结果
- 根据结果得到预测标签
- 计算train loss
BACKWARD - 反向计算梯度
- 优化器更新
统计本batch
- 统计本epoch
【注】
①如果是测试,则取消[自适应学习率更新]和[BACKWARD]的步骤即可
训练和测试可以结合起来 train=datalodaer(trainset…),test=dataloader(testset…)
则在开始训练一个epoch的时候,加一个循环 for phase in [train,test]
即可,后面的在测试不需要的步骤作判断if phase is train: do
就行
②可以设置一个全局的最优准确率,然后记录下来最佳准确率,并储存当时的最优模型权重
③注意设置模型模式,model.train(True)
设置为训练模式model.eval(True)
设置为测试模式
定义网络结构
在定义网络结构的时候,如下形式
# 定义的网络结构类必须继承自nn.Module
class myNet(nn.Module):
# 注意传入参数self到结构函数
# init中的参数为初始化网络的参数
def __init__(self):
super().__init__
# 定义网络
# 单个定义
self.s1 = nn.Conv2d(......)
# 或集合定义
self.s1 = nn.Sequential(
nn.Conv2d(......),
nn.ReLU()
)
# 全连接层(对于卷积神经网络用于分类)
self.fc = nn.Linear()
# 注意传入参数self和x(输入矩阵)!
# forward中的参数为训练的时候要传入的参数 比如求output = model(x)时
def forward(self,x):
x = self.conv1(x)
x = self.fc(x)
# 经过特征提取层后,要扁平化才能进入fc层!
x = x.view(x.size(0), -1)
return F.softmax(x)
注意,一个误区:定义网络是定义网络的结构!输入一般输入一个batch,对该batch的处理为网络的内容
nn包含了所有的层结构定义组件, F包含了所有的函数, nn中的每个组件都需要添加到nn.Module容器中才能使用. def参数中的self即指向nn.Module(指向本类,而本类继承自nn.Module), 通过定义self.diyiceng = nn.Conv2d(xxx) 即将组件添加到了nn.Module容器中
nn.Sequential 组合一系列组件定义
#eg
self.conv2 = nn.Sequential(
nn.Conv2d(16, 32, 5, 1, 2),
nn.ReLU(),
nn.MaxPool2d(2)
)
#这里就将三个组件组合成一个组件了
#注意里面直接写组件组成即可 不是变量定义
建立深度学习模型一般实践
数据预处理与特征工程
- 向量化
- 值归一化
- 处理缺省值
- 特征工程
过拟合 - 获取更多数据、数据增强等
- 缩小网络规模
- 应用权重正则化
- 应用dropout
欠拟合 - 获取更多数据
- 增加权重
一般流程
- 问题定义与数据集创建
- 选择模型评估标准
- 评估协议(测试集 验证集)
- 准备数据
- 模型基线(创建一个非常简单的模型来打破基线分数 如二分类为0.5)
- 训练大达到过拟合
- 应用正则化
- 学习率选择策略