从0开始的Pytorch框架与经典卷积神经网络

1 开始之前

1.1 pytorch的安装

可以参考一下该文【超详细教程】2024最新Pytorch安装教程(同时讲解安装CPU和GPU版本)-CSDN博客

2 CNN卷积神经网络算法原理

2.1 全连接神经网络 FCN

全连接神经网络本质上是有由单位到整体的过程,而模型的运行则是输入x输出y的过程,也被称为前向传播,本质为模型的计算过程。

2.1.1 整体结构

整体结构分为三部分,分别为输入层,隐藏层,输出层。

输入层是指输入的数据,而输出层则为输出的数据,中间的所有神经元都属于隐藏层。

                                                                 图1.1

                                                                 图1.2

                                                                

2.1.2 结构单元

结构单元也就是上面提到的神经元,就是图1.2所表示的a11,a12,a13一样的节点。一般为多个输入在此结构单元经过数据处理产生多个输出而多个结构单元经过一定的组合便成为了模型的整体结构。其中逻辑可简化为y=a(X1*W1+X2*W2+X3*W3+...+Xn*Wn+B),如图2.1。由此可知其中发挥重要作用的是参数W1,W2,W3...Wn,B,他们决定了模型的输出是否与预测的接近。

                                                                图2.1

而一层神经元输出结果即同一层内神经元输出结果a=h(w*x+b)形成的矩阵a也是下一层神经元的输入,即\mathbf{a_1}=h(w_1*\mathbf{a}+b_1),所以model的本质就是多个h(w*x+b)嵌套,其目的也转为找到一组最优的b和w使我们最后输出的y接近我们的真实值。也就是说对于a=h(w*x+b),其中的h(x)为激活函数,w,b为最佳参数。

2.1.2.1 激活函数(重中之重)

激活函数大多都是非线性函数,只有少部分是线性函数,在模型中起到特殊的功能。图2.2是对激活函数大多都是非线性函数的解释。

                                                                图2.2  

2.1.2.1.1 Sigmoid函数 

对于我们学习中遇到的函数,主要关注的点有两个:函数曲线与导数曲线,导数曲线用于求出在model已确定的情况下最合适的参数(w,b)。

                                                               图2.1.2.1.1 Sigmoid函数

对Sigmoid函数有其值域为(0,1)且越往两边越平缓的特性,导致其一般用于输出层中用于分类。

2.1.2.1.2 Tanh函数

                                                               图2.1.2.1.2 Tanh函数 

其值域为(-1,1),我们可以发现Tanh函数与Sigmoid函数十分相似,但Tanh函数为奇函数,关于原点呈中心对称

2.1.2.1.3 ReLU函数

                                                               图2.1.2.1.3 ReLU函数 

 ReLU函数在model中使用较多,其本质为分段函数。其特点是计算简单,能有效缓解梯度消失问题。训练时可能出现神经元死亡是因为在小于等于0的情况下, ReLU函数导数为0,导致w与b直接无法更新。

2.1.2.1.4 Leaky ReLU函数

                                                               图2.1.2.1.4 Leaky ReLU函数

Leaky ReLU函数为ReLU函数的改进版,通过设置不同的斜率解决了导数为0的问题。 但因为函数不对称导致无法为输入值提供一致的关系预测。

2.1.3 全连接神经网络前向传播

                                                                图2.1.3.1 前向传播计算过程

                                                                图2.1.3.2 具体计算过程

前向传播是神经网络中数据从输入层经过隐藏层传递到输出层的过程。每一层的神经元接收前一层输出的加权求和结果,通过激活函数处理并输出到下一层,最终得到预测值。本质为模型的计算过程。并且模型的训练,推理,验证,测试都需要前向传播的参与。在机器学习中,label指训练数据中的目标输出值。

2.1.4 损失函数(重点)

图 2.1.4 损失函数

损失函数(Loss Function)用于衡量模型预测值与真实值之间的差异,是机器学习和深度学习中优化模型的核心工具。通过最小化损失函数,模型逐步调整参数以提高预测准确性。

对于model的基本问题我们有三大基本模型,分别是回归,分类,聚类。

