论文阅读笔记: Snapshot Ensembles

来自于论文Snapshot Ensembles: Train 1, get M for free, 代码见SnapshotEnsemble, keras版本见Snapshot Ensemble in Keras.

提出问题

在做比赛的时候, 经常把训练集训练集使用KFold方法分成若干train setdev set, 训练得到K个不同的模型, 所有的模型再对测试集进行预测, 将多个预测结果进行综合, 例如投票或平均这种简单的方式, 就能在LB上取得较大的提升.

导致这种的现象的原因, 在这篇文章中提出了一种观点.

但我们更关心的是, 本来复杂模型的训练速度就已经很慢了, 通过这种方式直接成倍的放大了训练模型所需的时间, 是没有足够的资源进一步提升的. 在这篇文章中, 提出了一种方式, 能够使用正常的训练一次的时间, 达到多个模型集成的效果.

论文内容

Stochastic Gradient Descent(SGD)算法在最优化神经网络的方法中已经是一种很优秀的方法了, 主要是因为:

  • 这种方法能够避免陷入假鞍点(spurious saddle-points), 即局部极小点(local minima)
  • 这是因为small mini-batches的随机性, 使得梯度的计算具有随机性.

但是, 这些局部极小中, 就可能包含能够提升模型表现的一些信息. 而且因为理论上讲, 我们找不到全局最小, 那么对这些局部极小就有好坏区分, 我们认为:

  • 具有平坦区域的局部极小通常表现的更好

SGD的随机性, 配合合适大小的learning rate, 就能够避免下降过程中, 陷入到比较陡峭的局部极小范围中. 但当learning rate比较小时, 模型就会趋向于收敛到最近的局部极小. SGD的这种特征, 在训练的不同阶段被巧妙的使用:

  • 初始时, learning rate较大, 模型尽快步入一个邻近的平坦的局部极小
  • 当模型的表现不再提升时, 逐步减小learning rate, 直到到达最终的局部极小

为什么多次训练结果的综合就能提升预测效果

可能的局部极小的数量, 随着模型中参数的数量, 呈指数增长. 因此对于神经网络模型, 可能的局部极小的数量是数不胜数的. 因此:

  • 不同的初始化参数
  • 不同的训练的minibatch的样本顺序

都会导致模型在最优化过程中收敛到不同的局部极小. 尽管这些不同的局部极小拥有非常相近的loss, 但每个模型会犯不同的错误. 这种模型表现的多样性就可以通过集成(ensembling)的形式, 通过投票或者取平均值等简单的方法, 大大降低模型的最终loss, 大幅提升模型的表现.

但是这种集成的方式造成算例线性增加, 是我们难以承受的. 解决方法如下.

显著提升效果的方法

我们不需要训练若干个模型然后集成, 而是只需要训练一个模型, 配合SGD收敛和逃脱局部极小的功能, 在模型训练的过程中多次收敛:

  • 每次收敛之后保存下模型的参数, 这样就相当于得到了一个完整的训练好的模型
  • 提高learning rate, 继续训练逃脱出当前的局部极小
  • 重复上面两步, 直到满足需要的模型的个数.

文中提到了这样操作的具体方法: 根据一个cosine function, 迅速提高和降低learning rate以达到目的**.

这个过程如下图所示

具体训练方法

总的来说, 本模型就是在最优化过程中, 访问多个局部最优, 直到最后一次收敛, 每次收敛对应一个模型(snapshot model), 在预测时, 平均所有模型的预测结果.

每个单独的模型要求:

  • dev loss必须低, 这是保证模型预测能力的要求
  • 每个模型误分类的样本不能重叠, 这是保证模型之间差异性的要求

Ilya Loshchilov & Frank Hutter的Stochastic Gradient Descent with Warm Restarts中提到, 较早的降低学习率对最终的模型预测损失影响很小. 因此为了快速收敛, 我们尽快降低学习率.

为了达到收敛到多个局部最优的目的, 使用一种Cyclic Cosine Annealing(循环余弦退火)的方法:

  • 以大步幅降低学习率, 使模型在很少(50)个epochs之内收敛到第一个局部最优
  • 然后使用一个大的学习率继续优化, 使模型跳出局部最优
  • 重复这两个过程, 直到收集到指定数目的模型

我们定义学习率为:

\(\alpha(t) = f(mod(t-1, ceil(T/M)))\)

\(t\)是迭代轮数, \(T\)是总的迭代轮数, \(f\)是一个单调递减的函数. 我们将训练过程分成\(M\)个循环, 对应\(M\)个模型.

每次从一个大的学习率开始训练, 逐渐收缩到一个小的学习率. \(\alpha=f(0)\)代表着每次退火开始的较大的那个学习率, 使用这个学习率从局部最优中跳出. 最小的学习率为\(\alpha=f(ceil(T/M))\), 在这个学习率下达到预测效果较好的局部最优. 论文中使用如下的方式:

\[\alpha(t)=\frac{\alpha_0}{2}(\cos(\frac{\pi \mod(t - 1, ceil(T / M))}{ceil(T / M)}) + 1)\]

\(\alpha_0\)是初始的学习率, 因此学习率在\(\alpha_0\)到$f(ceil(T/M))\approx0 $之间变换.

在论文中, 学习率在每次迭代, 即每个batch迭代更新后, 进行更新, 而不是在每次epoch之后更新.

猜你喜欢

转载自www.cnblogs.com/databingo/p/9420892.html
今日推荐