效果预览:
第一步,搭建环境和环境配置
把我们之前创建好的环境配置进去
第二步,把我们的train文件进行训练
设置合适的训练参数
-
data_dir:
- 作用: 指定训练和验证数据所在的文件夹路径。
- 联系: 该路径用于加载数据集(如 CIFAR-10),这些数据将被用于训练和验证模型。
-
batch_files:
- 作用: 包含多个数据批次的文件名,用于逐批加载数据。
- 联系: 与
data_dir结合,程序会从指定路径中读取这些批次的数据,以便进行训练。
-
batch_size:
- 作用: 指定每个批次处理的样本数量(在这个例子中为 64)。
- 联系: 在训练过程中,每次使用
batch_size指定的数量来更新模型参数。这可以影响训练的效率和模型的收敛速度。
-
num_epochs:
- 作用: 指定整个训练数据集将被遍历的次数(在这个例子中为 10)。
- 联系: 与
batch_size一起决定了训练过程中总共会有多少次参数更新。每个 epoch 会使用所有数据进行一次训练。
-
learning_rate:
- 作用: 控制模型在每次参数更新时步伐的大小。较小的学习率可能导致训练过程缓慢,而较大的学习率可能导致不稳定或收敛失败。
- 联系: 与
num_epochs和batch_size结合,影响模型收敛的效果和速度。
-
device:
- 作用: 指定使用 CPU 还是 GPU 进行训练。
- 联系: 训练过程中使用的硬件会影响计算速度。使用 GPU 通常会加快训练过程,尤其是在处理大规模数据时。
数据预处理
-
transforms.Compose:
- 作用: 用于将多个图像变换组合成一个复合变换,便于在数据加载时统一应用。
- 联系: 通过
Compose可以按顺序应用多个变换,以简化数据预处理流程。
-
transforms.RandomHorizontalFlip() :
- 作用: 随机水平翻转图像,以增强模型的泛化能力。
- 联系: 通过数据增强,可以提高模型对不同图像姿态的鲁棒性,减少过拟合。
-
transforms.RandomCrop(32, padding=4) :
- 作用: 随机裁剪图像,生成一个 32x32 的图像,裁剪前图像会加上 4 像素的填充。
- 联系: 这种方法可以增加训练过程中图像的多样性,使模型能更好地学习到重要特征。
-
transforms.ToTensor() :
- 作用: 将图像数据转换为 PyTorch 的张量格式,并将像素值缩放到 [0, 1] 的范围内。
- 联系: 这是将图像数据准备好以供模型训练的必要步骤。
-
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) :
- 作用: 对张量进行归一化处理,将每个通道的均值调整为 0.5,标准差调整为 0.5。
- 联系: 归一化有助于加速收敛,并提高模型的稳定性和性能。
加载数据
我们可以看到在经过对数据的的一些处理最后返回的是这样的一个变量:
数据处理过后是一个这样的对象
self.data_dir=D:\\my\\cnn_model\\cifar-10-batches-py
self.batch_files= ["data_batch_1", "data_batch_2", "data_batch_3", "data_batch_4", "data_batch_5"]
self.data
self.labels
batch_size=64,
shuffle=True
数据加载好了,现在开始搭建一个cnn模型:
第一步,先搭建一个前向传播
import torch.nn as nn # 导入神经网络模块
import torch.nn.functional as F # 导入功能性操作模块
class CNNModel(nn.Module):
def __init__(self):
super(CNNModel, self).__init__() # 调用父类的构造函数
'''CNNModel 继承自 torch.nn.Module,而 torch.nn.Module 自身有一个构造函数用来初始化很多重要的功能,比如将模型置为训练模式、定义 parameters 等等。如果没有调用 super(CNNModel, self).__init__(),torch.nn.Module 的初始化逻辑就不会被执行,模型的行为可能不符合预期。'''
# 定义一个卷积层:输入通道为三(RGB)图像,输出通道为32,卷积核大小为三,步幅为一,填充为一
'''就是设置了32个算子,每个算子都对输入的所有通道进行卷积,然后卷积完成以后生成一个新的通道,有32个算子因此有32个新的通道'''
self.conv=nn.Conv2d(3,32,kernel_size=3,stride=1,padding=1)
'''上一层的输出就是下一层的输入'''
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1)
'''32*32*3'''
'''32*32*32'''
'''32*32*64'''
'''32*32*128'''
'''定义池化层'''
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
'''16*16*32'''
self.fc1 = nn.Linear(128 * 4 * 4, 512)
# 定义第二个全连接层:输入特征数为512,输出特征数为10(类别数)
self.fc2 = nn.Linear(512, 10)
def forward(self,x):
# 卷积 激活 池化
x = self.pool(F.relu(self.conv1(x)))
'''16*16*32'''
x = self.pool(F.relu(self.conv2(x)))
'''8*8*64'''
x = self.pool(F.relu(self.conv3(x)))
'''4*4*128'''
# 将多维张量展平为一维:-1表示自动计算批量大小,128 * 4 * 4是展平后的特征数
x = x.view(-1, 128 * 4 * 4)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x # 返回模型的输出
其中:
知识点一:CNNModel 继承自 torch.nn.Module,而 torch.nn.Module 自身有一个构造函数用来初始化很多重要的功能,比如将模型置为训练模式、定义 parameters 等等。如果没有调用 super(CNNModel, self).init(),torch.nn.Module 的初始化逻辑就不会被执行,模型的行为可能不符合预期。
知识点二:设置了32个算子,每个算子都对输入的所有通道进行卷积,然后卷积完成以后生成一个新的通道,有32个算子因此有32个新的通道
第二步,对训练集进行训练
验证集进行验证
此时一个cnn模型就搭好了