写点什么

深度学习基础入门篇 [六]:模型调优,学习率设置(Warm Up、loss 自适应衰减等),batch size 调优技巧,基于方差放缩初始化方法。

作者:汀丶
  • 2023-04-20
    浙江
  • 本文字数:9337 字

    阅读完需:约 31 分钟

深度学习基础入门篇[六]:模型调优,学习率设置(Warm Up、loss自适应衰减等),batch size调优技巧,基于方差放缩初始化方法。

1.学习率

学习率是训练神经网络的重要超参数之一,它代表在每一次迭代中梯度向损失函数最优解移动的步长,通常用表示。它的大小决定网络学习速度的快慢。在网络训练过程中,模型通过样本数据给出预测值,计算代价函数并通过反向传播来调整参数。重复上述过程,使得模型参数逐步趋于最优解从而获得最优模型。在这个过程中,学习率负责控制每一步参数更新的步长。合适的学习率可以使代价函数以合适的速度收敛到最小值。

1.1 学习率对网络的影响

梯度更新公式:


根据上述公式我们可以看到,如果学习率较大,那么参数的更新速度就会很快,可以加快网络的收敛速度,但如果学习率过大,可能会导致参数在最优解附近震荡,代价函数难以收敛,甚至可能会错过最优解,导致参数向错误的方向更新,代价函数不仅不收敛反而可能爆炸(如图 1a 所示)。如果学习率较小,网络可能不会错过最优点,但是网络学习速度会变慢。同时,如果学习率过小,则很可能会陷入局部最优点(如图 1b 所示)。因此,只有找到合适的学习率,才能保证代价函数以较快的速度逼近全局最优解。


1.2 学习率的设置

我们了解了只有合适的学习率才能保证网络稳定学习的同时,又以合理的高速收敛来减少训练时间。那么,如何设置学习率呢?**通常的,在训练网络的前期过程中,会选取一个相对较大的学习率以加快网络的收敛速度。而随着迭代优化的次数增多,逐步减小学习率,以保证最终收敛至全局最优解,而不是在其附近震荡或爆炸**。下面将介绍几种常用的学习率衰减方法,包括:分段常数衰减、指数衰减、自然指数衰减、多项式衰减、间隔衰减、多间隔衰减、逆时间衰减、Lambda 衰减、余弦衰减、诺姆衰减、loss 自适应衰减、线性学习率热身等。

1.2.1 分段常数衰减(Piecewise Decay)

在不同的学习阶段指定不同的学习率,在每段内学习率相同。该过程可以举例说明为:


boundaries = [100, 200]  # 指定学习率改变的边界点为100和200values = [1.0, 0.5, 0.1] # 指定不同区间下的学习率大小
learning_rate = 1.0 if epoch < 100 learning_rate = 0.5 if 100 <= epoch < 200learning_rate = 0.1 if epoch >= 200
复制代码

1.2.2 指数衰减(Exponential Decay)

学习率随训练轮数成指数衰减,每次将当前学习率乘以给定的衰减率得到下一个学习率。指数衰减的公式可表示为:


其中,gamma 为衰减率。

1.2.3 自然指数衰减 (Natural Exponential Decay)

每次将当前学习率乘以给定的衰减率的自然指数得到下一个学习率。其公式表达为:


$\textit{new_learning_rate}=\textit{learning_rate}e^{-gammaepoch}$


其中,learning_rate 为初始学习率,gamma 为衰减率,epoch 为训练轮数。

1.2.4 多项式衰减(Polynomial Decay)

通过多项式衰减函数,学习率从初始值逐渐衰减至最低学习率。其中,参数 cycle 表学习率下降后是否重新上升。若 cycle=True,则学习率衰减至最低后会重新上升到一定值,再降低至最低学习率并进行循环。若 cycle=False,则学习率从初始值单调递减至最低值。


  • 若 cycle=True,其计算公式为:


  • 若 cycle=False,其计算公式为:


