[深度学习] 超参数设定和网络训练

超参数设定和网络训练

介绍一些重要的网络设计过程中的超参数设定技巧和训练技巧,如学习率,批规范化操作和网络优化化策略的选择。

网络超参数的设定

网络超参数设定在搭建整个网络架构之前,需首先指定与网络结构相关的各项超参数:输入图像像素,卷积层个数,卷积核相关参数。

输入数据像素大小

使用卷积神经网络处理图像问题时,对不同输入图像为得到同规格输出,同时便于GPU运行,会将图像压缩到 2 2 大小。一些经典的案例例如:CIFAR-10 数据 32 × 32 像素,STL数据集的96 × 96像素。另外如果不考虑硬件设备限制(通常是GPU显存大小),更高分辨率的图像一般有利于网络性能提升更为显著。此外需要指出,由于一般卷积神经网络采用全连接层作为最后分类层,若直接改变原始网络模型的输入图像分辨率,会导致原始模型卷积层的最终输出无法输入全连接层的状况,此时要重新改变全连接层输入滤波器大小或重新指定其他相关参数。

卷积层参数的设定

卷积层的超参数主要包括卷积核大小卷积操作的步长卷积核个数。关于卷积核大小,小卷积相比大卷积的优势:
1. 增加网络的容量和模型复杂程度
2. 减少卷积参数个数
因此实践中推荐使用 3 × 3 及 5 × 5 这样的小卷积核,其对应的卷积操作步长设置为1
此外,卷积操作前还可以搭配填充操作(padding),该操作有两层功效
1. 可充分利用和处理输入图像,或输入数据的边缘信息
2. 搭配合适的卷积层参数可保持输出与输入同等大小,而避免随着网络的深度增加,输入大小的急剧减少。
通常来说,对卷积核大小 f * f, 步长为 1 的卷积操作,当 p =( f - 1 )/ 2 时,便可维持输出与原输入等大。

池化层参数

同卷积核大小类似,池化层的核大小一般也设定为比较小的值,如 2 * 2 , 3 * 3 等。常用的参数设定为2 * 2 , 池化步长为 2 。在此设定下,输出结果大小仅为输入数据长宽大小的 3 / 4。也就是说有 75% 的相应值被丢弃。这就起到了下采样的作用。为了不丢弃过多的输入相应而损失网络性能,池化操作极少使用超过 3 * 3 大小的池化操作。

训练技巧

训练数据随机打乱

在训练卷积神经网络时,尽管训练数据固定,但由于采用了随机批处理的训练机制,因此我们可在模型每轮训练进行前将训练数据随机打乱,以确保模型不同轮次相同批次看到的数据是不同的。这样的处理不仅会提高模型的收敛速度,而且,相对固定次序的训练模型,此操作会略微提升模型在测试集上的预测结果。

学习率的设定

训练模型时另一关键设定便是模型学习率,一个理想的学习率会促进模型收敛,而不理想的学习率甚至会导致模型直接损失函数损失值爆炸无法完成训练,学习率的设定可遵循以下原则:
1. 模型训练开始时初始学习率不宜过大,以0.01, 0.001为宜如果发现开始训练没几个轮次模型目标损失值就急剧上升,这说明模型训练学习率过大,此时应该减小学习率从头训练。
2. 学习率应该随着轮次增加而减缓,减缓机制可有不同,一般为如下三种方式:
1)轮数减缓。如前五轮学习率减半,下一个五轮再减半。
2)指数减缓,即学习率按训练轮次增长指数插值递减,在matlab中可指定20轮每轮学习率为 lr = logspace(1e-2, 1e-5, 20) 3) 分数减缓 如果原始的学习率为 l 0 , 学习率按照下式递减, l r = l 0 / (1 + k t ) , k 为超参数用来控制学习率减缓幅度,t 为训练轮数。
可使用模型训练曲线来判断当前学习率是否合适。
1. 如果模型损失值在模型训练开始的几个批次直接爆炸,则学习率太大, 此时应该大幅减小学习率从头开始训练
2. 若模型一开始损失值下降明显,但后劲不足(绿色线)此时应使用较小学习率从头开始训练,或在后几轮改小学习率仅重新训练几轮即可。
3. 若模型损失值一直下降缓慢,(蓝色线)此时应稍微增大学习率,后继续观察训练曲线
学习率

批规范化操作(batch normalization)

