【深度学习】从神经网络到卷积神经网络
前言
本篇主要介绍卷积神经网络,为什么有神经网络了还会出现卷积神经网络,以及卷积神经网络的主要层次。
一、神经网络
参考链接:【深度学习】神经网络与BP算法
传统的神经网络使用矩阵乘法来建立输入与输出的连接关系。其中,参数矩阵中每一个单独的参数都描述了一个输入单元与一个输出单元的交互。这意味着每一个输出单元与每一个输入单元都参数交互,也就是上图中第一个隐层中的每一个神经元都要与输入层的每一个神经元连接。
例如上图,假设加上偏置:
- 输入层到第一层隐藏层有多少个参数
- 第一层隐藏层到第二层隐藏层有多少个参数
- 输入层到第一层隐藏层有多少个参数
那么这个简单的神经网络一共有: 个参数。
这个结果貌似看出不什么,但是当我们在处理一张图像的时候,输入的图像可能包含成千上万个像素点,再加上多层网络,那么这个参数量将会很大,就是模型相当的复杂,不管是模型的训练还是存储都相当大。
二、卷积和池化运算
在介绍卷积神经网络之前,我们先回顾下卷积运算和池化运算:
三、卷积神经网络
卷积神经网络(Convolutional Neural Networks,CNN
),是一种专门用来处理类似网络结构的数据的神经网络,卷积网络是指那些至少在网络的一层中使用卷积运算来替代一般的矩阵乘法运算的神经网络。CNN
可以有效的降低传统神经网络的复杂性,这主要是通过卷积来达到的。CNN
的应用主要是在图像分类和物品识别等应用场景应用比较多。
卷积运算的主要思想体现在:稀疏交互、参数共享
- 稀疏交互
前面我们提到,传统的神经网络是通过矩阵相乘来建立输入与输出的连接关系。然而,卷积网络具有稀疏交互的特性,这便是通过卷积核的来实现的,因为我们可以使核的大小远远小于输入大小。
对于上面提到的图像数据,我们可以通过几十到几百个像素点的卷积核来检测一些小的有意义的特征,这就意味着我们需要存储的参数更少,不仅减少了模型的存储需要,还提高了它的统计效率,这也意味着得到输出我们只需要更少的计算量。
例如:有 个输入, 个输出,那么传统神经网络的矩阵乘法需要 个参数并且相应算法的时间复杂度为 。如果我们限制每一个输出拥有的连接数为 ,那么稀疏的连接方法只需要 个参数以及 的运行时间。在很多实际应用中,只需要保持 比 小几个数量级,就能在机器学习的任务中取得好的表现。
- 参数共享
是指在一个模型的多个函数中使用相同的参数。在传统的神经网络中,当计算一层的输出时,权重矩阵的每一个元素只使用一次,当它乘以输入的一个元素后就不会再用到了。而在卷积神经网络中,卷积核的每一个元素都作用在输入的每一个位置上。这样便可以保证我们在进行模型训练的时候只需要学习一个参数集合,而不是对每一位置都需要学习一个单独的参数集合。这使得卷积在存储需要和统计效率方面极大地优于稠密矩阵的乘法运算。
卷积神经网络的优点与缺点:
优点:
- 共享卷积核(共享参数),对高维数据的处理没有压力
- 无需选择特征属性,只要训练好权重,即可得到特征值
- 深层次的网络抽取图像信息比较丰富,表达效果好
缺点
- 需要调参,需要大量样本,训练迭代次数比较多,最好使用GPU训练
- 物理含义不明确,从每层输出中很难看出含义来
四、卷积神经网络的主要层次
1、数据输入层
熟悉机器学习开发流程的应该知道,在我们使用数据之前,我们都需要对数据进行预处理操作,卷积神经网络也不例外。
需要做预处理的主要原因有:
- 输入数据单位不一样,可能会导致神经网络收敛速度慢,训练时间长
- 数据范围大的输入在模式分类中的作用可能偏大,而数据范围小的作用就有可能偏小
- 由于神经网络中存在的**函数是有值域限制的,因此需要将网络训练的目标数据映射到**函数的值域
- S形**函数在(0,1)区间以外区域很平缓,区分度太小。例如S形函数f(X),f(100)与f(5)只相差0.0067
常见3种数据预处理方式:
-
去均值
将输入数据的各个维度中心化到0
-
归一化
将输入数据的各个维度的幅度归一化到同样的范围
-
PCA/白化
用PCA降维(去掉特征与特征之间的相关性),参考:主成分分析
白化是在PCA的基础上,对转换后的数据每个特征轴上的幅度进行归一化,参考:白化
备注:实际上在卷积神经网络中,一般并不会适用PCA和白化的操作,一般去均值和归一化使用的会比较多。
2、卷积计算层
人的大脑在识别图片的过程中,会由不同的皮质层处理不同方面的数据,比如:颜色、形状、光暗等,然后将不同皮质层的处理结果进行合并映射操作,得出最终的结果值,第一部分实质上是一个局部的观察结果,第二部分才是一个整体的结果合并。
基于人脑的图片识别过程,我们可以认为图像的空间联系也是局部的像素联系比较紧密,而较远的像素相关性比较弱,所以每个神经元没有必要对全局图像进行感知,只要对局部进行感知,而在更高层次对局部的信息进行综合操作得出全局信息;即局部感知
相关概念:
- 深度:depth
- 步长:stride
- 填充值:zero-padding
例子:
在神经网络中,输入是向量,而在卷积神经网络中,输入是一个多通道图像,如下图:
上图深度为3,步长为1,填充为0
- 第一层卷积使用的是 6 个 的卷积核,得到 6 个 的特征图
- 第二层卷积使用的是 10 个 的卷积核,得到 10 个 的特征图
- 局部感知: 在进行计算的时候,将图片划分为一个个的区域进行计算/考虑
- 参数共享机制:假设每个神经元连接数据窗的权重是固定的
- 滑动窗口重叠:降低窗口与窗口之间的边缘不平滑的特性
3、ReLU激励层
将卷积层的输出结果做一次非线性的映射, 也就是做一次“**”:
常用非线性映射函数:
- Sigmoid(S形函数)
优点:
- 取值范围(0~1)、简单、容易理解
缺点:
- 容易饱和和终止梯度传递(“死神经元”);
- sigmoid函数的输出没有0中心化。
- Tanh(双曲正切,双S形函数)
优点:
- 取值范围(-1~1)、易理解、0中心化
缺点:
- 容易饱和和终止梯度传递(“死神经元”)。
- ReLU
优点:
- 相比于Sigmoid和Tanh,提升收敛速度
- 梯度求解公式简单,不会产生梯度消失和梯度爆炸
缺点:
- 没有边界,可以使用变种ReLU:
min(max(0,x), 6)
- 比较脆弱,比较容易陷入出现”死神经元”的情况
- 解决方案:较小的学习率
- Leaky ReLU
在ReLU函数的基础上,对x≤0的部分进行修正;目的是为了解决ReLU**函数中容易存在的”死神经元”情况的;不过实际场景中:效果不是太好。
- Maxout
可以看作是在深度学习网络中加入一层**函数层,包含一个参数k,拟合能力特别强。特殊在于:增加了k个神经元进行**,然后输出**值最大的值。
优点:
- 计算简单,不会出现神经元饱和的情况
- 不容易出现死神经元的情况
缺点:
- 参数double,计算量复杂了
激励层建议:
- CNN尽量不要使用sigmoid,如果要使用,建议只在全连接层使用
- 首先使用ReLU,因为迭代速度快,但是有可能效果不佳
- 如果使用ReLU失效的情况下,考虑使用Leaky ReLu或者Maxout,此时一般情况都可以解决啦
- tanh**函数在某些情况下有比较好的效果,但是应用场景比较少
4、池化层
在连续的卷积层中间存在的就是池化层,主要功能是:通过逐步减小表征的空间尺寸来减小参数量和网络中的计算;池化层在每个特征图上独立操作。使用池化层可以压缩数据和参数的量,减小过拟合。
在池化层中,进行压缩减少特征数量的时候一般采用两种策略:
-
Max Pooling
:最大池化,一般采用该方式 -
Average Pooling
:平均池化
5、全连接层
类似传统神经网络中的结构,FC
层中的神经元连接着之前层次的所有**输出;换一句话来讲的话,就是两层之间所有神经元都有权重连接;通常情况下,在CNN
中,FC
层只会在尾部出现
一般的CNN结构依次为:
- INPUT:输入层
- [[CONV -> RELU] * N -> POOL?]*M:M个(N个卷积+激励)后池化
- [FC -> RELU] * K:K个全连接+激励
- FC:全连接
五、卷积神经网络的参数初始化
在卷积神经网络中,可以看到神经元之间的连接是通过权重 以及偏置 实现的。在具体的神经网络之前,我们还有一个任务需要做,那就是初始化参数:
权重的初始化:
- 一般方式:很小的随机数(对于多层深度神经网络,太小的值会导致回传的梯度非常小),一般随机数是服从均值为0,方差未知(建议:2/n, n为权重数量)的高斯分布随机数列。
- 错误方式:全部初始化为0,全部设置为0,在反向传播的时候是一样的梯度值,那么这个网络的权重是没有办法差异化的,也就没有办法学习到东西。
偏置项的初始化:
- 一般直接设置为0,在存在ReLU**函数的网络中,也可以考虑设置为一个很小的数字
六、卷积神经网络正则化和Dropout
神经网络的学习能力受神经元数目以及神经网络层次的影响,神经元数目越大,神经网络层次越高,那么神经网络的学习能力越强,那么就有可能出现过拟合的问题;(通俗来讲:神经网络的空间表达能力变得更紧丰富了)
-
Regularization
:正则化,通过降低模型的复杂度,通过在cost函数上添加一个正则项的方式来降低overfitting,主要有 和 两种方式 -
Dropout
:通过随机删除神经网络中的神经元来解决overfitting问题,在每次迭代的时候,只使用部分神经元训练模型获取 和 的值
一般情况下,对于同一组训练数据,利用不同的神经网络训练之后,求其输出的平均值可以减少overfitting。Dropout
就是利用这个原理,每次丢掉一半左右的隐藏层神经元,相当于在不同的神经网络上进行训练,这样就减少了神经元之间的依赖性,即每个神经元不能依赖于某几个其它的神经元(指层与层之间相连接的神经元),使神经网络更加能学习到与其它神经元之间的更加健壮robust(鲁棒性)的特征。另外Dropout不仅减少overfitting,还能提高准确率。
正则化
是通过给cost函数添加正则项的方式来解决overfitting,Dropout
是通过直接修改神经网络的结构来解决overfitting
建议:
- 一般都可以使用Dropout解决过拟合问题
- 回归算法中使用L2范数相比于Softmax分类器,更加难以优化。对于回归问题,首先考虑是否可以转化为分类问题,比如:用户对于商品的评分,可以考虑将得分结果分成1~5分,这样就变成了一个分类问题。如果实在没法转化为分类问题的,那么使用L2范数的时候要非常小心,比如在L2范数之前不要使用Dropout。
- 一般建议使用L2范数或者Dropout来减少神经网络的过拟合。
七、卷积神经网络训练算法
-
和一般的机器学习算法一样,需要先定义
Loss Function
,衡量预测值和实际值之间的误差,一般使用平方和误差公式 -
找到最小损失函数的W和b的值,CNN中常使用的是SGD
其实就是一般深度学习中的BP算法;SGD需要计算W和b的偏导,BP算法就是计算偏导用的,BP算法的核心是求导链式法则。
在神经网络中一般采用Mini-batch SGD
,主要包括以下四个步骤的循环:
- 采样一个batch的数据
- 前向计算损失loss
- 反向传播计算梯度(一个batch上所有样本的梯度和)
- 利用梯度更新权重参数
【深度学习】基于im2col的展开Python实现卷积层和池化层:这一篇主要是通过卷积层和池化层的前向传播和误差反向传播
【深度学习】CNN的实现以及在手写数字识别中的应用:这一篇是应用上一篇实现的卷积层和池化层来进行网络模型的构建与训练
八、总结
- 卷积神经网络通过卷积运算减少模型参数,降低模型的复杂度;卷积核模仿人识别图片时的局部感知;实现了参数共享机制;
- 通过激励函数将卷积层的输出结果做一次非线性的映射;
- 通过池化层可以压缩数据和参数的量,减小过拟合,最大池化和平均池化;
- 通常情况下,在CNN中,全连接层只会在尾部出现;
- 在具体的神经网络之前,我们需要做初始化参数;
- 一般使用
L2范数
或者Dropout
来减少神经网络的过拟合 - 卷积神经网络训练算法常使用的是小批量随机梯度下降(
Mini-batch SGD
)