其中,learning_rate 为初始学习率,decay_step 为进行衰减的步长,end_lr 为最低学习率,power 为多项式的幂。

1.2.5 间隔衰减 (Step Decay)

学习率按照指定的轮数间隔进行衰减,该过程可举例说明为:


learning_rate = 0.5 # 学习率初始值step_size = 30      # 每训练30个epoch进行一次衰减gamma = 0.1         # 衰减率

learning_rate = 0.5 if epoch < 30 learning_rate = 0.05 if 30 <= epoch < 60learning_rate = 0.005 if 60 <= epoch < 90
复制代码

1.2.6 多间隔衰减(Multi Step Decay)

学习率按特定间隔进行衰减,与间隔衰减的区别在于:间隔衰减的 epoch 间隔是单一且固定的,而多间隔衰减中的 epoch 间隔是预先指定的多间隔。该过程可举例说明为:


learning_rate = 0.5    # 学习率初始值milestones = [30, 50]  # 指定轮数间隔gamma = 0.1            # 衰减率
learning_rate = 0.5 if epoch < 30learning_rate = 0.05 if 30 <= epoch < 50learning_rate = 0.005 if 50 <= epoch...
复制代码

1.2.7 逆时间衰减(Inverse Time Decay)

学习率大小与当前衰减次数成反比。其计算公式如下:


其中,learning_rate 为初始学习率,gamma 为衰减率,epoch 为训练轮数。

1.2.8 Lambda 衰减(Lambda Decay)

使用 lambda 函数来设置学习率,其中 lambda 函数通过 epoch 计算出一个因子,使用该因子乘以初始学习率。该衰减过程可参考如下例子:


learning_rate = 0.5                      # 学习率初始值lr_lambda = lambda epoch: 0.95 ** epoch  # 定义lambda函数
learning_rate = 0.5 # 当epoch = 0时,0.5 * 0.95 ** 0 = 0.5learning_rate = 0.475 # 当epoch = 1时,0.5 * 0.95 ** 1 = 0.475learning_rate = 0.45125 # 当epoch = 2时,0.5 * 0.95 ** 2 = 0.45125...
复制代码

1.2.9 余弦衰减(Cosine Annealing Decay)

使用 cosine annealing 的策略来动态调整学习率,学习率随 step 数变化成余弦函数周期变化。该方法为论文 SGDR:Stochastic Gradient Descent with Warm Restarts 中 cosine annealing 动态学习率。学习率调整公式为


\eta_t=\eta_{min}+\dfrac{1}{2}(\eta_{max}-\eta_{min})(1+cos(\dfrac{T_{car}}{T_{max}}\pi)),\quad T_{car}\neq(2k+1)T_{max}

\eta_{t+1}=\eta_t+\dfrac{1}{2}(\eta_{max}-\eta_{min})(1-cos(\dfrac{1}{T_{max}}\pi)),\quad T_{car}=(2k+1)T_{max}
复制代码

1.2.10 诺姆衰减(Noam Decay)

诺姆衰减的计算方式如下:


其中,代表模型的输入、输出向量特征维度,warmup_steps 为预热步数,learning_rate 为初始学习率。更多细节请参考 attention is all you need

1.2.11 loss 自适应衰减(Reduce On Plateau)

当 loss 停止下降时,降低学习率。其思想是:一旦模型表现不再提升,将学习率降低 2-10 倍对模型的训练往往有益。此外,每降低一次学习率后,将会进入一个冷静期。在冷静期内不会监控 loss 变化也不会进行衰减。当冷静期结束后,会继续监控 loss 的上升或下降。

1.2.12 线性学习率热身(Linear Warm Up) 用的比较多

线性学习率热身是一种学习率优化策略,在正常调整学习率前,先逐步增大学习率。


当训练步数小于热身步数(warmup_steps)时,学习率 按如下方式更新:


