基于 LeNet 网络的 MNIST 数据集图像分类

发布于:2025-03-08 ⋅ 阅读:(110) ⋅ 点赞:(0)

1.LeNet的原始实验数据集MNIST

名称:MNIST手写数字数据集

数据类型:灰度图 (一通道)

图像大小:28*28

类别数:10类(数字0-9)

1.通过torchvision.datasets.MNIST下载并保存到本地为JPEG图片:

下载数据集并保存图片形式(download_mnist.py)

库:sys,os,tqdm

图片命名的格式为:子数据集名_在子数据集中的编号_真实值标签。

图片大小:28*28

 2.使用gzip解析MNIST数据集文件parse_mnist.py

MNIST的图片和标签均通过二进制文件进行保存(.gz),无法直接在Windows中查看手写数字的图片和标签,通过gzip解压,转换为numpy数组。

将标签数据转换为one-hot编码:将每个标签转换为一个向量,其中该标签对应的索引位置为 1,其他位置为 0。

one-hot编码

将类别标签转化为一个 长度为类别数的二进制向量,每个类别的位置对应为 1,其它位置为 0。

one-hot编码

将类别标签转化为一个 长度为类别数的二进制向量,每个类别的位置对应为 1,其它位置为 0。

  • 数字 0[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  • 数字 1[0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
  • 数字 2[0, 0, 1, 0, 0, 0, 0, 0, 0, 0]

3、预处理数据集(prepare_data.py)

调用parse_mnist函数对原始的mnist数据进行解析,创建数据加载器train_loader

  1. 归一化:将加载的图像数据除以 255.0,将图像的像素值从 [0, 255] 范围缩放到 [0, 1]。
  2. 转换为 Tensor:将NumPy 数组转换为 PyTorch 的 Tensor 。
  3. 重塑图像:将图像数据从 28x28 的二维数组重塑为符合神经网络输入要求的形状 (-1, 1, 28, 28)。
  4. 创建数据集和数据加载器:

train_dataset = TensorDataset(train_image, train_label)
#TensorDataset:数据集类,将图像和标签数据封装成一个数据集
train_loader=(train_dataset,batch_size=64,shuffle=True)
#DataLoader:数据加载器类,数据集分成小批次,shuffle=True可打乱

2.LeNet神经网络模型

公式

1.N = (W-F+2P)/S+1

卷积后尺寸=(输入-卷积核+加边像素数)/步长 +1

用于计算卷积层/池化层输出的尺寸,参数含义:

N:输出特征图的大小

W:输入特征图的大小

F:卷积核的大小(5*5)

P:填充(padding)的大小,表示在输入的边缘填充多少像素

S: 步长(stride),卷积核每次滑动的步幅

2.输出通道数 = 卷积核组数量

输入通道数=上一层的输出通道数

卷积层通道数逐渐增加

3.输出图像尺度计算

N = (W-F+2P)/S+1

  • 第一层:C1卷积层

输入:28*28*1

参数:self.c1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5, padding=2,stride=1)

输出:28*28*6(padding=2宽高不变,通道数为6)

  • 第二层:S2池化层(使图像尺寸减半)

输入:28*28*6

参数:self.s2 = nn.AvgPool2d(kernel_size=2, stride=2,padding=0)

池化核大小默认等于步长,使输出大小是输入大小的一半

输出:14*14*6

  • 第三层:C3卷积层

输入:14*14*6

参数:self.c3 = nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5,padding=0,stride=1)

输出:10*10*16

  • 第四层:S4池化层

输入:10*10*16

参数:self.s4 = nn.AvgPool2d(kernel_size=2, stride=2)

输出:5*5*16

  • 第五层:C5卷积层

输入:5*5*16

参数self.c5 = nn.Conv2:d(in_channels=16, out_channels=120, kernel_size=5,padding=0,stride=1)

输出:1*1*120

概念

卷积层

卷积核:二维数组

主要功能:对输入数据进行特征提取,卷积操作实质上是把卷积核当滤波器在图像上特征提取。

卷积步骤:

  1. 卷积窗口从输入数组的最左上方,从左往右、从上到下,依次在输入数组上滑动。
  2. 窗口中的输入子数组与卷积核按元素相乘并求和,得到输出数组中相应位置的元素。

池化层

基本操作:缩小图片,保留重要特征。不会裁剪删除内容。

池化步骤:

  1. 池化层对输入数据的局部区域(池化窗口)计算输出,取最大值或平均值,最终降低特征图的尺寸。

最大池化Max Pooling

取局部区域的最大值

作用:保留最明显的特征(边缘、纹理)

平均池化Avg Pooling

取局部区域的平均值

作用:反映特征的整体分布情况。

池化核大小Kernel_size

定义池化窗口的大小

步长stride

控制窗口移动的步长(默认等于池化核大小)

填充padding

在输入特征图的边缘补零:

保持输出大小不变(如 padding=1 可以保持尺寸)。

防止边缘信息丢失

激活函数(非线性函数)

(1)sigmoid函数

输出范围(0,1),适用于输出概率。sigmoid函数清晰地解释神经元激活水平:接近1,更高激活;接近0,较低激活。

应用场景:二分类问题

(2)ReLU激活函数

如果输入x是 正数,ReLU 输出 x本身。

如果输入x是 负数,ReLU 输出 0。

作用:

  1. 激活函数的作用是让网络学习非线性的特征
  2. 解决梯度消失问题:Sigmoid 和 Tanh 函数,输入值变的特别大或特别小时,激活函数的梯度接近0.

缺点:

死神经元问题:某些神经元输出 永远是 0 时(也就是当输入总是负数时)。这会导致这些神经元在训练过程中不再被更新

(3)tanh函数

 

 输出范围:(-1,1)

优化算法

ADM算法

AGD随机梯度下降


网站公告

今日签到

点亮在社区的每一天
去签到