先说一下我自己的体会。在了解快照集成(Snapshot Ensembles)之前,老实说我对学习率(Learning Rate)的认识是比较粗浅的。通常我会设置一个比较大的学习率,然后逐渐降低。快照集成这篇论文使用的余弦退火学习率,让我对学习率有了新的认识。这不仅在深度学习的比赛中,而且在实际业务应用中,都具有一定意义。
快照集成是一种在不增加训练成本的前提下,提升模型效果的方法。通常在比赛中更有意义。
原文的代码是Pytorch,本文在Cifar10数据集上,使用Keras框架,证明了快照集成的效果。
本文完整代码(运行时间约25分钟):
https://github.com/Qiuyan918/Snapshot-Ensembles-Keras-Case-Study/blob/master/Snapshot_Ensemble.ipynb
目录:
- 什么是快照集成(Snapshot Ensembles)?
- 什么是余弦退火学习率(Cosine Annealing Learning Rate)?
- 实验证明
1. 什么是快照集成?
快照集成一句话概括就是在同一个训练过程中,将不同节点的,且存在多样性的模型保存下来,再用于集成。这里有两个需要关注的点。
第一点是“同一个训练过程”。不同于一般的集成方法,快照集成不需要重新训练模型,而是在同一个训练过程中,产生成多个模型。我们知道,一个神经网络模型的训练时间很长。如果要训练多个模型,就需要更多时间和算力。快照集成的好处就是在不增加训练成本的前提下,仍然实现集成的效果。
第二点是“存在多样性的模型”。一般的集成方法之所有需要重新训练,就是为了保证模型的多样性,即预测错误的地方是不同的。正因为模型存在多样性,所以集成才能够比单个模型效果更好。而快照集成是如何使得同一训练过程中的模型存在多样性呢?这就需要了解余弦退火这个概念。
2. 什么是余弦退火学习率?
![](https://s2.ax1x.com/2019/11/25/MvfNh8.png)
余弦退火学习率是一种在训练过程中,调整学习率的方法。如图1,余弦退火学习率不同于传统的学习率,随着epoch的增加,learning rate 先急速下降,再陡然提升,然后不断重复这个过程。
这样剧烈波动的目的在于:逃离当前的最优点。
![](https://s2.ax1x.com/2019/11/25/MvfG7t.png)
如上图左,传统的训练过程中学习率逐渐减小,所以模型逐渐找到局部最优点。这个过程中,因为一开始的学习率较大,模型不会踏入陡峭的局部最优点,而是快速往平坦的局部最优点移动。随着学习率逐渐减小,模型最终收敛到一个比较好的最优点。
如上图右,由于余弦退火的学习率急速下降,所以模型会迅速踏入局部最优点(不管是否陡峭),并保存局部最优点的模型。⌈快照集成⌋中⌈快照⌋的指的就是这个意思。保存模型后,学习率重新恢复到一个较大值,逃离当前的局部最优点,并寻找新的最优点。因为不同局部最优点的模型则存到较大的多样性,所以集合之后效果会更好。
两种方式比较起来,可以理解为模型训练的“起点”和“终点”是差不多的。不同的是,余弦退火学习率使得模型的训练过程比较“曲折”。
3.1 实验证明
3.1.1 数据
以下的实验将用到的数据是图像数据Cifar10,总共有10种图片类型。
![](https://s2.ax1x.com/2019/11/25/MvfYAP.png)
(trainX, trainY), (testX, testY) = cifar10.load_data()
trainX = trainX.astype('float32')
trainX /= 255.0
testX = testX.astype('float32')
testX /= 255.0
idx = 4
plt.imshow(trainX[idx][:,:,0])
我们抽取一张图片看看,见图4。
![](https://s2.ax1x.com/2019/11/25/MvflXd.png)
3.1.2 Baseline
![](https://s2.ax1x.com/2019/11/25/Mvf3nA.png)
首先我们先建立一个baseline模型,来和快照集成的效果进行比较。这里我们定义一个callback来调整学习率,使得它从大到小逐渐降低,如图5。
class LearningRateScheduler(Callback):
def __init__