当训练步数大于等于热身步数(warmup_steps)时,学习率为:


其中,lr 为热身之后的学习率,start_lr 为学习率初始值,end_lr 为最终学习率,epoch 为训练轮数。

2.batch size

2.1 什么是 BatchSize

  • Batch 一般被翻译为批量,设置 batch_size 的目的让模型在训练过程中每次选择批量的数据来进行处理。Batch Size 的直观理解就是一次训练所选取的样本数

  • Batch Size 的大小影响模型的优化程度和速度。同时其直接影响到 GPU 内存的使用情况,假如你 GPU 内存不大,该数值最好设置小一点。


在神经网络的训练过程中,一个非常直观的需要调整的超参数就是 batch size。我们需要决定在一次训练中,要选取多少样本喂给神经网络,这个要选择的样本个数,就是 batch size。batch size 的可取值范围为 1 到全体样本数。举个例子,


  • 传统的梯度下降法(Gradient Descent)就是采用了全部样本来进行训练和梯度更新,

  • 它的变体随机梯度下降法(stochastic gradient descent),则设定 batch size 为 1,即每次只将一个样本喂给神经网络,

  • 在 mini-batch 梯度下降法中,则采用了一个折中的方法,每次选择一部分数据用于训练

2.2 batch size 对网络的影响

  • 在没有使用 Batch Size 之前,这意味着网络在训练时,是一次把所有的数据(整个数据库)输入网络中,然后计算它们的梯度进行反向传播,由于在计算梯度时使用了整个数据库,所以计算得到的梯度方向更为准确。但在这情况下,计算得到不同梯度值差别巨大,难以使用一个全局的学习率,所以这时一般使用 Rprop 这种基于梯度符号的训练算法,单独进行梯度更新。

  • 在小样本数的数据库中,不使用 Batch Size 是可行的,而且效果也很好。但是一旦是大型的数据库,一次性把所有数据输进网络,肯定会引起内存的爆炸。所以就提出 Batch Size 的概念。


  1. 当采取传统的梯度下降法时,神经网络每一次训练都会使用全部数据。梯度基于全样本计算,因此会很准确。对于凸问题,局部最优即为全局最优的情况下,准确的梯度计算可以使梯度更新朝着正确的方向进行,以较快的速度达到全局最优解。但在真实的神经网络训练过程中,我们通常遇到的都是非凸问题,此时,局部最优解不是全局最优解,而传统的梯度下降法在这种情况下很容易陷入局部最优点或鞍点。同时,当整体样本数不大时,采用全体样本做 batch size 不会非常耗时,而当样本数很大时,每一次的计算将会非常耗时,也会导致内存爆炸。

  2. 当采取随机梯度下降法时,batch size 值为 1,每次获得的梯度都是根据当前的随机样本计算得来。由一个样本的梯度来近似所有的样本,会导致梯度估计不是很准确。同时,梯度易收到极端值的影响,导致损失剧烈震荡。但因为 batch size 为 1,随机梯度下降法的计算速度会非常快。

  3. 如果选取比较折中的 batch size 作为 mini-batch 来进行随机梯度下降,其优点是用部分样本来近似全部样本,梯度相对于 batch size 为 1 更为准确,同时相比与使用全部样本,计算量减小,计算速度和收敛速度都会得到提升。看到这里可能会有一个疑问,为什么 10000 样本训练 1 次会比 100 样本训练 100 次收敛慢呢?我们假设样本真实的标准差为,则 n 个样本均值的标准差为,表明使用更多样本来估计梯度的方法回报是低于线性的。10000 个样本训练一次和 100 个样本训练一次,由于计算量是线性的,前者的计算量是后者的 100 倍,但均值标准差只比后者降低了 10 倍,那么在相同的计算量下(同样训练 10000 个样本),小样本的收敛速度是远快于使用整个样本集的。同时,相对于训练全部样本,由于梯度存在不准确性,噪声的影响很可能会让梯度下降的过程中离开局部最优点或鞍点,从而有机会寻找全局最优点。