BN 不仅加快了模型收敛速度,而且更重要的是在一定程度上缓解了深层网络的一个难题“梯度弥散”,从而使得训练深层网络模型更加稳定和容易。
批规范化的流程:
这里写图片描述

批规范化就是在模型每次随机梯度下降训练时,通过mini-batch来对相应的网络响应做规范化操作,使得结果(输出信号和各个维度)的均值为0,方差为1。
BN 分为 4 步:
前两步分别计算批处理的数据的均值和方差,第三步则根据计算的均值和方差对该批数据做规范化,而最后的 “尺度变换和偏移” 操作则是为了让训练所需而“刻意”加入的BN能够有可能还原最初的输入( γ = V a r ( x i ) = α B β = E ( x i ) = μ B 时),从而保持整个网络的容量。
BN奏效原因:
首先要说一下“内部协变量偏移”(internal covariate shift)。在统计学习中有一个经典的假设是“源空间”(source domain)和目标空间(target domain)的数据分布(distribution)是一致的。如果不一致那么就出现了新的机器学习问题,如迁移学习等。而协变量偏移就是分布不一致假设下的一个分支问题。他是指源空间和目标空间的条件概率是一致的,但是其边缘概率不同。即对于所有x属于X, P s (Y|X=x) = P t (Y|X=x), 但是 P s (x) != P t (x)。
条件概率:在X=x的条件下,Y发生的概率
边缘概率:x发生的概率

的确对于神经网络各层的输出,由于它经过了层内操作作用,其分布显然与各层对应的输入信号分布不同,而且差异会随着网络深度越来越大,不过他们所指示的样本标记(label)仍然不变,这便符合协变量偏移的定义。
Google研究员发现,可通过 BN 来规范化某些层或所有层的输入,从而可固定每层输入信号的均值与方差。这样一来,即使网络模型较深层的相应或梯度很小,也可通过BN的规范化将其尺度放大,以便可解决深层网络训练可能带来的“梯度弥散”问题。
举例:对一组很小的随机数做 l 2 规范化操作,这组随机数为
l 2 规范化操作:v <— v / ||v||2
v = [0.0066, 0.0004, 0.0085, 0.0093, 0.0068,0.0076, 0.0074, 0.0039, 0.0066, 0.0017]
在l2规范化之后
v’ =[0.3190, 0.0174, 0.4131, 0.4544, 0.3302, 0.3687, 0.3616, 0.1908, 0.3189, 0.0833]
现在在规范化之后,原本微小的数值其尺度被拉大了,试想未作规范化操作的那组随机数v就是反向传播的梯度信息,规范化自然可以起到梯度弥散效应。
BN一般用在非线性映射函数前,另外,如果神经网络训练时遇收敛速度较慢,或梯度爆炸等无法训练的情况可以尝试用BN来解决。

网络模型的优化算法选择

什么是优化算法

优化算法的功能就是改善训练方式,来最小化(最大化)损失函数
模型内部有些参数,是用来计算测试集中目标值 Y 的真实值和预测值的偏差,基于这些参数,就形成了损失函数E(x)。
比如说,权重( ω )和偏差(b)就是这样的内部参数,一般用于计算输出值,在训练神经网络模型时起到主要作用。
在有效地训练模型并产生准确结果时,模型的内部参数起到了非常重要的作用。这也是为什么我们应该用各种优化策略和算法,来更新和计算影响模型训练和模型输出的网络参数,使其逼近或达到最优值。
优化算法分为两大类:

一阶优化算法

这种算法使用各参数的梯度值来最小化或最大化损失函数,最常用的一阶优化算法是梯度下降。
函数梯度:导数 dy / dx 的多变量表达式,用来表示y相对于x的瞬时变化率。往往为了计算多变量函数的导数时,会用梯度取代导数,并使用偏导数来计算梯度。梯度和导数之间的一个主要区别是函数的梯度形成了一个向量场。
因此,对单变量函数,使用导数来分析;而梯度是基于多变量函数而产生的。更多理论细节在这里不再进行详细解释。

二阶优化算法

二阶优化算法使用了二阶导数(也叫做Hessian方法)来最小化或最大化损失函数。由于二阶导数的计算成本很高,所以这种方法并没有广泛使用。

