读《解析卷积神经网络》

《解析卷积神经网络–深度学习实践手册》 作者魏秀参


1.CNN基本部件

1.1 深度学习的“端到端”学习方式

深度学习的一个重要思想“端到端”的学习方式,属于表示学习的一种。其他机器学习算法,如特征选择算法、分类器算法、集成学习算法等,均假设样本特征表示是给定的,并在此基础上设计具体的机器学习算法。在深度学习时代之前,样本表示基本都使用人工特征,但是人工特征的优劣往往很大程度决定了最终的任务精度。而在深度学习普及之后,人工特征已逐渐被表示学习根据任务自动需求“学到”的特征表示所取代。

过去解决一个人工智能问题(以图像识别为例)往往通过分治法将其分解为预处理、特征提取与选择、分类器设计等若干步骤。子问题上的最优解并不意味着就能得到全局问题的最后解。深度学习为我们提供了另一种学习方式,即“端到端”学习方式,整个学习流程并不进行人为的子问题划分,而是完全交给深度学习模型直接学习从原始输入到期望输出的映射。

1.2 卷积层
卷积层是卷积神经网络中的基础操作,甚至在网络最后起分类作用的全连接层在工程实现时也是由卷积操作替代的。 卷积层有一个独特的特征:“权值共享”特征。
卷积操作的两个重要的超参数:卷积核大小(filter size)和卷积步长(stride)。

1.3 池化(pooling)层
文中翻译为汇合层。
通常使用的汇合操作为平均值汇合和最大值汇合,还有随机汇合介于二者之间。
汇合操作实际上就是一种“降采样”操作,另一方面,汇合也看成是一个用p-范数作为非线性映射的“卷积”操作,当p趋近正无穷时就是最常见的最大值汇合。
汇合层的引入是仿照人的视觉系统对视觉输入对象进行降维(降采样)和抽象。汇合层有以下三种功效:
1.特征不变性。汇合操作时模型更关注是否存在某些特征而不是特征具体的位置,使特征学习包含某种程度自由度,能容忍一些特征微小的位移。
2.特征降维。汇合相当于空间范围内做了维度约减,从而使模型可以抽取更广范围的特征。同时减小了下一层输入大小,进而减少计算量和参数个数。
3.在一定程度上防止过拟合,更方便优化。

汇合操作并不是CNN必须的元件或操作。

1.4 激活函数
激活函数的引入为的是增加整个网络的表达能力(即非线性)。
Sigmoid型函数将输出响应的值域被压缩到[0,1]之间,0对应了生物神经元的“抑制状态”,1则对应了“兴奋状态”。Sigmoid有一个严重的问题,即梯度的“饱和效应”。在输出值接近1时,梯度接近0,这会导致在误差反向传播过程中导数处于该区域的误差将很难甚至根本无法传递到前层,进而导致整个网络无法训练。
ReLU函数是目前深度卷积神经网络中最为常用的激活函数之一。ReLU函数的梯度在x>=0时为1,反之为0。对x>=0部分完全消除了Sigmoid型函数的梯度饱和效应。ReLU函数还有助于随机梯度下降方法收敛,收敛速度约快6倍左右。

1.5 全连接层
全连接层起到将学到的特征表示映射到样本的标记空间的作用。

1.6 目标函数
目标函数的作用是用来衡量该预测值与真实样本标记之间的误差。

2.CNN经典结构

  1. 感受野
    随着网络深度的加深,后层神经元在第一层输入层的感受野会随之增大。也就是说,小卷积核通过多层叠加可取得与大卷积核同等规模的感受野。
    小卷积核的优势:
    (1)由于小卷积核需要多层叠加,加深了网络深度进而增强了网络容量
    (2)增强网络容量的同时减少了参数个数

  2. 残差网络模型
    神经网络的深度和宽度是表征网络复杂度的两个核心因素,不过深度相比宽度在增加网络的复杂度方面更有效。然而,随着深度的增加,训练会变得愈加困难。这主要因为在基于随机梯度下降的网络训练过程中,误差信号的多层反向传播非常容易引发梯度“弥散”或者“爆炸”。一些特殊的权重初始化策略和批规范化(batch normalization)可以使这个问题得到极大的改善,但是效果有限。
    当深度网络收敛时,另外的问题又随之而来:随着继续增加网络的深度,训练数据的训练误差没有降低反而升高。残差网络很好的解决了这个问题。

3.卷积神经网络的压缩