2.3 如何设置 Batch_Size 的值?

更大的 batch size 会得到更精确的梯度估计值,但其估计梯度的回报是低于线性的。如果训练集较小,可以直接使用梯度下降法,batch size 等于样本集大小。


设置 BatchSize 要注意一下几点:


     1)batch 数太小,而类别又比较多的时候,真的可能会导致 loss 函数震荡而不收敛,尤其是在你的网络比较复杂的时候。


     2)随着 batchsize 增大,处理相同的数据量的速度越快。


     3)随着 batchsize 增大,达到相同精度所需要的 epoch 数量越来越多。


     4)由于上述两种因素的矛盾, Batch_Size 增大到某个时候,达到时间上的最优。


     5)由于最终收敛精度会陷入不同的局部极值,因此 Batch_Size 增大到某些时候,达到最终收敛精度上的最优。


     6)过大的 batchsize 的结果是网络很容易收敛到一些不好的局部最优点。同样太小的 batch 也存在一些问题,比如训练速度很慢,训练不容易收敛等。


     7)具体的 batch size 的选取和训练集的样本数目相关。


     8)GPU 对 2 的幂次的 batch 可以发挥更佳的性能,因此设置成 16、32、64、128…时往往要比设置为整 10、整 100 的倍数时表现更优,Deep Learning 书中提到,在某些硬件上使用特定大小的数组时,运行时间会更少。尤其是在使用 GPU 时,通常使用 2 的幂数作为 batch size 可以获得更少的运行时间。


    我在设置 BatchSize 的时候,首先选择大点的 BatchSize 把 GPU 占满,观察 Loss 收敛的情况,如果不收敛,或者收敛效果不好则降低 BatchSize,一般常用 16,32,64 等。

2.3.1 在合理范围内,增大 Batch_Size 有何好处?

  • 内存利用率提高了,大矩阵乘法的并行化效率提高。

  • 跑完一次 epoch(全数据集)所需的迭代次数减少,对于相同数据量的处理速度进一步加快。

  • 在一定范围内,一般来说 Batch_Size 越大,其确定的下降方向越准,引起训练震荡越小。

2.3.2 盲目增大 Batch_Size 有何坏处?

  • 内存利用率提高了,但是内存容量可能撑不住了。

  • 跑完一次 epoch(全数据集)所需的迭代次数减少,要想达到相同的精度,其所花费的时间大大增加了,从而对参数的修正也就显得更加缓慢。

  • Batch_Size 增大到一定程度,其确定的下降方向已经基本不再变化。

2.3.3 调节 Batch_Size 对训练效果影响到底如何?

  • Batch_Size 太小,模型表现效果极其糟糕(error 飙升)。

  • 随着 Batch_Size 增大,处理相同数据量的速度越快。

  • 随着 Batch_Size 增大,达到相同精度所需要的 epoch 数量越来越多。

  • 由于上述两种因素的矛盾, Batch_Size 增大到某个时候,达到时间上的最优。

  • 由于最终收敛精度会陷入不同的局部极值,因此 Batch_Size 增大到某些时候,达到最终收敛精度上的最优

  • batchsize 过小:每次计算的梯度不稳定,引起训练的震荡比较大,很难收敛。


batchsize 过大优点:


  • (1)提高了内存利用率,大矩阵乘法并行计算效率提高。

  • (2)计算的梯度方向比较准,引起的训练的震荡比较小。

  • (3)跑完一次 epoch 所需要的迭代次数变小,相同数据量的数据处理速度加快。


batchsize 过大缺点:


  • 容易内容溢出,想要达到相同精度,epoch 会越来越大,容易陷入局部最优,泛化性能差。


batchsize 设置:通常 10 到 100,一般设置为 2 的 n 次方。


