卷积神经网络基础知识

1. 卷积神经网络(CNN )的发展史

在这里插入图片描述

  • 1986年,Runmelheart 和 Hinton 等人提出了反向传播算法(Back Propagation, BP)
  • 1998 年,LeCun 利用BP 算法训练 LeNet5 网络,标志着 CNN 的真正面世(但此时的硬件水平很难去训练网络)
  • 2006年,Hinton在他们的Science Paper中首次提出了Deep Learning的概念
  • 2012年,Hinton的学生Alex Krizhevsky在寝室用GPU死磕了一个Deep Learning模型,一举摘下了视觉领域竞赛ILSVRC 2012的桂冠,在百万量级的ImageNet数据集合上,效果大幅度超过传统方法(70%多 -> 80%多)

2. 全连接层(Fully Connected Layer,FC)

全连接层的英文是 Fully Connected Layer,也称为密集连接层(Dense Layer)。它一般位于整个卷积神经网络的最后,负责将卷积输出的二维特征图转化成一维的一个向量,由此实现了端到端的学习过程(即:输入一张图像或一段语音,输出一个向量或信息)。它可以将输入特征与每个神经元之间的连接权重进行矩阵乘法和偏置加法操作,从而得到输出结果。全连接层的作用是将输入特征映射到输出结果,通常在神经网络的最后一层使用,用于分类、回归等任务。

在这里插入图片描述
说的简单直白一些,FC其实就是一个线性投影的操作在FC后面一个非线性激活函数,那么可以使其拥有一定的非线性表达能力

3. Back Propagation(BP)

BP算法包括①信号的前向传播②误差的反向传播两个过程。即

  • 计算误差输出时按“输入->输出”的方向进行
  • 调整权值和阈值时则按“输出->输入”的方向进行

在这里插入图片描述
理论上,三层的BP神经网络可以实现多维单位立方体 R m 到 R n \mathcal{R}^m 到 \mathcal{R}^n RmRn 的映射,即能够逼近任何有理函数

4. CNN中独特的层结构——卷积层 (Convolution Layer)

卷积层(Convolutional Layer)是卷积神经网络中最重要的部分之一。它由若干个卷积单元组成,每个卷积单元的参数都是通过反向传播算法最佳化得到的。在卷积层中,每个神经元仅与前一层神经元中一个小矩形区域内的神经元相连。若第一层为图像,则只与一个小矩形区域内的像素相连。卷积层可以产生一组平行的特征图(feature map),它通过在输入图像上滑动不同的卷积核并执行一定的运算而组成。

在这里插入图片描述

4. 1卷积的本质

卷积其实就是一个可以滑动的窗口在特征图上滑动并计算得到新特征图的操作。

4.2 卷积的目的

进行图像的特征提取

4.3 卷积的特性

  1. 局部感知机制
  2. 权值共享

4.3.1 局部感知机制

因为滑动窗口的大小是由卷积核大小决定的,一般使用的卷积核大小为 1 × 1 1×1 1×1, 3 × 3 3×3 3×3 5 × 5 5×5 5×5,…。所以一般比特征图要小,所以每次的计算只能计算窗口大小的值,即感知的大小只有滑动窗口那么大

4.3.2 权值共享

我们知道,卷积核里面的是有值的,里面的值就确定了滑动窗口该如何进行计算。训练网络的目的主要是为了更新、优化卷积核里面的值。由于卷积具有局部感知的机制,所以需要多次滑动窗口才能浏览完整张特征图,而权值共享就意味着,并不是说每滑动一次窗口,卷积核里面的值要变一下,而是卷积核里面的值是固定的,3×3的卷积核里面就9个数,在卷积过程中不会变,只有反向传播时参数优化才会变

4.4 权值共享的好处

在这里插入图片描述

普通的BP神经网络

对于一张分辨率 1280×720 的图片,假设隐藏层1(hidden layer 1)的神经元个数为1000,那么图片经过第一个隐藏层后的参数数量为:
P a r a m s = 1280 × 720 × 1000 = 921 , 600 , 000 \begin{aligned} \mathrm{Params} & = 1280 \times 720 \times 1000 \\ & = 921,600,000 \end{aligned} Params=1280×720×1000=921,600,000

这个参数量是巨大的(这也就是为什么现在的分类网络基本上不再使用FC作为分类头了)。而对于卷积神经网络来说,假设 layer1 采用1000个5×5的卷积核,那么图片经过它后的参数数量为:
P a r a m s = 5 × 5 × 1000 = 25 , 000 \begin{aligned} \mathrm{Params} & = 5 \times 5 \times 1000 \\ & = 25,000 \end{aligned} Params=5×5×1000=25,000

可以看到,参数量大大减少。