按照压缩过程对网络结构的破坏程度,我们将模型压缩技术分为“前端压缩”与“后端压缩”两部分。所谓“前端压缩”,是指不改变原网络结构的压缩技术,主要包括知识蒸馏、紧凑的模型结构设计以及滤波器层面的剪枝等;而“后端压缩”则包括低秩近似、未加限制的剪枝、参数量化以及二值网络等,其目标在于尽可能地减少模型大小,因而会对原始网络结构造成极大程度的改造。

低秩近似、剪枝与参数量化作为常用的三种压缩技术,已经具备了较为明朗的应用前景;其他压缩技术,如二值网络、知识蒸馏等尚处于发展阶段。

  1. 低秩近似
    使用结构化矩阵来进行低秩分解的算法;也可以直接使用矩阵分解来降低权重矩阵的参数。低秩近似算法在中小型网络模型上取得了很不错的效果,但其超参数量与网络层数呈线性变化趋势,随着网络层数的增加与模型复杂度的提升,其搜索空间会急剧增大。

  2. 剪枝与稀疏约束
    给定一个预训练好的网络模型,常用的剪枝算法一般都遵从如下的操作流程:
    (1)衡量神经元的重要程度。衡量其重要程度的方法也是多种多样,从一些基本的启发式算法,到基于梯度的方案,其计算复杂度与最终的效果也是各有千秋。
    (2)移除掉一部分不重要的神经元。这里可以根据某个阈值来判断神经元是否可以被剪除,也可以按重要程度排序,剪除掉一定比例的神经元。一般而言,后者比前者更加简便,灵活性也更高。
    (3)对网络进行微调。由于剪枝操作会不可避免地影响网络的精度,为防止对分类性能造成过大的破坏,需要对剪枝后的模型进行微调。
    (4)返回第一步,进行下一轮剪枝

  3. 参数量化
    最简单也是最基本的一种量化算法便是标量量化。该算法的基本思路是,对于每一个权重矩阵,首先将其转化为向量形式。之后对该权重向量的元素进行 k 个簇的聚类,这可借助于经典的k均值聚类算法快速完成。如此一来,只需将 k 个聚类中心(标量)存储在码本之中便可,而原权重矩阵则只负责记录各自聚类中心在码本中的索引。

  4. 二值网络
    二值网络可以被视为量化方法的一种极端情况:所有参数的取值只能是±1。正是这种极端的设定,使得二值网络能够获得极大的压缩效益。

    首先,在普通的神经网络中,一个参数是由单精度浮点数来表示的,参数的二值化能将存储开销降低为原来的1/32。其次,如果中间结果也能二值化的话,那么所有的运算仅靠位操作便可完成。借助于同或门等逻辑门元件便能快速完成所有的计算。而这一优点是其余压缩方法所不能比拟的。深度神经网络的一大诟病就在于其巨大的计算代价,如果能够获得高准确度的二值网络,那么便可摆脱对GPU等高性能计算设备的依赖。

  5. 知识蒸馏
    在不改变模型复杂度的情况下,通过增加监督信息的丰富程度,带来性能上的提升。

  1. 紧凑的网络结构
    直接训练小模型。设计上不容易,依赖经验和技巧。随着参数数量的降低,网络的泛化性不一定能得到保障。

4.数据扩充

数据扩充是深度模型训练前的必须一步,此操作可扩充训练数据集,增强数据多样性,防止模型过拟合。
简单的数据扩充方式有:水平翻转,随机扣取,尺度变换,旋转等; 对原图或已变换的图像进行色彩抖动。
实践中,往往会将上述几种方式叠加使用,如此可将图像数据扩充至原有数据的数倍甚至数十倍。

特殊的数据扩充方式:

  1. Fancy PCA
  2. 监督式数据扩充

5.数据预处理

机器学习中, 对于输入特征做归一化预处理操作是常见的步骤。类似的,在图像处理中,图像的每个像素信息同样可以看做一种特征。在实践中,对每个特征减去平均值来中心化数据是非常重要的,这种归一化处理方式被称作“中心式归一化”(mean normalization)。
减均值操作的原理是,我们默认自然图像是一类平稳的数据分布(即数据每一个维度的统计都服从相同分布),此时,在每个样本上减去数据的统计平均值(逐样本计算)可以移除共同部分,凸显个体差异。
需要注意的是,在实际操作中应首先划分好训练集、验证集和测试集,而该均值仅针对划分后的训练集计算。不可直接在未划分的所有图像上计算均值,如此会违背机器学习基本原理,即“模型训练过程中能且仅能从训练数据中获取信息”。

6.网络参数初始化

