【深度学习笔记系列】卷积神经网络(CNN)详解
博主声明该深度学习笔记系列为个人学习笔记整理。内容来源于网上的大牛和机器学习专家所无私奉献的资料,仅供学习交流,非商用。具体引用的资料请看参考文献。具体的版本声明也参考原文献,有部分参考资料没有给出来源,请各位原博主理解,如果涉及侵权,请联系博主删除。本人才疏学浅,整理总结的时候难免出错,此属于第一版本,若有错误,还需继续修正与增删。如果博主有未注意的错误,还望各位前辈不吝指正,谢谢。...
博主声明
-
该深度学习笔记系列为个人学习笔记整理。内容来源于网上的大牛和机器学习专家所无私奉献的资料,仅供学习交流,非商用。具体引用的资料请看参考文献。具体的版本声明也参考原文献,有部分参考资料没有给出来源,请各位原博主理解,如果涉及侵权,请联系博主删除。
-
本人才疏学浅,整理总结的时候难免出错,此属于第一版本,若有错误,还需继续修正与增删。如果博主有未注意的错误,还望各位前辈不吝指正,谢谢。
卷积神经网络(CNN)详解
从神经网络到卷积神经网络(CNN)
神经网络
神经网络,也指人工神经网络(Artificial Neural Networks,简称ANNs),是一种模仿生物神经网络行为特征的算法数学模型,由神经元、节点与节点之间的连接(突触)所构成,如下图:
神经元
神经网络由大量的节点(或称“神经元”、“单元”)和相互连接而成。每个神经元接受输入的线性组合,进行非线性变换(亦称激活函数activation function)后输出。每两个节点之间的连接代表加权值,称之为权重(weight)。不同的权重和激活函数,则会导致神经网络不同的输出。
神经网络的每个神经元/单元如下:
组织在一起,便形成了神经网络。下图便是一个三层神经网络结构:
上图中最左边的原始输入信息称之为输入层,最右边的神经元称之为输出层(上图中输出层只有一个神经元),中间的叫隐藏层。
- 输入层(Input layer):众多神经元(Neuron)接受大量非线形输入信息。输入的信息称为输入向量。
- 输出层(Output layer):信息在神经元链接中传输、分析、权衡,形成输出结果。输出的讯息称为输出向量。
- 隐藏层(Hidden layer):简称“隐层”,是输入层和输出层之间众多神经元和链接组成的各个层面。如果有多个隐藏层,则意味着多个激活函数。
那卷积神经网络跟它是什么关系呢?
其实卷积神经网络依旧是层级网络,只是层的功能和形式做了变化,可以说是传统神经网络的一个改进。比如下图中就多了许多传统神经网络没有的层次:
卷积神经网络
概览
卷积神经网络是一种多层神经网络,擅长处理图像特别是大图像的相关机器学习问题。
卷积网络通过一系列方法,成功将数据量庞大的图像识别问题不断降维,最终使其能够被训练。CNN最早由Yann LeCun提出并应用在手写字体识别上(MINST)。LeCun提出的网络称为LeNet,其网络结构如下:
这是一个最典型的卷积网络,由卷积层、池化层、全连接层组成。其中卷积层与池化层配合,组成多个卷积组,逐层提取特征,最终通过若干个全连接层完成分类。
卷积层完成的操作,可以认为是受局部感受野概念的启发,而池化层,主要是为了降低数据维度。
综合起来说,CNN通过卷积来模拟特征区分,并且通过卷积的权值共享及池化,来降低网络参数的数量级,最后通过传统神经网络完成分类等任务。
卷积神经网络结构
输入层(Input Layer)
该层要做的处理主要是对原始图像数据进行预处理,其中包括:
- 去均值:把输入数据各个维度都中心化为0,如下图所示,其目的就是把样本的中心拉回到坐标系原点上。
- 归一化:幅度归一化到同样的范围,如下所示,即减少各维度数据取值范围的差异而带来的干扰。
- PCA/白化:用PCA降维;白化是对数据各个特征轴上的幅度归一化。
去均值与归一化效果图:
去相关与白化效果图:
卷积计算层(Cnov Layer)
卷积神经网络的名字来源于“卷积”计算。在卷积神经网络中,卷积的主要目的是从输入图像中提取特征。通过使用输入数据中的小方块来学习图像特征,卷积保留了像素间的空间关系。
什么是卷积操作?对图像(不同的数据窗口数据)和滤波矩阵(一组固定的权重:因为每个神经元的权重固定,所以又可以看做一个恒定的滤波器filter)做内积(逐个元素相乘再求和)的操作就是所谓的『卷积』操作,也是卷积神经网络的名字来源。比如下图中,图中左边部分是原始输入数据,图中中间部分是滤波器filter,图中右边是输出的新的二维数据:
在这个卷积层,有两个关键操作:
- 局部关联:每个神经元看做一个滤波器(filter),也称为过滤器
- 窗口(receptive field)滑动:filter对局部数据计算
在介绍卷积计算之前,先介绍下卷积层遇到的几个名词:
- 深度(depth):它控制输出单元的深度,也就是filter的个数,连接同一块区域的神经元个数。
- 步长(stride):窗口一次滑动的长度
- 填充值(zero-padding):通过在输入单元周围补零来改变输入单元整体大小,从而控制输出单元的空间大小
填充值是什么呢?以下图为例子,比如有这么一个
5
∗
5
5*5
5∗5的图片(一个格子一个像素),我们滑动窗口取
2
∗
2
2*2
2∗2,步长取
2
2
2,那么我们发现还剩下1个像素没法滑完,那怎么办呢?
那我们在原先的矩阵加了一层填充值,使得变成
6
∗
6
6*6
6∗6的矩阵,那么窗口就可以刚好把所有像素遍历完。这就是填充值的作用。
在了解了卷积层相关概念以后,我们看一下卷积层最重要的部分:卷积层是如何计算的?
假设一张图像有
5
∗
5
5*5
5∗5 个像素,1 代表白,0 代表黑,这幅图像被视为
5
∗
5
5*5
5∗5 的单色图像。现在用一个由随机地 0 和 1 组成的
3
∗
3
3*3
3∗3 矩阵去和图像中的子区域做乘法,每次迭代移动一个像素,这样该乘法会得到一个新的
3
∗
3
3*3
3∗3 的矩阵。下面的动图展示了这个过程:
下图展示了使用两个三通道滤波器从三通道(RGB)图像中生成两个卷积输出的详细过程,滤波器 w0 和 w1 是「卷积」,输出是提取到的特征,包含这些滤波器的层叫做卷积层:
举个直观的例子,方便大家理解卷积操作。对于同一张输入图像,不同的过滤器矩阵将会产生不同的特征映射,例如输入图像为:
在下表中,我们可以看到上图在不同过滤器下卷积的效果。如图所示,只需在卷积运算前改变过滤器矩阵的数值就可以执行边缘检测,锐化和模糊等不同操作— 这意味着不同的过滤器可以检测图像的不同特征,例如边缘, 曲线等。
激励层(ReLU Layer)
激励层的主要作用是将卷积层的结果做非线性映射。常见的激励层函数有sigmoid
、tanh
、Relu
、Leaky Relu
、ELU
、Maxout
。CNN采用的激励函数一般为ReLU(The Rectified Linear Unit/修正线性单元
),它的特点是收敛快,求梯度简单,但较脆弱。
S i g m o i d Sigmoid Sigmoid函数
Sigmoid
函数,也叫Logistic
函数,用于隐层神经元输出,取值范围为(0,1)。Sigmoid
函数的缺点有:
- 反向传播时,很容易就会出现梯度消失的情况(导数重0开始又消失于0),从而无法完成深层网络的训练。
- 函数输出并不是0均值(zero-centered),输出值恒大于0。
- 幂运算相对来讲比较耗时。
T a n h Tanh Tanh函数
T
a
n
h
(
x
)
=
2
s
i
g
m
o
i
d
(
2
x
)
−
1
Tanh(x)=2sigmoid(2x)-1
Tanh(x)=2sigmoid(2x)−1
Tanh
函数,称为双切正切函数,取值范围为[-1,1]。,是sigmoid
的变形,与 sigmoid
不同的是,tanh
是0均值的。但是,梯度消失和幂运算的问题仍然存在。实际应用中,tanh
会比 sigmoid
更好。
R e L U ReLU ReLU函数
R
e
L
u
ReLu
ReLu函数的优点:
- R e L U ReLU ReLU的收敛速度会比 s i g m o i d / t a n h sigmoid/tanh sigmoid/tanh 快很多。因为在原点右侧它的偏导数为1,求导简单,这样在做反向传播时速度比较快。相比于 s i g m o i d / t a n h sigmoid/tanh sigmoid/tanh, R e L U ReLU ReLU只需要一个阈值就可以得到激活值。
- R e L U ReLU ReLU解决了梯度消失的问题。
R e L u ReLu ReLu函数的缺点:
- 较为脆弱,原点左侧的函数具有的sigmoid相似的问题,即导数等于0,这样导致某些神经元可能永远不会被激活,导致相应的参数永远不能被更新,那么这个神经元的梯度就永远都会是0了。
L e a k y Leaky Leaky R e L u ReLu ReLu函数
f
(
x
)
=
m
a
x
(
a
x
,
x
)
f(x)=max(ax,x)
f(x)=max(ax,x)
L
e
a
k
y
Leaky
Leaky
R
e
L
u
ReLu
ReLu在是
R
e
L
u
ReLu
ReLu的“增强版”,通过上图可以看出,相比
R
e
L
u
ReLu
ReLu,
L
e
a
k
y
Leaky
Leaky
R
e
L
u
ReLu
ReLu在原点左侧的表达式中对x乘以了一个比较小的系数,这样保证了在做反向传播时不会挂掉,改善了
R
e
L
U
ReLU
ReLU的死亡特性,并且其计算也很快,但是也同时损失了一部分稀疏性。
ELU函数
E
L
U
ELU
ELU:指数线性单元(Exponential linear unit
), 该激活函数由Djork
等人提出,被证实有较高的噪声鲁棒性,同时能够使得使得神经元的平均激活均值趋近为 0,同时对噪声更具有鲁棒性。由于需要计算指数,计算量较大。
Maxout函数
泛化了
R
e
L
U
ReLU
ReLU和
L
e
a
k
y
Leaky
Leaky
R
e
L
U
ReLU
ReLU,改善了死亡特性,但是同样损失了部分稀疏性,每个非线性函数增加了两倍的参数。
激活函数的实践经验
- 不要用
sigmoid
!不要用sigmoid
!不要用sigmoid
! - 首先试
ReLU
,因为快,但要小心点 - 如果
ReLU
失效,请用Leaky ReLU
或者Maxout
- 某些情况下
tanh
倒是有不错的结果,但是很少
池化层(Pooling Layer)
池化(Pooling):也称为欠采样或下采样。主要用于特征降维,压缩数据和参数的数量,减小过拟合,同时提高模型的容错性。
池化层的具体作用:
- 特征不变性:就是我们在图像处理中经常提到的特征的尺度不变性,池化操作就是图像的resize,平时一张狗的图像被缩小了一倍我们还能认出这是一张狗的照片,这说明这张图像中仍保留着狗最重要的特征,我们一看就能判断图像中画的是一只狗,图像压缩时去掉的信息只是一些无关紧要的信息,而留下的信息则是具有尺度不变性的特征,是最能表达图像的特征。
- 特征降维:我们知道一幅图像含有的信息是很大的,特征也很多,但是有些信息对于我们做图像任务时没有太多用途或者有重复,我们可以把这类冗余信息去除,把最重要的特征抽取出来,这也是池化操作的一大作用。
- 防止过拟合:在一定程度上防止过拟合,更方便优化。
池化操作对每个深度切片独立,规模一般为 2 ∗ 2 2*2 2∗2,相对于卷积层进行卷积运算,池化层进行的运算一般最常见有以下几种:
- 最大池化(Max Pooling):取4个点的最大值。这是最常用的池化方法。
- 均值池化(Mean Pooling):取4个点的均值。
举个最大池化的例子,通过
2
×
2
2×2
2×2窗口在修正特征映射(卷积+ ReLU 操作后得到)上应用最大池化操作,这样就降低了特征映射的维度:
全连接层(Fully-Connected Layer)
完全连接层是一个传统的多层感知器,它在输出层使用 softmax 激活函数(也可以使用其他分类器,比如 SVM,但在本文只用到了 softmax)。“完全连接”这个术语意味着前一层中的每个神经元都连接到下一层的每个神经元。
卷积层和池化层的输出代表了输入图像的高级特征。完全连接层的目的是利用这些基于训练数据集得到的特征,将输入图像分为不同的类,例如(图片来自CS231n:用于视觉识别的卷积神经网络)我们要执行的图像分类任务有四个可能的输出,如下图所示(请注意,下图没有展示出完全连接层中节点之间的连接):
关于参数减少与权值共享
CNN牛逼的地方就在于通过感受野和权值共享减少了神经网络需要训练的参数的个数。那究竟是什么呢?
如下图左:如果我们有1000*1000
像素的图像,有100万
个隐层神经元,那么他们全连接的话(每个隐层神经元都连接图像的每一个像素点),就有1000x1000x1000000=10^12
个连接,也就是10^12
个权值参数。如果计算所有的连接,显然是不值得的。我们利用之前提到的下采样层进行原始数据的分组特征提取,这样,我们就可以减少连接的数目,也就是减少神经网络需要训练的权值参数的个数了。
如下图右:假如局部感受野是10x10
,隐层每个感受野只需要和这10x10
的局部图像相连接,所以100万
个隐层神经元就只有一亿个连接,即10^8个参数。比原来减少了四个数量级,大幅度减少了计算量,这样训练起来就没那么费力了,但还是感觉很多的啊,那还有啥办法没?
下面我们来看看卷积神经网络第二个神器—权值共享。在上面的局部连接中,隐含层的每一个神经元都连接10x10
个图像区域,也就是说每一个神经元存在10x10=100
个连接权值参数。那如果我们每个神经元这100个参数是相同的呢?那么参数数目就变为100个了,这就是权值共享。那怎么理解权值共享呢?
我们可以将这100个参数(也就是卷积操作)看成是提取特征的方式,该方式与图像上的位置无关。这其中蕴含的原理是:图像的一部分统计特性与其他部分是一样的。这也意味着我们在这一部分的学习的特征也能用到另一部分上,所以对于图像上所有的位置,我们都能使用同样的学习特征。
在卷积操作中,我们展示了一个
3
∗
3
3*3
3∗3的卷积核在
5
∗
5
5*5
5∗5的图像上做卷积的过程。每个卷积都是一种特征提取方式,就像一个筛子,将图像中符合条件(激活值越大越符合条件)的部分筛选出来:
好了,看到这你就会想,这样提取特征只是提取了一种特征。我们需要对各种图像进行特征提取,比如数字识别和图像识别就不一样。那么,我们需要提取不同的特征,多加几种卷积核行吗?
如上所述,只有100个参数时,表明只有1个 10 ∗ 10 10*10 10∗10的卷积核,显然,特征提取是不充分的。也就是说,卷积核不够,我们可以添加多个卷积核,比如100种卷积核,可以学习100种特征。
假设我们加到100种滤波器,每种滤波器的参数不一样,表示它提出输入图像的不同特征,例如不同的边缘。这样每种卷积核去卷积图像就得到对图像的不同特征的表示,我们称为FM(Feature Map)
。所以100种卷积核就有100个FM。这100个Feature Map就组成了一层神经元。那么我们计算下这层的参数:
100 种 卷 积 核 ∗ 每 种 卷 积 核 共 享 100 个 参 数 = 100 ∗ 100 = 10 K 100种卷积核*每种卷积核共享100个参数=100*100=10K 100种卷积核∗每种卷积核共享100个参数=100∗100=10K
看一下最开始我们的参数是10^12,而且只是一种特征提取,现在我们把它缩减到1万个参数,还能提取100个特征,这不仅降低了很多的计算成本,而且还提取了多个特征,这就是卷积神经网络的强大实力。具体见下图(不同的颜色表达不同的滤波器):
刚才说隐层的参数个数和隐层的神经元个数无关,只和滤波器的大小和滤波器种类的多少有关。那么隐层的神经元个数怎么确定呢?它和原图像输入的大小(神经元个数)、卷积核的大小和卷积核在图像中的滑动步长都有关!那什么是滑动步长呢?步长就是决定卷积核覆盖范围的参数。例如,图像是
1000
像
素
∗
1000
像
素
1000像素*1000像素
1000像素∗1000像素,卷积核大小是
10
像
素
∗
10
像
素
10像素*10像素
10像素∗10像素,假设卷积核没有重叠,它的步长定义为10,那么隐含层的神经元个数就是:
(
1000
∗
1000
)
/
(
10
∗
10
)
=
100
∗
100
(1000*1000 ) / (10*10)=100*100
(1000∗1000)/(10∗10)=100∗100个神经元。注意了,这只是一种卷积核,也就是一个FM的神经元个数,如果100个FM就是100倍了。由此可见,图像越大,神经元个数和需要训练的权值参数个数的差距就越大,如下图所示。
需要注意的一点是,上面的讨论都没有考虑每个神经元的偏置部分。所以权值个数需要加1 。这个也是同一种卷积核共享的。
总之,卷积网络的核心思想是:将完整输入信息切分成一个个子采样层进行采样,然后将提取的特征和权重值作为输入参数,传递至下一层。这其中充分利用了局部感受野、权值共享以及时间或空间的采样规则等方法。
卷积神经网络的优缺点
优点
- 共享卷积核,对高维数据处理无压力
- 无需手动选取特征,训练好权重,即得特征分类效果好
缺点
- 需要调参,需要大样本量,训练最好要GPU
- 物理含义不明确(也就说,我们并不知道没个卷积层到底提取到的是什么特征,而且神经网络本身就是一种难以解释的“黑箱模型”)
常用卷积神经网络
卷积神经网络的发展
图片引自:卷积神经网络经典网络(LeNet、AlexNet、VGG、ResNet)
卷积神经网络最初为解决图像识别问题而提出,目前广泛应用于图像,视频,音频和文本数据。目前图像分类中的ResNet
, 目标检测领域占统治地位的Faster R-CNN
,分割中最牛的Mask-RCNN
, UNet
和经典的FCN
都是以下面几种常见网络为基础。
LeNet
背景
LeNet
诞生于1994年,由深度学习三巨头之一的Yan LeCun
提出,他也被称为卷积神经网络之父。LeNet
主要用来进行手写字符的识别与分类,准确率达到了98%,并在美国的银行中投入了使用,被用于读取北美约10%的支票。LeNet
奠定了现代卷积神经网络的基础。LeNet论文地址
网络结构
上图为LeNet
结构图,是一个6层网络结构:三个卷积层,两个个下采样层和一个全连接层(图中C代表卷积层,S代表下采样层,F代表全连接层)。其中,C5
层也可以看成是一个全连接层,因为C5
层的卷积核大小和输入图像的大小一致,都是5*5
(可参考LeNet详解)。
网络特点
- 每个卷积层包括三部分:卷积、池化和非线性激活函数(
sigmoid
激活函数) - 使用卷积提取空间特征
- 降采样层采用平均池化
AlexNet
背景
AlexNet
由Hinton
的学生Alex Krizhevsky
于2012年提出,并在当年取得了Imagenet
比赛冠军。AlexNet
可以算是LeNet的一种更深更宽的版本,证明了卷积神经网络在复杂模型下的有效性,算是神经网络在低谷期的第一次发声,确立了深度学习,或者说卷积神经网络在计算机视觉中的统治地位。AlexNet论文
网络结构
AlexNet
的结构及参数如上图所示,是8层网络结构(忽略激活,池化,LRN,和dropout层),有5个卷积层和3个全连接层,第一卷积层使用大的卷积核,大小为11*11
,步长为4。第二卷积层使用5*5
的卷积核大小,步长为1,剩余卷积层都是3*3
的大小,步长为1。激活函数使用ReLu,池化层使用重叠的最大池化,大小为3*3
,步长为2。在全连接层增加了dropout
,第一次将其实用化。(可参考AlexNet详解)
网络特点
- 使用两块GPU并行加速训练,大大降低了训练时间
- 成功使用ReLu作为激活函数,解决了网络较深时的梯度弥散问题
- 使用数据增强、dropout和LRN层来防止网络过拟合,增强模型的泛化能力
VGGNet
背景
VGGNet
是牛津大学计算机视觉组和Google DeepMind
公司一起研发的深度卷积神经网络,并取得了2014年Imagenet
比赛定位项目第一名和分类项目第二名。该网络主要是泛化性能很好,容易迁移到其他的图像识别项目上,可以下载VGGNet
训练好的参数进行很好的初始化权重操作,很多卷积神经网络都是以该网络为基础,比如FCN
,UNet
,SegNet
等。VGG
版本很多,常用的是VGG16
,VGG19
网络。VGGNet论文
网络结构
上图为VGG16
的网络结构,共16层(不包括池化
和softmax
层),所有的卷积核都使用3*3
的大小,池化都使用大小为2*2
,步长为2的最大池化,卷积层深度依次为64 -> 128 -> 256 -> 512 ->512。
网络特点
网络结构和AlexNet有点儿像,不同的地方在于:
- 主要的区别,一个字:深,两个字:更深。把网络层数加到了16-19层(不包括池化和
softmax
层),而AlexNet
是8层结构。 - 将卷积层提升到卷积块的概念。卷积块有2~3个卷积层构成,使网络有更大感受野的同时能降低网络参数,同时多次使用ReLu激活函数有更多的线性变换,学习能力更强(详细介绍可参考:VGGNet详解)。
- 在训练时和预测时使用
Multi-Scale
做数据增强。训练时将同一张图片缩放到不同的尺寸,在随机剪裁到224*224
的大小,能够增加数据量。预测时将同一张图片缩放到不同尺寸做预测,最后取平均值。
ResNet
背景
ResNet(残差神经网络)
由微软研究院的何凯明等4名华人于2015年提出,成功训练了152层超深的卷积神经网络,效果非常突出,而且容易结合到其他网络结构中。在五个主要任务轨迹中都获得了第一名的成绩(ImageNet分类任务、ImageNet检测任务、ImageNet定位任务、COCO检测任务、COCO分割任务)。ResNet论文
网络结构
下图为残差神经网络的基本模块(专业术语叫残差学习单元),输入为x
,输出为F(x)+x
,F(x)
代表网络中数据的一系列乘、加操作,假设神经网络最优的拟合结果输出为H(x)=F(x)+x
,那么神经网络最优的F(x)
即为H(x)
与x
的残差,通过拟合残差来提升网络效果。为什么转变为拟合残差就比传统卷积网络要好呢?因为训练的时候至少可以保证残差为0,保证增加残差学习单元不会降低网络性能,假设一个浅层网络达到了饱和的准确率,后面再加上这个残差学习单元,起码误差不会增加。(可参考:ResNet详细解释)
通过不断堆叠这个基本模块,就可以得到最终的ResNet模型,理论上可以无限堆叠而不改变网络的性能。下图为一个34层的ResNet
网络:
网络特点
- 使得训练超级深的神经网络成为可能,避免了不断加深神经网络,准确率达到饱和的现象(后来将层数增加到1000层)。
- 输入可以直接连接到输出,使得整个网络只需要学习残差,简化学习目标和难度。
ResNet
是一个推广性非常好的网络结构,容易和其他网络结合。
参考资料
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)