一、卷积神经网络(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%多)
学习视频来自b站up:
霹雳吧啦Wz的个人空间_哔哩哔哩_bilibili
二、全连接层
全连接层就是由许许多多的神经元共同连接得来的
- x1,x2,x3是这个神经元的三个激励,w1,w2,w3是这三个激励对应的权重
- -1是这个神经元的偏置
1. Back Propagation(BP)
BP算法包括信号的前向传播和误差的反向传播两个过程。即计算误差输出时按“输入→输出”的方向进行,而调整权值和阈值时则按“输出→输入”的方向进行。
实例:利用BP神经网络做车牌数字识别
1、首先读入一张彩色的RGB图像,每一个像素里面都包含3个值(RGB分量)
- 首先将它进行灰度化(得到中间的图),每个像素值就只剩下一个分量了
- 再进行二值化处理,得到一个黑白图像
2、用一个5行3列的滑动窗口在二值化后的黑白图像上进行滑动,每滑动到一个地方就计算这个滑动窗口中白色的像素占整个滑动窗口所覆盖的像素比例
- 当滑动窗口滑动到到最右边的时候,此时列数不够了,可以进行补零处理,也可以进行一个判断,当滑动窗口快越界的时候就暂时把它变成一个5行2列的滑动窗口
- 通过这个方法遍历整个图像就得到一个5*5的矩阵
3、将所得到的5*5的矩阵按行进行展开,并将其拼接成一个行向量(1行25列),这样就可以把这个行向量当成输入神经网络的输入层
4、输入层有了之后,再看输出层。one-hot编码是常用的对标签进行编码的方式
- 上图展示了0-9每个数字对应的one-hot编码,没有重复
5、有了输入和输出之后,就可以对神经网络进行训练了。在实际训练过程中,可以将输入层的输入节点数设为25,将输出层的输出节点数设为10,中间的隐藏层按实际情况进行设置
二、卷积层
卷积层是卷积神经网路中独特的网络结构
卷积:一个滑动窗口在特征图上进行滑动,并计算(将卷积核上的值与特征图上的值对应相乘,再进行相加,就得到最后矩阵中的一个值,每滑动一步计算一个值,最终得到卷积结果)
卷积的计算方式:如上图左侧橘色框
(1*1)+(0*0)+(0*1)+(1*0)+(1*1)+(0*0)+(1*1)+(1*0)+(1*1) = 4
卷积的目的就是为了进行图像的特征提取
卷积的特性
- 拥有局部感知机制:以滑动窗口的形式在特征图上进行滑动计算,所以具有局部感知能力
- 权值共享:滑动过程中,卷积核的值不会发生变化,所以又具有权值共享的特性
1.权值共享的优势(对比BP神经网络)
- 这里的参数指的是神经元的权重
- 权值的共享使得卷积神经网络的参数个数大幅度减少
2.卷积的过程
实际应用过程中往往是对多维的特征矩阵进行卷积操作
卷积核的深度要和输入特征矩阵一致(这里的深度指的是channel,即通道数),都是三维的,最终卷积得到的矩阵是由三通道的输入特征矩阵和三通道的卷积核分别对应卷积,再对应相加后得到一个卷积矩阵
3.总结
1、卷积核的channel与输入特征层的channel相同(都是三通道)
2、输出的特征矩阵channel与卷积核的个数相同(通过卷积核1和卷积核2最终得到一个两通道的输出特征矩阵)
4.思考
(1) 如果加上偏移量bias该如何计算?
只需要将最终卷积得到的矩阵的每个元素和偏移量进行相加即可
(2) 加上激活函数该如何计算?
常用的激活函数
- 为什么要使用激活函数?在线性的计算过程中引入非线性因素,使其具备解决非线性问题的能力
- Relu激活函数实际上是将负值全部过滤掉,只保留了正值不变,在实际应用中使用较多
- 在反向传播误差的过程中,如果使用sigmoid激活函数,导数的求解非常麻烦
- 如果使用Relu激活函数,权重如果进入失活状态后无法被再次激活,所以在训练的过程中,建议不要一开始就使用特别大的学习率进行学习,否则很容易导致大量神经元失活
(3) 如果在卷积的过程中出现越界的情况该如何处理?
- 一般强况下,可以使用padding的方式在图像的周围直接补零进行处理,补零后就能够正常地进行卷积,而不会出现越界的情况了
- padding的像素p:一般实际应用过程中是两边同时补零,即左右上下进行对称的:补零操作
- 上图中只补了一边,所以只用加上一个p就够了
- N = ( 4 - 3 + 1 )/ 2 + 1 = 2 ,所以最后得到一个2*2的特征矩阵
三、池化层
池化层的目的就是对特征图进行稀疏处理,减少数据运算量
maxpooling下采样:寻找池化核对应范围内的最大值来进行最大下采样操作
averagepooling下采样层:寻找池化核对应范围内的平均值来进行平均下采样操作
池化层的特点
1、没有训练参数,只是在原始的特征图上进行求最大值或者平均值的操作
2、它只会改变特征矩阵的宽度(w)和高度(h),并不会改变深度(channel)
3、一般池化核的大小(poolsize)和步长(stride)相同,可以将特征图进行一定比例的缩小,计算更加方便(这只是一般情况下,但并不绝对)
四、误差的计算
以三层的BP神经网络进行讲解
参数:
- 第一层:输入层:两个节点 和
- 第二层:隐藏层:三个节点 是激活函数, 和 是对应的权重,是偏置
以中间节点为例进行计算
同理求出 和 的值
1.Softmax激活函数的计算过程
为什么用Softmax激活函数?
因为:希望输出的 和 符合概率分布
2.Cross Entropy Loss,交叉熵损失函数
1.针对多分类问题(softmax输出,所有输出概率之和为1)
2.针对二分类问题(sigmoid输出,每个输出节点之间互不相干)
采用Softmax输出则符合概率输出(所有概率之和为1)
采用Sigmoid输出则不符合概率输出
根据公式我们可以得到Loss使用交叉熵的计算公式。
五、误差的反向传播
计算 的误差梯度(即求偏导)
对黄色框中的偏导分别进行计算
所求的值相当于已经把得到的误差反向传播到每一个节点,得到了每一个节点的损失梯度
六、权重的更新
更新权重的表达式非常简单,但是我们无法确定所求的梯度方向是不是减少损失最快的方向。
在实际训练中,我们往往是设置batch进行训练的,每一个批次训练完毕后会计算该批次的Loss以及梯度,虽然有梯度,但这个梯度是对于这一个批次来说是最优的,对于整个数据而言就不一定的。所以为了更好的在batch训练中进行梯度更新,引入了优化器(optimizer)的概念。
七、 优化器(optimizer)
做出以下优化 :多出一个动量部分
除了计算当前batch的梯度外还会加入之前batch的梯度。
为本次batch的梯度,为上一个batch的梯度, 为本次batch实际更新的梯度。
加了动量可以有效抑制样本噪声的干扰。
该优化器是对学习率进行改进的。
随着batch的进行,最终 会越来越小 -> 代表着更新的力度越来越小,看起来就像更新时用到的学习率逐渐变小了。
缺点:学习率下降太快,可能还没有收敛就停止训练了。
也是对学习率进行调整,是Adagrad优化器的改进版本。相比于Adagrad优化器,RMSProp其实就是添加了两个系数去控制学习率的衰减力度。
6.几种优化器效果对比
- SGD虽然速度慢,但梯度更新的方向是比较理想的。
- 带有Momentum的SGD开始时不好,但很快找回了正确的路径
- Adagrad和RMSProp不仅方向保持是正确的,而且速度也很快
- 这里没有展示Adam优化器的效果
在实际项目中,比较常用的有:
- 带有Momentum的SGD
- Adam
可能有很多人选择使用Adam优化器,因为它的效果比较好,但是在论文中,很多作者仍然使用的是带有momentum的SGD优化器
如何选择还是要看实际情况