理想的网络参数初始化使模型训练事半功倍,相反,糟糕的初始化方案不仅会影响网络收敛甚至会导致梯度弥散或爆炸致使训练失败。介绍几种目前实践中常用的几种网络参数初始化方式。

  1. 全零初始化
    当网络收敛到稳定状态时,参数(权值)在理想情况下应基本保持正负各半的状态(此时期望为 0)。因此,一种简单且听起来合理的参数初始化做法是,干脆将所有参数都初始化为0,因为这样可使得初始化全零时参数的期望与网络稳定时参数的期望一致为零。

    不过,细细想来则会发现参数全为0时网络不同神经元的输出必然相同,相同输出则导致梯度更新完全一样,这样便会令更新后的参数仍然保持一样的状态。换句话说,如若参数进行了全零初始化,那么网络神经元将毫无能力对此做出改变,从而无法进行模型训练。

  2. 随机初始化

    将参数随机化自然是打破上述“僵局”的一个有效手段,不过我们仍然希望所有参数期望依旧接近0。遵循这一原则,我们可将参数值随机设定为接近0的一个很小的随机数(有正有负)。在实际应用中,随机参数服从高斯分布或均匀分布都是较有效的初始化方式。还有一个问题,网络输出数据分布的方差会随着输入神经元个数改变。所以会在初始化的同时加上方差大小的规范化。

  3. 其他初始化方法

    利用预训练模型—-将预训练模型的参数作为新任务上模型的参数初始化。

7.激活函数

激活函数又称为“非线性映射函数”。以下将介绍七种当下深度卷积神经网络中常用的激活函数:
1.Sigmoid型函数

Sigmoid型函数值域的均值并非为0而是全为正,这样的结果实际上并不符合我们队神经网络内数值的期望(均值)应为0的设想。

2.tanh(x)型函数

tanh(x)型函数是在Sigmoid型函数基础上为解决均值问题提出的激活函数。tanh(x)型函数又称作双曲正切函数,其函数范围是(-1,+1),输出响应的均值为0。但是tanh(x)型函数仍基于Sigmoid型函数,依然会发生“梯度饱和”现象。

3.修正线性单元(ReLU)

ReLU函数是目前深度卷积神经网络中最为常用的激活函数之一。
对 x ≥ 0 部分完全消除了Sigmoid型函数的梯度饱和效应。但是也存在缺陷,即在 x < 0 时,梯度便为0。对于小于0的这部分卷积结果响应,它们一旦变为负值将再无法影响网络训练——这种现象被称作“死区”。

4.Leaky ReLU
为了缓解“死区”现象,研究者将ReLU函数中 x < 0 的部分调整为 f(x) = α·x, 其中 α 为 0.01或0.001数量级的较小正数。

原始的ReLU函数实际上是Leaky ReLU函数的一个特例。不过由于Leaky ReLU中 α 为超参数,合适的值较难设定且较为敏感,因此Leaky ReLU函数在实际使用中的性能并不十分稳定。

5.参数化ReLU
参数化ReLU的提出很好的解决了Leaky ReLU中超参数 α 不易设定的问题:参数化ReLU直接将 α 也作为一个网络中可学习的变量融入模型的整体训练过程。
参数化ReLU在带来更大自由度的同时,也增加了网络模型过拟合的风险,在实际使用中需格外注意。

6.随机化ReLU
另一种解决 α 超参设定的方式是将其随机化,这便是随机化ReLU。

7.指数化线性单元(ELU)

ELU具备ReLU函数的优点, 同时ELU也解决了ReLU函数自身的“死区”问题。不过,ELU函数中的指数操作稍稍增大了计算量。实际使用中,ELU中的超参数 λ 一般设置为1。

8.目标函数

  1. 交叉熵损失函数
    又称为Softmax损失函数,是目前卷积神经网络中最常用的分类目标函数,通过指数化变换使网络输出h转换为概率形式。

  2. 合页损失函数
    在SVM中被广泛使用。

    一般情况的分类任务中,交叉熵损失函数的分类效果略优于合页损失函数的分类效果。

  3. 坡道损失函数

  4. 大间隔交叉熵损失函数
  5. 中心损失函数

总结:
交叉熵损失函数是最为常用的分类目标函数,且效果一般优于合页损失函数;
大间隔损失函数和中心损失函数从增大类间距离、减小类内距离的角度不仅要求分类准确,而且还有助提高特征的分辨能力;
坡道损失函数是分类问题目标函数中的一类非凸损失函数,由于其良好的抗噪特性,推荐将其用于样本噪声或离群点较多的分类任务。

9.网络正则化