卷积核大小是5×5,我们前面说过,卷积具有两个特性,而第二个特性就是权重共享,意思就是说,对于 1280×720 的图片而言,我们不需要考虑卷积核要在图片上移动多少次,因为每次移动都不会改变卷积核的参数,卷积核的参数是共享的。

4.5 多通道卷积的使用


在这里插入图片描述

3通道输入的卷积示例

输入特征矩阵为 3 通道,为了保证可以计算,卷积核的维度应该也是3维。和特征图一样,卷积核也是一个多维 tensor。而卷积核的数量决定了输出特征图的通道数。这就解释了为什么在代码中,我们只需要指定输入通道数和输出通道数即可(卷积核的 channel 不需要我们指定):

torch.nn.modules.conv.Conv2d 
        def __init__(self,
             in_channels: int,  # 输入通道数,即卷积核的通道数
             out_channels: int,  # 输出通道数,即卷积核的个数
             kernel_size: int | tuple[int, int],  # 卷积核的大小
             stride: int | tuple[int, int] = 1,  # 卷积核的步长
             padding: str | int | tuple[int, int] = 0,  # 卷积核的填充大小
             dilation: int | tuple[int, int] = 1,  # 空洞卷积的空洞率大小
             groups: int = 1,  # 卷积时分组的个数
             bias: bool = True,  # 是否存在偏置
             padding_mode: str = 'zeros',  # 填充时使用的模式
             device: Any = None,  # 负责进行此操作的设备(CPU、GPU、DP、DDP)
             dtype: Any = None) -> None  # 数据类型
  1. in_channels: 输入通道数,即输入特征图的的通道数 -> 目的是给卷积核分配对应的维度 。
    假设输入为(channel, height, width) = (32, 28, 28),那么卷积核会根据in_channels参数来指定卷积核,即卷积核为(channel, height, width) = (32, kernel_size[0], kernel_size[1])
  2. out_channels:输出通道数,即输出特征图的通道数 -> 目的是告诉卷积核分配几个卷积核去进行运算,因为一个卷积核只能生成一个单通道feature,最后进行维度的拼接,得到out_channels维度大小的输出特征图
  3. kernel_size:卷积核滑动窗口的大小。

小结

  1. 卷积核的 channel 与输入特征图的 channel 要相同(写代码时不用考虑)
  2. 输出特征图的维度与卷积核的个数相同(out_channels 即为卷积核的个数,也是输出特征图的通道数)

4.6 加了bias的卷积运算

非常简单,就是输入特征图直接加上bias就可以了。

在这里插入图片描述

4.7 加了激活函数的卷积运算

4.7.1 前置知识——常用的非线性激活函数

Q1: 为什要引入非线性激活函数?
A1: 神经网络引入非线性激活函数的目的是为了增强网络的表达能力。

如果没有非线性激活函数,无论神经网络有多少层,其输出都可以被表示为输入的线性组合。这意味着,不含非线性激活函数的多层神经网络等效于一个单层神经网络。这样的网络无法解决复杂的非线性问题

非线性激活函数能够引入非线性因素,使得神经网络能够学习并近似任意复杂度的函数。这大大增强了神经网络的表达能力,使其能够解决复杂的非线性问题。


Q2:在神经网络中,什么层是线性操作?
A2:在神经网络中,全连接层(Fully Connected Layer)和卷积层(Convolutional Layer)都是线性操作。这些层中的神经元对输入进行加权求和,然后加上一个偏置项。这个过程是线性的。

然而,通常在这些层之后会接一个非线性激活函数,将线性输出转换为非线性输出。这样,整个网络就能够学习并近似复杂的非线性函数。


Q3:在神经网络中,什么层是非线性操作?
A3:在神经网络中,激活函数层(Activation Layer)是非线性操作。激活函数层通常位于全连接层或卷积层之后,它对前一层的线性输出应用一个非线性函数,将线性输出转换为非线性输出。

常用的非线性激活函数包括 Sigmoid 函数、双曲正切函数(Tanh)、整流线性单元(ReLU)和 Softmax 函数等。这些函数能够引入非线性因素,使得神经网络能够学习并近似任意复杂度的函数。


Q4:池化层是线性操作还是非线性操作?
A4:池化层(Pooling Layer)是一种非线性操作。池化层通常位于卷积层之后,它对输入特征图进行下采样,减少特征图的尺寸。常用的池化操作包括最大值池化(Max Pooling)和平均值池化(Average Pooling)。
最大值池化是一种非线性操作,它在每个池化窗口内取最大值作为输出。平均值池化也是一种非线性操作,它在每个池化窗口内取平均值作为输出。
池化层能够减少特征图的尺寸,降低计算复杂度,同时也能够增强特征的平移不变性。

4.7.2 常用的激活函数

4.7.2.1 Sigmoid