原因:计算机的 gpu 和 cpu 的 memory 都是 2 进制方式存储的,设置 2 的 n 次方可以加快计算速度。


深度学习中经常看到 epoch、 iteration 和 batchsize 这三个的区别:


  1. batchsize:批大小。在深度学习中,一般采用 SGD 训练,即每次训练在训练集中取 batchsize 个样本训练;

  2. iteration:1 个 iteration 等于使用 batchsize 个样本训练一次;

  3. epoch:1 个 epoch 等于使用训练集中的全部样本训练一次;


举个例子,训练集有 1000 个样本,batchsize=10,那么训练完整个样本集需要:100 次 iteration,1 次 epoch。


1.当数据量足够大的时候可以适当的减小 batch_size,由于数据量太大,内存不够。但盲目减少会导致无法收敛,batch_size=1 时为在线学习,也是标准的 SGD,这样学习,如果数据量不大,noise 数据存在时,模型容易被 noise 带偏,如果数据量足够大,noise 的影响会被“冲淡”,对模型几乎不影响。


2.batch 的选择,首先决定的是下降方向,如果数据集比较小,则完全可以采用全数据集的形式。这样做的好处有两点,


1)全数据集的方向能够更好的代表样本总体,确定其极值所在。


2)由于不同权重的梯度值差别巨大,因此选取一个全局的学习率很困难。

3.参数初始化

在我们开始训练神经网络之前,首先要做的是给网络中的每一个权重和偏置赋值,这个赋值的过程就是参数初始化。合理的初始化可以缩短神经网络的训练时间,而不合理的初始化可能使网络难以收敛。那么,我们要如何对参数进行初始化呢?或许你有想到过将全部参数都设置为 0,这看起来是一个简单又方便的办法,但遗憾的是神经网络中不能对权重进行全零初始化。在讨论如何对参数进行初始化前,我们先来看看为什么不能进行全零初始化。

为什么不能全零初始化?

以一个三层网络为例,假设其具体的网络示意图如图 1 所示。


其中,可表达为:


由于权重和偏置的初始值都为 0,且同一层网络的激活函数相同,则有:


对于神经网络的最终输出 ,我们可以得到:


其中,为第三层网络的激活函数。


假设真实值为 y, 损失函数为 ,根据反向传播算法和链式法则,我们可以得到:


同样地:


由于 ,则有:


权重更新表达式为:


$\begin{array}{c}w'{47}=w{47}+\Delta w\ w'{57}=w{57}+\Delta w\ w'{67}=w{67}+\Delta w\end{array}$


由于 的初始值均为 0,那么:,同理:。由此可见,更新后的参数在每一层内都是相同的。同时,无论经过多少次网络训练,相同网络层内的参数值都是相同的,这会导致网络在学习时没有重点,对所有的特征处理相同,这很可能导致模型无法收敛训练失败。这种现象被称为对称失效。

3. 常见的初始化方法

3.1 基于固定方差的参数初始化

一种非常常见的方式是采用高斯分布或均匀分布来对权重进行随机初始化。高斯分布和均匀分布的选择似乎没有很大差别,但初始分布的大小对于优化过程的结果和网络泛化能力都有很大影响。


高斯分布初始化:使用一个均值为,方差为 的高斯分布 N(μ,σ2)对每个参数进行随机初始化,通常情况下,μ=0,并对生成的数乘上一个小数,把权重初始化为很小的随机数。比如:,这里选择乘以 0.01 初始化为一个很小的数是因为,如果最初随机到的 w 值很大,当我们选择 sigmoid 或 tanh 激活函数时,函数值 会停留在一个很平坦的地方,激活值接近饱和,导致梯度下降时,梯度很小,学习变得缓慢。但也不是说权重值越小越好,如果权重值过小,会导致在反向传播时计算得到很小的梯度值,在不断的反向传播过程中,引起梯度消失。