其中回归问题多用来预测一个具体的数值,如预测房价、未来的天气情况等等。例如我们根据一个地区的若干年的PM2.5数值变化来估计某一天该地区的PM2.5值大小,预测值与当天实际数值大小越接近,回归分析算法的可信度越高。由此我们可知回归问题的预测值是连续的。当然预测值与真实值的差值可能为负,为解决差值分别为-1,0,+1的损失函数计算为0(-1+0+1=0),我们需要给差值加绝对值或平方,于是得到适合回归问题的损失函数均方误差的损失函数如图2.1.4。对于图2.1.4中的1/2则为对函数导数化的方便计算,对函数本身并无影响。

而分类则是对事物进行分类,所以其预测值也就是离散的,如只有false和true。

2.1.5 反向传播与梯度下降法

2.1.5.1 反向传播

对于前向传播所经历的过程我们可以得到对应每一层的损失函数的结果loss值,那么花那么大力气求得的结果有什么用呢?这就要引出一个与前向传播相应的过程:反向传播。

反向传播(Backpropagation)是一种用于训练神经网络的算法,通过计算损失函数对网络参数的梯度,利用梯度下降法优化参数。核心思想是利用链式法则从输出层向输入层逐层传播误差,调整权重和偏置以减少预测误差。其本质就是根据前向传播的结果反作用于参数w,b的修改使loss值下降,从而使model效果更好。而反作用使loss值下降的方法就是梯度下降法。

2.1.5.2 梯度下降法(重点)

图 2.1.5.1 对w的梯度下降法(对b同理,只需换字符就行)

因为我们有损失函数J(x)=\frac{1}{2m}\sum_{i=1}^{m} (f(x_{i})-y_{i})^{2},由此可反推在已知x,y的情况下w,b的值,即对损失函数求导算出最小值,但我们为什么不这么做呢?因为函数中的x往往为矩阵,通过求导求最小值会极为困难甚至可能无解。所以我们只能用参数更新的方式去逼近。其中a决定了单次梯度下降的倾斜程度,所以a不能太大也不能太小,避免一次就超过或效率过慢。

 图 2.1.5.2 下降梯度法原理图示

图 2.1.5.3 对w,b的下降梯度法三维演示 

2.1.5.2.1 举例计算(不在乎细节可跳)

图 2.1.5.2.1.1 案例

图 2.1.5.2.1.2 计算过程1

注意其中a21=relu(a11*w21+b2)

图 2.1.5.2.1.3 计算过程2 

图 2.1.5.2.1.2 计算过程3

图 2.1.5.2.1.3 第二轮验证 

2.1.6 存在的问题

对于全连接神经网络而言,其相对于CNN卷积神经网络在图像识别的问题在于其会破坏图像信息的空间结构。这是因为全连接层将输入图像的所有像素展开为一维向量,导致像素间的二维空间关系被破坏。例如,一张28x28x1(其中1表明图像为灰度图,RGB则为x3,意为有红黄绿三个维度)的图像会被展平为784维向量,相邻像素的行列位置信息完全丢失。这种扁平化处理忽略了图像的局部特征(如边缘、纹理)在空间上的相关性。但CNN卷积神经网络因卷积核仅连接输入图像的局部区域(如3x3窗口)从而可以保留空间拓扑结构。

2.2 卷积神经网络 CNN

卷积神经网络本质上是运用卷积运算搭建的神经网络。其核心在于利用卷积运算提取局部特征,并通过层级结构实现高效的特征学习和模式识别。

2.2.1 卷积层--卷积运算

卷积层通过滑动窗口(卷积核)在输入数据上执行局部加权求和,自动学习空间或时间上的局部模式。这种操作具有参数共享和稀疏连接的特性,显著减少了模型的参数量,同时保留了数据的平移不变性。

图2.2.1.1 卷积运算演示 

在卷积运算中卷积核其实就相当于全连接神经网络中的w,但不同的是卷积核的大小(即权重)不会因输入数据的多少而发生变化(如图2.2.1.1中核的大小为2x2),全连接神经网络中的w个数与输入数据正相关。同时卷积神经网络中的偏置也可看作成b,即卷积神经网络可写成y=h(x\times w+b)