Sigmoid激活函数饱和(值接近1或-1)时梯度值非常小,故网络层数较深时易出现梯度消失的问题。

4.7.2.2 ReLU

缺点在于当反向传播过程中有一个非常大的梯度经过时,反向传播更新后可能导致权重分布中心小于零,导致该处的倒数始终为0,反向传播无法更新权重,即进行失活状态

在这里插入图片描述

从上图可以看到,对于Sigmoid激活函数来说,当函数值很大/小时,导数就趋近于0了 -> 可能导致梯度消失的问题

4.8 卷积核越界处理

在这里插入图片描述

在卷积操作过程中,矩阵经卷积操作后的尺寸由以下几个因数决定:

  1. 输入视频大小 W × W W×W W×W
  2. 卷积核大小 F × F F×F F×F
  3. 步长 S S S
  4. padding的像素数 P P P

经卷积后的矩阵尺寸大小计算公式为:
N = ( W − F + 2 P ) S + 1 N = \frac{(W - F + 2P)}{S + 1} N=S+1(WF+2P)


当卷积核越界时,通常有两种处理方法:填充(Padding)和舍弃(Valid Convolution)。

  1. 填充(Padding):在输入特征图的边界周围填充一定数量的零,使得卷积核能够在边界处进行卷积运算。这样做可以保持输出特征图的尺寸不变。

  2. 舍弃(Valid Convolution):只在卷积核完全位于输入特征图内部时进行卷积运算,舍弃边界处的卷积结果。这样做会导致输出特征图的尺寸减小。

这两种方法各有优缺点,具体使用哪种方法取决于具体任务的需求。

5. 池化层(Pooling)

目的:对特征图进行稀疏处理,减少数据运算量。

特点

  1. 没有训练参数
  2. 没有卷积核,所以没有可以学习的参数——本质上就是一个非线性运算
  3. 只改变特征矩阵的 w 和 h ,不改变channel
  4. 没有卷积核,也就谈不上改变channel了(卷积核个数 = 输出的channel),但是有pool kernel,可以改变特征图的尺寸
  5. 一般pool sizestride相同

Q:什么是池化核(Pool Kernel)?
A:池化核(Pool Kernel)是池化层中用于对输入特征图进行下采样的滑动窗口。池化核的大小决定了池化操作的范围,步长(Stride)决定了池化核在特征图上滑动的距离。

常用的池化操作包括最大值池化(Max Pooling)和平均值池化(Average Pooling)。最大值池化在每个池化窗口内取最大值作为输出,而平均值池化在每个池化窗口内取平均值作为输出。

5.1 MaxPooling

在这里插入图片描述

5.2 Average Pooling

在这里插入图片描述

6. Loss的计算

在这里插入图片描述

3层的BP神经网络计算流程图
  • 第一层:输入层
  • 中间层:隐藏层
  • 第三层:输出层

    在这里插入图片描述
隐藏层第一个节点的计算

在这里插入图片描述

输出的计算

6.1 Softmax激活函数的计算过程

性质:经过sofmax处理后所有输出节点概率之和为1

公式

o i = e y i ∑ j e y i o_i = \frac{e^{y_i}}{\sum_je^{y_i}} oi=jeyieyi

在这里插入图片描述

经过BP神经网络输出的 y 1 , y 2 y_1, y_2 y1,y2 其实并不符合概率的分布,而一般情况下我们想要得到的是一个概率的输出,所以我们使用Softmax激活函数对其进行处理得到概率分布。

6.2 Cross Entropy Loss,交叉熵损失函数

6.2.1 针对多分类问题(softmax输出,所有输出概率之和为1)

H = − ∑ i o i ∗ ln ⁡ o i H = - \sum_io_i^*\ln o_i H=ioilnoi

6.2.2 针对二分类问题(sigmoid输出,每个输出节点之间互不相干)

H = − 1 N ∑ i = 1 N [ o i ∗ ln ⁡ o i + ( 1 − o i ∗ ) ln ⁡ ( 1 − o i ) ] H = -\frac{1}{N}\sum^{N}_{i=1}[o^*_i\ln o_i + (1-o^*_i)\ln (1-o_i)] H=N1i=1N[oilnoi+(1oi)ln(1oi)]

其中 o i ∗ o_i^* oi 为真实标签值(GT), o i o_i oi 为预测值,默认 log ⁡ \log log e e e为底等于 ln ⁡ \ln ln

  • Softmax 函数能够将一组实数映射为概率分布,使得所有输出值之和为1。因此,当神经网络需要输出概率分布时,通常会采用 Softmax 函数。
  • Sigmoid 函数能够将实数映射到0和1之间,但是多个 Sigmoid 输出值之和并不一定为1。因此,当神经网络需要输出概率分布时,不适合采用 Sigmoid 函数。