均匀分布初始化:在一个给定区间 [−r,r]内采取均匀分布进行初始化。假设随机变量在区间 [a,b]内均匀分布,则其方差为 。因此,当在 [−r,r]的区间内均匀分布采样,并满足 时,则有


上述两种基于固定方差的初始随机化方法中,关键点在于如何设置方差过大或过小的方差都会导致梯度下降缓慢,网络训练效果不好等问题。为了降低固定方差对网络性能及优化效率的影响,基于固定方差的随机初始化一般要配合逐层归一化来使用。

3.2 基于方差缩放的参数初始化

方差缩放方法能够根据神经元的链接数量来自适应地调整初始化分布地方差,尽可能的保证每个神经元的输入和输出方差一致。那么,为什么要保证前后方差的一致性呢?这是因为如果输入空间和输出空间的方差差别较大,也就是说数据空间分布差异较大,那么在反向传播时可能会引起梯度消失或爆炸问题。比如,当输入空间稀疏,输出空间稠密时,将在输出空间计算得到的误差反向传播给输入空间时,这个误差可能会显得微不足道,从而引起梯度消失。而当输入空间稠密,输出空间稀疏时,将误差反向传播给输入空间,就可能会引起梯度爆炸,使得模型震荡。

3.2.1 Xavier 初始化

Xavier 初始化的提出,遵循了 Bradley(2009)的理论环境,假设网络中的每一层的激活函数都是关于 0 对称的线性激活函数,权重间的初始化和输入特征相互独立,且均值都为 0。


假设在一个神经网络中,对于一层线性网络,其表示为:


代表该层网络的第 i 个神经元,y 为该层网络的输出,为本层网络的权重,b 为偏置,为激活函数。这里我们假设激活函数为恒等函数,即 f(x)=x,导数为 1。


对于其中的每个 ,其方差为:


由于 的均值都为 0,因此可以得到:


又因为 相互独立,则有:


其中,代表第 i 层的神经元数量。


通过上面的公式我们可以发现,输入 的方差和输出 y 方差相差 倍,也就是说输入信号在经过神经元后会被放大或缩小倍。为保证经过多层网络后,信号不被过分的放大或缩小,我们需要尽可能保证前向传播和反向传播时每层方差保持一致,则有:


权衡上述两个限制,提出一个折中的办法:


根据计算出的理想方差,可选择通过高斯分布或均匀分布来随机初始化参数。若采用高斯分布,则权重可按照的高斯分布来进行初始化。若采用在区间 [−r,r]的均匀分布进行初始化,则初始化分布有:


Xavier 初始化因为基本保证了输入和输出的方差一致,使得样本空间和类别空间的分布差异相似,因此使得模型的训练速度和分类性能获得提升。但 xavier 初始化的推导基于激活函数是线性的假设,使其并不适合于 ReLU、sigmoid 等非线性激活函数。


具体论文参见:Understanding the difficulty of training deep feedforward neural networks

3.2.2 Kaiming 初始化

kaiming 初始化是一种针对 ReLU 的初始化方法,假定使用 ReLU 激活函数时,网络每一层都中有一半的神经元被激活,另一半为 0,因此其分布的方差也近似为恒等函数的一半。这样在考虑前向传播和反向传播时则有:


的理想方差为:


当采用高斯分布时,则权重可按照的高斯分布来进行初始化。若采用在区间 [−r,r]的均匀分布进行初始化,则初始化分布有:


Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification


发布于: 刚刚阅读数: 4
用户头像

汀丶

关注

本博客将不定期更新关于NLP等领域相关知识 2022-01-06 加入

本博客将不定期更新关于机器学习、强化学习、数据挖掘以及NLP等领域相关知识,以及分享自己学习到的知识技能,感谢大家关注!

评论

发布
暂无评论
深度学习基础入门篇[六]:模型调优,学习率设置(Warm Up、loss自适应衰减等),batch size调优技巧,基于方差放缩初始化方法。_人工智能_汀丶_InfoQ写作社区