- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊
前言
在训练模型时,通常会把整个数据集分成多个批次(batch),每个批次用于更新模型的参数。而epoch是指整个数据集被完整地遍历一次的过程,模型需要多次遍历整个数据集来逐渐优化参数,每一次遍历(epoch)都能让模型学到更多东西。为了防止模型在训练过程中记住数据的顺序,在每个epoch开始时打乱数据顺序,从而提高泛化能力。
实验概述
采用CNN实现四种天气状态的识别。本文通过新增Dropout层并且将最大池化层调整成平均池化层,达到增加模型的泛化能力。
一、实验目标
- 本地读取并加载数据。
- 测试集accuracy到达93%
二、卷积层、池化层的计算
下面的网络数据shape变化过程为:
3, 224, 224(输入数据)
-> 12, 220, 220(经过卷积层1)
-> 12, 216, 216(经过卷积层2)-> 12, 108, 108(经过池化层1)
-> 24, 104, 104(经过卷积层3)
-> 24, 100, 100(经过卷积层4)-> 24, 50, 50(经过池化层2)
-> 60000 -> num_classes(4),手动计算过程:
三、我的环境:
● 语言环境:Python3.8
● 编译器:jupyter notebook
● 深度学习环境:Pytorch
● 数据:不对外披露
实现代码
一、前期准备
1.设置GPU
2.导入数据
● 第一步:使用pathlib.Path()函数将字符串类型的文件夹路径’./data/‘转换为对象。
● 第二步:使用glob()方法获取’./data/'路径下的所有文件路径,并以列表形式存储在对象中。
● 第三步:通过split()函数对上述对象中的每个文件路径执行分割操作,获得各个文件所属的类别名称,并进行存储。
● 第四步:打印存储列表,显示每个文件所属的类别名称。
使用列表推导式加载和显示./data/cloudy/文件路径下的图像:
数据归一化处理:
3. 划分数据集
● train_size表示训练集大小,通过将总体数据长度的80%转换为整数得到;
● test_size表示测试集大小,是总体数据长度减去训练集大小。
使用torch.utils.data.random_split()方法进行数据集划分。
该方法将总体数据total_data按照指定的大小比例([train_size, test_size])随机划分为训练集和测试集,并将划分结果分别赋值给train_dataset和test_dataset两个变量。
torch.utils.data.DataLoader 是 PyTorch 中用于加载和管理数据的一个实用工具类。它允许以小批次的方式迭代数据集,DataLoader 构造函数接受多个参数,下面是一些常用的参数及其解释:
- dataset(必需参数):这是数据集对象,通常是 torch.utils.data.Dataset 的子类,它包含了数据样本。
- batch_size(可选参数):指定每个小批次中包含的样本数。默认值为 1。
- shuffle(可选参数):如果设置为 True,则在每个 epoch 开始时对数据进行洗牌,以随机打乱样本的顺序。这对于训练数据的随机性很重要,以避免模型学习到数据的顺序性。默认值为 False。
- num_workers(可选参数):用于数据加载的子进程数量。通常,将其设置为大于 0 的值可以加快数据加载速度,特别是当数据集很大时。默认值为 0,表示在主进程中加载数据。
二、模型构建
构建简单的CNN网络:在卷积层和全连接层之间,可以使用torch.flatten()也可以使用下面的x.view()或者torch.nn.Flatten()。torch.nn.Flatten()与TensorFlow中的Flatten()层类似,前两者则仅仅是一种数据集拉伸操作(将二维数据拉伸为一维),torch.flatten()方法不会改变x本身,而是返回一个新的张量。而x.view()方法则是直接在原有数据上进行操作
三、训练模型
1.设置超参数
2.编写训练函数
3.编写测试函数
,不进行梯度下降对网络权重进行更新,不需要传入优化器
4.正式训练: 如图-测试集accuracy到达93%
- model.train()
model.train()的作用是启用 Batch Normalization 和 Dropout。
如果模型中有BN层(Batch Normalization)和Dropout,需要在训练时添加model.train()。model.train()是保证BN层能够用到每一批数据的均值和方差。对于Dropout,model.train()是随机取一部分网络连接来训练更新参数。
- model.eval()
model.eval()的作用是不启用 Batch Normalization 和 Dropout。
如果模型中有BN层(Batch Normalization)和Dropout,在测试时添加model.eval()。model.eval()是保证BN层能够用全部训练数据的均值和方差,即测试过程中要保证BN层的均值和方差不变。对于Dropout,model.eval()是利用到了所有网络连接,即不进行随机舍弃神经元。
训练完train样本后,生成的模型model要用来测试样本。在model(test)之前,需要加上model.eval(),否则的话,有输入数据,即使不训练,它也会改变权值。这是model中含有BN层和Dropout所带来的的性质。