图 2.2.1.2 卷积运算详细过程 

那么如何进行卷积运算呢?由图 2.2.1.2我们不难发现卷积运算分为以下5步:

输入准备
卷积运算需要一个输入矩阵(如图像)和一个卷积核(或滤波器)。输入矩阵通常是一个二维数组,卷积核是一个更小的二维数组,其大小由设计者决定(如3x3、5x5等)。

滑动窗口操作
将卷积核从输入矩阵的左上角开始,每次滑动一个步长(stride),覆盖输入矩阵的一个局部区域。在每个位置上,卷积核与输入矩阵的对应元素进行逐元素相乘。如图2.2.1.2中顺序为左上右上左下右下。

逐元素相乘并求和
对于每个覆盖的局部区域,计算卷积核与输入矩阵对应元素的乘积,并将所有乘积结果相加,得到一个输出值。这个输出值成为输出矩阵(特征图)的一个元素。如图2.2.1.2中左上为0x0+1x1+3x2+4x3=19.

填充与步长的影响
填充(padding)可以在输入矩阵周围添加额外的行和列(通常用0填充),以控制输出矩阵的大小。步长(stride)决定了卷积核每次滑动的距离,较大的步长会减少输出矩阵的尺寸。如图2.2.1.1中19+偏置的值2=21及结果。

输出特征图生成
重复上述滑动和计算过程,直到卷积核覆盖整个输入矩阵,最终生成完整的输出特征图。

2.2.1.1 卷积层--步幅

图2.2.1.1.1 步幅S=2时卷积运算过程 

卷积层的步幅(Stride)指卷积核在输入数据上滑动时的步长。步幅决定了卷积核每次移动的像素数量,直接影响输出特征图的尺寸。如图 2.2.1.2与图2.2.1.1.1对比可发现步幅S大时输出尺寸会相应减小。

2.2.1.2 卷积层--填充

填充(Padding)是在输入特征图周围添加额外像素(通常为0),以控制输出特征图的尺寸。主要作用包括:

  • 保持空间维度:避免卷积操作导致特征图尺寸过快缩小,尤其在深层网络中。

因为图片在经过卷积操作后尺寸会变小,为了

  • 利用边缘信息:防止输入边缘区域的信息因卷积核中心对齐而丢失。
2.2.1.3 卷积层--经过计算后的特征图大小(重要)

 图2.2.1.3 特征图大小的计算公式(p为填充,S为步幅)

若计算结果为小数,一般向下取整,但也有向上取整的模型框架。

2.2.1.4 卷积层--多通道数据卷积运算

图2.2.1.4.1  多通道数据单卷积核卷积运算过程

图2.2.1.4.2 多通道数据多卷积核卷积运算过程

如图2.2.1.4所示根据2.2.1.3的计算公式有OH=\frac{H-2P-FH}{S}+1=\frac{3+2\times 0-1}{1}+1=2,所以输出的特征图的大小为2x2x1.至于深度为何为1是因为该运算的卷积核是深度为三的单个卷积核,所以我们可看出输出的特征图深度不由输入数据与卷积核的深度(通道数)决定,而是由卷积核的数量决定。如图2.2.1.4.2所示。在卷积神经网络(CNN)中,卷积核的数目与偏置(bias)的通道数相等,这是因为每个卷积核对应一个独立的偏置项。

2.2.2 池化层

池化层(Pooling Layer)是卷积神经网络(CNN)中的一种重要组件(实际上不算是一个神经网络层,因为它不带有参数,其本质是一种下采样操作),主要用于降低特征图的空间维度(宽度和高度)不改变深度,减少计算量并增强模型的平移不变性。通过聚合局部区域的信息,池化层能够保留主要特征,同时减少过拟合风险。

2.2.2.1 最大池化

图2.2.2.1 最大池化过程 

顾名思义,就是取局部区域的最大值,保留最显著特征。通常在滑动窗口内操作,窗口大小(如 2×2)和步长(如 2)是常见参数。
2.2.2.2 平均池化

图2.2.2.2.1 平均池化过程

其本质也就是输入特征图的局部区域取平均值来降低其空间维度。

