卷积神经网络简介
本文最后更新于 2024年5月16日 上午
卷积神经网络简介
针对用于图像识别的卷积神经网络而言
卷积神经网络的识别
卷积神经网络的结构分为输入层,隐含层和输出层。其中隐含层包括了卷积层(矩阵通过卷积层后还需要经过激活函数处理),池化层和全连接层。图像依次通过这三个层,然后通过softmax函数输出最终的概率。
输入层
彩色图像在输入层被分离为RGB三通道的三个大矩阵。
隐含层
卷积层
卷积的实质是图滤波,通过卷积核参数的设定为图像的像素赋予权重,达到增强并削弱图像中特定像素点的效果。卷积层的作用是通过预设好的卷积核对三通道矩阵进行照射,起到提取图像特征的作用。
卷积层的参数
卷积层的参数为:卷积核大小,步长,填充,三者称为卷积层的超参数,共同决定卷积层输出图像的尺寸。
卷积核大小
卷积核的大小通常是奇数,主要原因是根据卷积公式,最终得到的图像长宽均与卷积核的基数倍有关,如果设置卷积核大小为偶数维度则最终得到的图像长宽可能不是一个整数。此外还有便于强调中心,奇数卷积核对边沿、对线条更加敏感,可以更有效的提取边沿信息等优点。步长(Step)
指一次照射结束后,卷积核移动的像素单位数,通常以\(\alpha\)表示。 步长过大可能导致图像的某些位置未被处理,步长过小则被重叠滤波的像素面积增多。填充(Padding)
由于卷积过程是一个降维过程(直观来看图像会被缩小),有时为了保证卷积输出的图像不被降维,需要在图像外围添加像素值为0的像素点,填充反映了像素点添加的多少。 填充的方式有非常多种。
激活函数
激活函数为卷积神经网络建立了非线形的建模能力,使得神经网络能够表达非线性映射关系,能够非线形分类。 图像通过卷积层后,需要通过激活函数对这一层的结果进行非线性化,使得模型具有复杂的建模能力。
常见的激活函数
Sigmoid 函数
\[f(x)=\frac{1}{1+e^{-x}}\] Sigmoid函数是最简单的非线形二分类函数,能够把连续实数进行放缩,使得函数输出值在0-1的范围内。 缺点是当输入非常大或者非常小的时候梯度容易消失。ReLU 函数
\[f(x)=max(0,x)\] 输入信号<0时,输出都是0,输入>0 的情况下,输出等于输入。 好处是过滤了负值像素的同时提供了一种极其简便的计算方式,使得计算量小,收敛速度比较快。 并且由于其一阶导是一个常数,因此不容易发生梯度消失。
缺点是如果一个非常大的梯度通过一个 ReLU 神经元,更新过参数之后,这个神经元再也不会对任何数据有激活现象了,这个神经元的梯度永远都是0。 尤其是学习率设置的比较大的时候,可能网络中的大部分神经元都会出现这类问题。
池化层
池化层的作用是通过对卷积图的降维过程进一步加强提取到的特征,具体的实现方式是通过预设的卷积核照射卷积图,得到能够表征整个照射区域的数值(比如最大值,均值,中值),这些数值组成新的矩阵。 常见的池化方法是最大值池化(用照射区域的最大值表征整个照射区域)和均值池化(用照射区域的均值表征整个照射区域)。
全连接层
全连接层的作用是把隐含层的输出结果向量化以减小分类函数的计算量,具体而言全连接层的作用就是首先按顺序把最后一个隐含层的所有神经元输出的特征图按顺序展开并拼接为一个特征向量。 这个特征向量会被投入到激活函数当中,最终输出为一个位置表示tag,值表示评分的标签向量。 最终这个标签向量被投入到softmax函数中,求出目标属于每一类的概率,并返回最大的概率值和类别。
softmax 函数
\[p(y|x)=\frac{e^{X_i}}{\sum_{i=1} e^{X_i}}\] 通过softmax函数的归一化作用,将输出映射成为(0,1)的值,而这些值的累和为1,满足概率的性质。最后选取输出时,选取概率最大的结果,输出为预测目标。softmax函数使用指数作为表达的原因是一是归一化操作满足概率性质,二是可以将负值输出正值化。
神经网络的训练
前向传播
对于一组数据和其标签\((x,y)\),去掉标签后投入到神经网络中,得到每一个神经单元的输出和最终的预测结果\((x,a)\)的过程叫做前向传播。
反向传播
执行反向传播的目的是为了求出每一个神经单元的误差\(\delta=y-a\)进而求出\(\frac{\partial J}{\partial \Theta}\) 的值,以此来带入到梯度下降算法当中求得梯度并更新参数。
从池化层的误差推导卷积层的误差
以最大值池化为例,对于池化前特征图中每一个被池化卷积核照射到的区域,由于只有最大值所处的位置才会有误差,其余区域由于最大池化过滤而不会对误差有任何影响,因此原特征图被照射区域中只有最大值对应的位置(需要在前向传播时记录下来)有误差\(\delta\),其余位置的误差为0.
对均值池化,原特征图被照射区域的所有位置上对误差均等的贡献造成了整体误差\(\delta\),因此每个位置上的误差都是\(\frac{\delta}{N}\).
通用的解决办法为:
当第\(l\)层为卷积层,第\(l+1\)层为池化层时,第\(l\)层某一个像素(神经元)的误差为第\(l+1\)层与其相关的所有像素(神经元)的误差与权重的乘积之和。由于激活函数的影响,当前层激活之前的特征图矩阵\(X\)每一个位置通过激活函数的导数处理,再将处理后的矩阵与第\(l+1\)层的神经元误差矩阵对应位置相乘。此处神经元误差矩阵需要做上采样处理以统一维度进行运算,该过程表示为:
\[\delta_j^l=w_j^{l+1}(f’(x_j^l) \odot
up(\delta_j^{l+1}))\]
\(w_j^{l+1}\):\(l+1\)层第\(j\)神经元的权重,\(up\):上采样,\(\odot\):对应位置相乘。
记激活函数\(f(x)=z\),矩阵化后有第\(l\)层的误差向量\(\delta^l\):
\[\delta^l=w_j^{l+1}( z’^{l} \odot up(\delta^{l+1}))\]
卷积层的反向传播
从卷积层推导池化层,\(l\)层的误差\(δ^{l-1}\),等于卷积后结果的\(δ^{l}\)误差经过零填充后,与卷积核旋转180度后的卷积。如图所示:
\[\delta^{l-1} = (\frac{\partial
z^{l}}{\partial z^{l-1}})^T\delta^{l} = \delta^{l}*rot180(W^{l})
\odot \sigma^{'}(z^{l-1})\]
已知\(δ^{l-1}\),求损失函数\(C\)对该层参数的导数\(\frac{∂C}{∂w^l}\):
\[\frac{∂C}{∂w^l}=δ^l*σ(z^{l-1})\]
卷积神经网络的训练过程
- 对神经网络进行初始化,定义好网络结构,设定好激活函数,对卷积层的卷积核\(W\)、偏置\(b\)进行随机初试化,对全连接层的权重矩阵\(W\)和偏置\(b\)进行随机初始化。
设置好训练的最大迭代次数,每个训练batch的大小,学习率\(η\)。
- 从训练数据中取出一个batch的数据
- 从该batch数据中取出一个数据,包括输入\(x\)以及对应的正确标签\(y\)
- 将\(x\)放入CNN的输入端利用前向传播得到\(z^l\),\(a^l\)
- 结合\(z^l\),\(a^l\)和\(y\),算出神经网络的损失函数
- 计算损失函数对输出层的误差\(δ^L\)
- 利用反向传播,计算前一层的误差\(δ^l-1\):
- 全连接层:\(δ^l=(W^{l+1})^Tδ^{l+1}⊙ \sigma^{'}(z^{l})\)
- 卷积层:\(\delta^{l-1} = (\frac{\partial
z^{l}}{\partial z^{l-1}})^T\delta^{l} = \delta^{l}*rot180(W^{l})
\odot \sigma^{'}(z^{l-1})\)
- 池化层:\(\delta^l=w_j^{l+1}( z’^{l}
\odot up(\delta^{l+1}))\)
- 利用误差求出损失函数对该层参数的导数:
- 全连接层:\(\frac{∂C}{∂W^l}=δ^l(a^{l-1})^T\)
- 卷积层:\(\frac{∂C}{∂w^l}=δ^l*σ(z^{l-1})\)
- 全连接层:\(\frac{∂C}{∂W^l}=δ^l(a^{l-1})^T\)
- 将求得的导数加到该batch数据求得的导数之和上(初始化为0),跳转到步骤3,直到该batch数据都训练完毕
- 利用一个batch数据求得的导数之和,根据梯度下降法对参数进行更新
- 跳转到步骤2,直到达到指定的迭代次数