深度卷积神经网络通常采用随机梯度下降类型的优化算法进行模型训练和参数求解。经过近些年相关领域的发展,出现了一系列有效的网络训练优化新算法。许多工具箱都提供了了这些优化算法,工程实践中只需要根据自身的任务的需求选择合适的优化算法即可。
以下介绍为了简化起见,我们假设待学习参数 ω ,学习率或步长为 η ,一阶梯度值为 g t 表示第t轮训练。

随机梯度下降法

经典的随机梯度下降法(Stochastic Gradient Descent,简称SGD)是神经网络训练的基本算法,即每次批处理训练时计算网络误差并作误差反向传播,后根据一阶梯度信息对参数进行更新,其更新策略可表示为:

ω t = ω t 1 η g

其中,一阶梯度信息 g 完全依赖与当前批数据在网络目标函数上的误差,故可以将学习率 η 理解为当前批的梯度对网络整体参数更新的影响程度。经典的随机梯度下降是最常见的神经网络优化方法,收敛效果稳定,不过收敛速度慢。

基于动量的随机梯度下降法

随机梯度下降算法是非常受欢迎的优化方法,但学习过程会有时很慢。动量方法旨在加速学习,特别是处理高曲率,小但一致的梯度或是带噪声的梯度。动量的方法积累了之前梯度指数级衰减的移动平均,并且沿着该方向移动。
这里写图片描述

上图为没有动量,下图为有动量,可以看出动量相当于在连续梯度指向相同方向时,加大步长。我们可以将梯度下降比喻成一个小球在冰上,每当它沿着表面最抖的部分下降时,它会累计继续在该方向上滑行的速度,直到其开始向上滑为止。在上滑时步长变小。
公式为:

v t = μ v t 1 η g

ω t = ω t 1 + v t

这个公式和SDG的区别其实就是加上了一个 μ v t 1
其中 μ 为动量因子,控制动量信息对整体梯度更新的影响程度,一般取值0.5, 0.9, 0.99。 基于动量的随机梯度下降算法除了可以抑制震荡,还可以在网络训练后期趋于收敛,网络参数在局部最小值附近来回震荡时帮助其跳出局部限制。
当其梯度指向实际移动方向时,动量项 v 增大;当梯度与实际移动方向相反时, v 减小。这种方式意味着动量项只对相关样本进行参数更新,减少了不必要的参数更新,从而得到更快且稳定的收敛,也减少了振荡过程。

Nesterov型动量随机下降法

Nesterov型动量随机梯度下降方法是在上述动量梯度下降法更新梯度时加入对当前梯度的校正。相比一般动量方法,Nesterov型动量法对于凸函数在收敛性上有更强的理论保证。同时,Nesterov型动量也有更好的表现。
自己理解:动量随机梯度下降法从公式上看应该只是对于连续梯度指向同一个方向时,加大步长。而Nesterov是不仅仅改变步长,而且还对梯度方向进行调整。

ω a h e a d = ω t 1 + μ v t 1

v t = μ v t 1 η ω a h e a d

ω t = ω t 1 + v t

Require:学习率η, 动量参数μ
Require:初始参数w,初始速度v
   while 没有达到停止条件准则 do
     从训练集中找m个样本X={x1,x2...xm}的小批量,对应目标yi
     应用临时更新: w' = w + μv
     计算梯度(在临时点)g = 1/m ▽w'
     计算速度更新: v =  μ*v- η*g
     应用更新:w = w + v

Adagrad

Adagrad 能独立地适应所有模型参数的学习率,缩放每个参数反比与其它所有梯度历史平方值总和的平方根。具有损失最大偏导的参数相应地有一个快速下降的学习率,而具有小偏导的参数在学习率上有相对较小的下降。净效果是在参数空间中更为平缓的倾斜方向会取得更大进步。
AdaGrad算法具有一些令人满意的理论性质。然而,经验上已经发现,对于训练神经网络模型而言,从训练开始累计梯度平方会导致有效的学习率过早和过量的减小。

Require:全局学习率η
Require:初始参数w
Require:小常数δ, 为了数值稳定大约设定为10^-7
  初始化梯度累计变量 r=0
  while 没有达到停止准则 do
    从训练集中采包含m个样本X={x1,x2...xm}的小批量,对应目标yi
    计算梯度(在临时点)g = 1/m ▽w'
    累积平方梯度: r = r + g*g (g 和 g逐元素相乘)
    计算更新 w' = η /+ sqrt(r))*g
    应用更新 w = w + w'
 end while

RMSProp

RMSProp改进了Adagrad在训练开始就累计梯度平方会导致有效的学习率过早和过量的减少。