机器学习的一个核心问题是如何使学习算法不仅在训练样本上表现良好,并且在新数据或测试集上同样奏效,学习算法在新数据上的这样一种表现我们称之为模型的“泛化能力”。若某学习算法在训练集表现优异,同时在测试集依然表现良好,可以说该学习算法有较强泛化能力。

1.L2正则化
L2正则化方式在深度学习中有个常用的叫法是“权重衰减”, 另外L2正则化在机器学习中还被称作“岭回归”或Tikhonov正则化。

2.L1正则化
需注意,L1正则化除了同L2正则化一样能约束参数量级外,L1正则化还能起到使参数更稀疏的作用。稀疏化的结果使优化后的参数一部分为 ,另一部分为非零实值。非零实值的那部分参数可起到选择重要参数或特征维度的作用, 同时可起到去除噪声的效果。

3.最大范数约束
最大范数约束是通过向参数量级的范数设置上限对网络进行正则化的手段。

4.dropout(随机失活)
随机失活的提出正是一定程度上缓解了神经元之间复杂的协同适应,降低了神经元间依赖,避免了网络过拟合的发生。其原理非常简单:对于某层的每个神经元,在训练阶段均以概率 p 随机将该神经元权重置0(故被称作“随机失活”),测试阶段所有神经元均呈激活态,但其权重需乘 (1 − p) 以保证训练和测试阶段各自权重拥有相同的期望。

由于失活的神经元无法参与到网络训练,因此每次训练(前向操作和反向操作)时相当于面对一个全新网络。以含两层网络、各层有三个神经元的简单神经网络为例,若每层随机失活一个神经元,该网络共可产生9种子网络。根据上述随机失活原理,训练阶段相当于共训练了9个子网络,测试阶段则相当于9个子网络的平均集成。

5.验证集的使用
借助验证集对网络训练“早停”是一种有效的防止网络过拟合方法。

10.超参数设定和网络训练

  1. 输入数据像素大小
    统一将图像压缩到2^n大小,便于GPU设备并行。

  2. 卷积层参数的设定
    包括卷积核大小、卷积操作的步长和卷积核个数。
    实践中推荐使用3 3以及 5 5,其对应卷积操作步长为1。
    为了硬件字节级存储管理的方便,卷积核个数通常设置为2 的次幂,如64,128,512等。

  3. 汇合层参数的设定
    常用的参数设定为2 2、汇合步长为2,起到“降采样”的作用。为了不丢弃过多输入相应而损失网络性能,汇合操作极少使用超过3 3大小的汇合操作。

训练技巧

  1. 训练数据随机打乱
    在训练卷积神经网络时,尽管训练数据固定,但由于采用了随机批处理(mini-batch)的训练机制,因此我们可在模型每轮(epoch)训练进行前将训练数据集随机打乱(shuffle),确保模型不同轮数相同批次“看到”的数据是不同的。
  2. 学习率的设定
    (1)模型训练开始时的初始学习率不宜过大,以0.01和0.001为宜
    (2)模型训练过程中,学习率应随轮数增加而减缓。也可以分为,轮数减缓、指数减缓、分数减缓。
  3. 批规范操作(BN)
    在模型每次随机梯度下降训练时,通过mini-batch来对相应的网络响应做规范化操作,使得结果(输出信号各个维度)的均值为0,方差为1。算法如下:

    BN奏效的原因:在统计机器学习中的一个经典假设是“源空间和目标空间的数据分布是一致的”。如果不一致,那么就出现了新的机器学习问题,如迁移学习等。通过BN来规范化某些层或所有层的输入,从而可以固定每层输入信号的均值与方差。这样一来,即使网络模型较深层的响应或梯度很小,也可通过BM的规范化作用将其的尺度变大,以此便可解决深层网络训练很可能带来的“梯度弥散” 问题。

  4. 网络模型优化算法选择
    (1)随机梯度下降法。经典的随机梯度下降是最常见的神经网络优化方法,收敛效果较稳定,不过收敛速度过慢。
    (2)基于动量的随机梯度下降法。
    (3)Nesterov型动量随机下降法。
    (4)Adagrad法。
    (5)Adadelta法。
    (6)RMSProp法。
    (7)Adam法。
  5. 微调神经网络
    微调预训练模型简单来说,就是用目标任务数据在原先预训练模型上继续进行训练过程。微调预训练模型时,需注意学习率调整和原始数据与目标数据的关系。另外,还可使用“多目标学习框架”对预训练模型进行微调。

后面的几章涉及到的都是基础内容,就不做过多介绍。