Q1:Sigmoid一般用于二分类?
A1:是的,Sigmoid 函数常用于二分类问题。在二分类问题中,神经网络的输出层只有一个神经元,其输出值表示样本属于正类的概率。Sigmoid 函数能够将实数映射到0和1之间,因此适合用作二分类问题的输出层激活函数。

当然,Sigmoid 函数也可以用于多标签分类问题,其中每个标签都是独立的二分类问题。在这种情况下,输出层有多个神经元,每个神经元都使用 Sigmoid 函数作为激活函数。


Q2:Sigmoid函数用于二分类时,得到的两个结果的和是1吗?
A2:在二分类问题中,神经网络的输出层通常只有一个神经元,其输出值表示样本属于正类的概率。Sigmoid 函数能够将实数映射到0和1之间,因此适合用作二分类问题的输出层激活函数。

在这种情况下,样本属于负类的概率可以通过 1 减去正类概率来计算。因此,正类概率和负类概率之和为1。

例如,假设神经网络的输出值为0.7,则表示样本属于正类的概率为0.7,属于负类的概率为1-0.7=0.3。两个概率之和为1。


根据公式我们可以得到Loss使用交叉熵的计算公式。

在这里插入图片描述

7. Loss的反向传播

在得到Loss后我们需要对Loss进行反向传播。

在这里插入图片描述

正向传播的计算函数我们已经知道了,根据这个函数我们进行链式求导就可以得到梯度的计算公式。

先对 y 1 y1 y1求导再对 w 11 w_{11} w11求导

接下来对表达式中的每一个偏导进行计算:

在这里插入图片描述

在这里插入图片描述

这样我们就可以得到每一个节点的损失梯度。接下来我们需要根据梯度进行权值的更新。

8. 权值更新

在这里插入图片描述

更新权重的表达式非常简单,但是我们无法确定所求的梯度方向是不是减少损失最快的方向

在这里插入图片描述

在实际训练中,我们往往是设置batch进行训练的,每一个批次训练完毕后会计算该批次的Loss以及梯度,虽然有梯度,但这个梯度是对于这一个批次来说是最优的,对于整个数据而言就不一定的。所以为了更好的在batch训练中进行梯度更新,引入了优化器(optimizer)的概念

9. 优化器(optimizer)


在这里插入图片描述

一般常用的优化器有:

  • SGD
  • SGD + Momentum
  • Adagrad
  • RMSProp
  • Adam

使用优化器的目的是为了使网络更快的收敛

9.1 SGD(Stochastic Gradient Descent)

在这里插入图片描述

SGD的缺点

  • 易受样本噪声影响
  • 有些标签是错误的,SGD会受到较大的影响
  • 可能陷入局部最优解

9.2 SGD+Momentum

在这里插入图片描述

除了计算当前batch的梯度外还会加入之前batch的梯度。

g ( t + 1 ) g_{(t+1)} g(t+1) 为本次batch的梯度, g ( t ) g_{(t)} g(t)为上一个batch的梯度, g ( t + 1 ) ∗ g^*_{(t+1)} g(t+1) 为本次batch实际更新的梯度。

加了动量可以有效抑制样本噪声的干扰。

9.3 Adagrad(自适应学习率)

该优化器是对学习率进行改进的。

在这里插入图片描述

随着batch的进行,最终 α s t + ϵ \frac{\alpha}{\sqrt{s_t + \epsilon}} st+ϵ α 会越来越小 -> 代表着更新的力度越来越小,看起来就像更新时用到的学习率逐渐变小了

Adagrad缺点

  • 学习率下降太快,可能还没有收敛就停止训练了。

9.4 RMSProp(自适应学习率)

也是对学习率进行调整,是Adagrad优化器的改进版本。相比于Adagrad优化器,RMSProp其实就是添加了两个系数去控制学习率的衰减力度。

在这里插入图片描述

9.5 Adam(自适应学习率)

在这里插入图片描述

9.6 几种优化器效果对比

9.6.1 速度比较

在这里插入图片描述

9.6.2 在鞍点的性能比较

在这里插入图片描述

9.7 优化器总结

  • SGD虽然速度慢,但梯度更新的方向是比较理想的。
  • 带有Momentum的SGD开始时不好,但很快找回了正确的路径
  • Adagrad和RMSProp不仅方向保持是正确的,而且速度也很快

这里没有展示Adam优化器的效果

9.8 优化器推荐

在实际项目中,比较常用的有:

  • 带有Momentum的SGD
  • Adam

可能有很多人选择使用Adam优化器,因为它的效果比较好,但是在论文中,很多作者仍然使用的是带有momentum的SGD优化器

如何选择还是要看实际情况 😂

参考

  1. 1.1 卷积神经网络基础
  2. Convolution arithmetic
  3. 优化函数和损失函数的区别与联系
  • 11
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值