平均池化与最大池化的对比

  • 最大池化:保留局部最显著特征,适合纹理、边缘等高频信息。
  • 平均池化:保留整体分布特性,适合平滑区域或背景主导的任务。
2 2.2.3 池化输出大小计算

图2.2.2.3 池化输出大小计算公式(其中FH,FW为自己设定的窗口大小和步长) 

2.2.3 卷积神经网络整体结构

卷积神经网络(CNN)通常由输入层、卷积层、池化层、全连接层和输出层组成。输入层接收原始数据(如图像),卷积层提取局部特征,池化层降低空间维度,全连接层整合特征,输出层生成预测结果。

其中卷积层的功能为输出特征图,且特征图的通道数由卷积核的个数决定。而卷积层的各个卷积核都分别对不同部分做提取,所以到最后一层池化层时输出的数据已是被提取的数据,与原始输入无关,此时便不用担心全连接对数据的空间结构的破坏。输出层的结构取决于任务类型。

3.LeNet与AlexNet原理与实战

对于我们神经网络模型的搭建一般是先搭建模型(model.py),再搭建训练代码即送入并处理数据(train.py),之后再搭建测试代码即test.py。其中train.py与test.py大多相近,可重复套用模板。

3.1 LeNet

LeNet(LeNet-5)是由 Yann LeCun 等人在 1998 年提出的经典卷积神经网络(CNN)架构,主要用于手写数字识别(MNIST 数据集)。它是现代深度卷积神经网络的先驱,奠定了 CNN 的基础设计模式。

3.1.1 LeNet-5 网络结构

图3.1.1 LeNet网络结构 

LeNet-5 由 7 层组成,包括卷积层、池化层和全连接层:

  • 输入层:32×32 的灰度图像(MNIST 图像被填充到这一尺寸)。
  • 卷积层 C1:6 个 5×5 的卷积核,输出 6 个 28×28 的特征图。
  • 池化层 S2:2×2 的平均池化,输出 6 个 14×14 的特征图。
  • 卷积层 C3:16 个 5×5 的卷积核,输出 16 个 10×10 的特征图。
  • 池化层 S4:2×2 的平均池化,输出 16 个 5×5 的特征图。
  • 全连接层 C5:120 个神经元,与 S4 层全连接。
  • 全连接层 F6:84 个神经元。
  • 输出层:10 个神经元(对应 0-9 的数字类别),使用 Softmax 激活函数。

其中因为池化层无参数并不算是神经网络层,所以该模型的神经网络层为5层(-5的由来)。同时LeNet也可视为由两部分组成:由两个卷积层和两个平均池化层组成的特征提取主干,由三个全连接层组成的任务层(如分类)。

3.1.2 LeNet-5网络参数详解

图3.1.2.1 LeNet-5网络结构参数

图3.1.2.2 LeNet-5网络参数细节

注意OH=\frac{H-2P-FH}{S}+1就可以一层层向下推,由此可以得到卷积是用来增多特征的,池化是用来修改特征表现的,如平滑或者突出。

3.1.3 LeNet-5总结

图3.1.3 LeNet-5总结

import torch.nn as nn

class LeNet5(nn.Module):
    def __init__(self):
        super(LeNet5, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.pool1 = nn.AvgPool2d(2, stride=2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.pool2 = nn.AvgPool2d(2, stride=2)
        self.fc1 = nn.Linear(16*5*5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool1(torch.tanh(self.conv1(x)))
        x = self.pool2(torch.tanh(self.conv2(x)))
        x = x.view(-1, 16*5*5)
        x = torch.tanh(self.fc1(x))
        x = torch.tanh(self.fc2(x))
        x = self.fc3(x)
        return x
 

3.2 AlexNet

AlexNet 是由 Alex Krizhevsky、Ilya Sutskever 和 Geoffrey Hinton 在 2012 年提出的深度卷积神经网络(CNN),在 ImageNet 竞赛中以显著优势获胜,推动了深度学习在计算机视觉领域的广泛应用。其核心创新包括 ReLU 激活函数、Dropout 正则化和 GPU 并行训练。

3.2.1 AlexNet网络结构

图3.2.1 AlexNet网络结构

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值