1.本节目标:
(1)了解什么是MNIST 数据集;
(2)了解卷积神经网络对图片处理的流程;
(3)能够看懂Python 编写的对图片分类任务的代码;
(4)在一定程度上掌握处理类似任务的编程能力。
注意:本章节使用开源机器学习库PyTorch
2.简介
刚开始接触编程的时候,一定都见过“Hello World!”,而 MNIST 数据集,就是计算机视觉中的“Hello World“数据集,这个经典的手写图像 数据集已然成为了分类算法的基础。图像的基本元素pixel。每 一 个pixel都有它的颜色值,而电脑普遍把颜 色值分为256个区间,也就是0~255。0就是黑色,255就是最亮的白色。如果这个图像是 一 个RGB 三通道图像,那一个pixel就会有3个数值,分别表示红色、绿色和蓝色3个颜色的值。这次分类任务是十分类(0~9)。
3.解决思路
(1)了解数据集,探索数据;
(2)图像处理;
(3)构建模型;
(4)用训练数据训练模型;
(5)用测试数据评估模型。
常见的图像处理部分就是对图像进行旋转、翻转、平移、重塑大小、标准化等操作。 一般来说,最常见的操作就是先旋转,再平移,再标准化。 标准化:通常指的是将某些量按照一定的比例或规则进行调整,使之符合标准格式或范围。使用Dataset
类的好处是,它可以很容易地与DataLoader
类配合使用,实现数据的批量加载和批处理。DataLoader
类是PyTorch中用于加载数据集的迭代器。它封装了Dataset
对象,并提供了一系列功能来加载和批量处理数据。DataLoader
的主要作用是提供一个高效的数据管道,使得数据可以快速地被模型处理,同时减少内存消
-
Transform 处理:
transform
是Dataset
中的一个环节,通常用于定义数据预处理和数据增强的操作。- 在 PyTorch 中,
transform
可以是一个函数或torchvision.transforms
模块中的方法,用于在加载数据时对数据进行操作,如调整大小、归一化、随机裁剪等。 - 使用
transform
的目的是将原始数据转换为适合模型训练的格式,同时可能增加数据的多样性,提高模型的泛化能力
transform处理过程:
(1)把数据转化为PIL Image图片格式。
(2)对图片进行旋转和平移(SHIFT) 的操作。
(3)把PIL Image变量转化为Tensor 变 量 。Tensor 是 PyTorch 中的变量,只有 Tensor变量才能进行训练。
(4)对Tensor 变量进行归一化,平均值是0.5,标准差是0.5。
PIL:特别是在使用机器学习库如PyTorch时,将数据转化为PIL Image图片格式是一种常见的数据预处理步骤。PIL(Python Imaging Library)是一个流行的图像处理库,它的一个后继版本是Pillow,一个更现代化、易用的图像处理库。
模型构建:
PyTorch 模型构建的三要素:
(1)继承nn.Module,让PyTorch 知道这个类是一个模型;
(2)在 init (self)中设置好需要的组件,比如卷积层(Conv)、池化层(pooling)、全连接层等;
( 3 ) 在forward(self)中用定义好的组件进行组装,依次把之前定义好的组件连起来,这样模型就定义完成了
每个全连接层都包含一个 Dropout 层(防止过拟合)、 一个 BatchNorm层(防止协方差偏移问题,称为批归一化层)和一个ReLU激活函数(线性整流函数)。 一般把这些一起称为一层网络,而不是四层网络。
过拟合:指的是模型在训练数据上表现得很好,但是对于未见过的新数据(测试数据)泛化能力差的现象。
训练模型
模型的训练主要有两个部分的操作:
(1)定义损失函数和优化器;
(2)定义训练函数。
大致思路:
定义model.train(), 说明这是训练过程;再定义 scheduler.step(); 不断从 train_ loader中取data 数据;清空梯度;通过data 和 model得到预测output; 通过output 和真实 值计算出Loss;把 Loss反向传播;更新模型参数。
清空梯度:如果不清空梯度,模型的参数更新将不准确,因为它们会包含之前迭代的梯度信息,这可能导致模型训练不稳定或无法收敛。
反向传播:反向传播是一种算法,用于计算这些梯度
梯度:在神经网络中,梯度是指损失函数对模型参数(如权重和偏置)的偏导数。梯度的方向和大小指示了损失函数增加最快的方向。网络训练一个batch的流程图。
除此之外,通常还会定义一个evaluate()函数,用来在模型训练完一个epoch后,评估 整体准确率。
epoch:一个epoch指的是整个训练数据集被用于一次完整的模型训练的过程。
这个模型是自己创建的,如果使用Google公司等创建的经典网络,就要使用到迁移学习(transfer learning)和微调(finetune) 。
import torch
import torch.nn as nn
import torch.nn.functional as func# 是一个用于导入 PyTorch 库中神经网络功能模块的语句,并将该模块重命名为 func
import torch.optim as optim#模块包含了多种优化算法,用于神经网络的参数更新
class MyCNN(nn.Moudle):
def __init__(self):#使用 def 定义函数时,语法规则要求 def 和函数名之间必须有一个空格
#创建一个pytroch的神经网络模型
super(MyCNN,self).__init__()
'''是一个在 Python 类中调用父类(超类)初始化方法的常见用法。这里的 super() 函数用于初始化或调用父类的方法。具体来说:
MyCNN 是当前类的名字。
self 是对当前类的实例的引用。
__init__() 是类的构造器方法,用于在创建类的新实例时进行初始化。
'''
#卷积层1,32通道输出,卷积核大小3*3,步长1*1,padding为1
self.Conv1=nn.Conv2d(1,32,3,1,1)#卷积层是卷积神经网络中的核心组件,它主要用于提取输入数据的局部特征。
'''
第一个参数 1 表示输入通道数。
第二个参数 32 表示输出通道数,也就是卷积层的过滤器数量。
第三个参数 3 表示卷积核的大小(这里使用的是 3x3 的卷积核)。
第四个参数 1 表示步长(stride),即卷积核移动的步长。
第五个参数 1 表示填充(padding),即在输入特征图边缘添加的填充大小。
'''
#填充是指在输入数据的边缘添加的零值,以控制输出特征图的大小
#多通道处理:在处理多通道数据(如彩色图像,其中每个像素有红、绿、蓝三个通道)时,每个过滤器也会在所有通道上应用,以提取跨通道的特征
#最大值池化,核大小2*2,步长2*2,最大值池化通常用于卷积层之后,以减少特征图的空间尺寸,同时保留重要的特征信息。这有助于提高模型的泛化能力,并减少过拟合的风险
self.pool1=nn.MaxPool2d(2,2)#一种二维池化操作,通常用于处理二维数据,如图像.
#maxpool2d 会将输入的特征图(通常是高度和宽度)划分为多个矩形区域,然后在每个区域内取最大值作为输出。这样做可以减少数据的空间尺寸,从而减少计算量,同时保留重要的特征信息。
#maxpool1d:这是一种一维池化操作,用于处理一维数据,如时间序列或文本数据
#maxpool1d 会将输入数据划分为多个子区间,然后在每个子区间内取最大值作为输出。它同样可以减少数据的尺寸,但只在一个维度上进行操作
self.Conv2=nn.Conv2d(32,64,3,1,1)
self.pool2=nn.MaxPool2d(2,2)
self.Conv3=nn.Conv2d(64,128,3,1,1)
self.pool3=nn.MaxPool2d(2,2)
#定义全连接层,全连接层将卷积层和池化层提取的局部特征进行整合,形成一个全局的特征表示。这些局部特征可能来自于图像的不同区域,全连接层通过加权求和的方式将它们结合起来
self.fc1=nn.Linear(128*3*3,768)
'''第一个参数 128*3*3 表示输入特征的维度,这里是通过将前一层的输出(例如,经过卷积和池化操作后的二维特征图)展平后得到的一维特征向量的长度。128 可能是前一层卷积层的输出通道数,3*3 可能是经过池化操作后的特征图的尺寸。
第二个参数 768 表示全连接层输出的维度,即这一层将输出一个长度为 768 的特征向量'''
self.fc2=nn.Linear(768,10)
def forward(self,x):# forward 方法中,定义了一个神经网络的前向传播过程
x=self.pool1(func.relu(self.Conv1(x)))
x=self.pool2(func.relu(self.Conv2(x)))
x=self.pool3(func.relu(self.Conv3(x)))
x=func.relu(self.fc1(x))
#softmax层,输出预测结果
x=func.softmax(x,dim=1)
return x
'''神经网络的前向传播过程:
前向传播用于计算给定输入的预测输出,然后通过反向传播(Backpropagation)来计算损失函数关于网络参数的梯度
,进而更新网络的权重和偏置。在推理过程中,前向传播用于对新的输入数据进行预测。
'''
注意:
——pycache是自动生成的,不用管。DS.store是苹果系统的,与windows无关,不影响跑代码, .pt没了也能运行, .gitignore是控制版本的,删除不影响代码运行,pyc没用可以删除了,开始训练模型之前,不会有 .pt
文件,pt文件需要保存后才存在,手动保存