Require:全局学习率η, 衰减速率ρ
Require:初始参数w
Require:小常数δ, 为了数值稳定大约设定为10^-6
  初始化梯度累计变量 r=0
  while 没有达到停止准则 do
    从训练集中采包含m个样本X={x1,x2...xm}的小批量,对应目标yi
    计算梯度(在临时点)g = 1/m ▽w'
    累积平方梯度: r = ρr + (1-ρ)g*g (g 和 g逐元素相乘)
    计算更新 w' = η /+ sqrt(r))*g
    应用更新 w = w + w'
 end while

RMSProp使用指数衰减平均以丢弃遥远过去的历史,使其能够找到凹碗之后快速收敛。

使用Nesterov动量的RMSProp算法

Require:全局学习率η, 衰减速率ρ, 动量系数μ
Require:初始参数w, 初始参数v
Require:小常数δ, 为了数值稳定大约设定为10^-6
  初始化梯度累计变量 r=0
  while 没有达到停止准则 do
    从训练集中采包含m个样本X={x1,x2...xm}的小批量,对应目标yi
    应用临时更新: w' = w + μv
    计算梯度(在临时点)g = 1/m ▽w'
    累积平方梯度: r = ρr + (1-ρ)g*g (g 和 g逐元素相乘)
    计算更新 w' = μ * v - η / (sqrt(r))*g
    应用更新 w = w + w'
 end while

Adam

Require: 步长η(默认为:0.001Require: 距估计的指数衰减速率,ρ1和ρ2在区间[0, 1)内,建议0.9 / 0.99
Require:用于数值稳定的小常数δ(建议默认为10^-8)
Require: 初始参数w
 初始化一阶和二阶矩变量 s=0, r=0
 初始化时间步t=0
 while没有达到停止准则 do
   从训练集中采包含m个样本X={x1,x2...xm}的小批量,对应目标yi
   计算梯度(在临时点)g <- 1/m ▽w'
   t <- t+1
   更新有偏一阶距估计: s <- ρ1*s + (1 - ρ1)g
   更新有偏二阶距估计: r <- ρ2*r + (1 - ρ2)g*g  (*表示点乘)
   更新一阶矩的偏差:s' <- s / (1 - ρ1(t))
   更新二阶矩的偏差:r' <- r / (1 - ρ2(t))
   计算更新:w' = -η * s' / ()sqrt(r')+δ)
   应用更新 w <- w + w'
 end while

微调神经网络

除了从头训练自己的网络之外,一种更加有效,高效的方法是微调已训练好的网络模型。微调预训练模型简单有效,就是用目标任务数据在原先预训练模型上继续进行训练过程。
1. 由于网络在原始数据集上已经收敛,因此应设置较小的学习率在目标数据上微调,如 10 4 数量级以下。
2. 卷积神经网络浅层拥有更泛化的特征(如边缘,纹理等),深层的特征则更抽象对应高层语义。因此,在新数据上微调时泛化特征更新可能或程度很小,高层语义特征更新可能程度较大,故可根据层神对不同层设置不同学习率:网络深层的学习率可稍大于浅层学习率
3. 根据目标任务数据与原始数据相似程度采用不同微调策略:
a) 当目标数据较少且目标数据与原始数据非常相似时,可仅微调网络靠近目标函数的后几层;
b) 当目标数据充足且相似时,可微调更多网络层,也可全部微调;
c) 当目标数据充足但与原始数据差异较大,此时须多调节一些网络层,直至微调全部;
d) 当目标数据极少,同时还与原始数据有较大差异时,这种情形比较麻烦,微调成功与否要具体 问题具体对待,不过仍可尝试首先微调网络后几层后再微调整个网络模型。

针对“当目标数据极少,同时还与原始数据有较大差异时”的情况,目前比较有效的方式是借助部分原始数据与目标数据协同训练。Ge和Yu提出,因预训练模型的浅层网络特征更具有泛化力,故可在浅层空间选择目标数据的近邻作为原始数据子集。之后,将微调阶段改为多任务学习(多任务学习就是有两个不同的任务,用同一个网络,同时生成两个结果):一者将目标任务基于原始数据子集,二者将目标任务基于全部目标数据。
这里写图片描述

参考文献

[1] 解析卷积神经网络——深度学习实践手册
[2] 深度学习(花书)

猜你喜欢

转载自blog.csdn.net/siyue0211/article/details/80292824