论文地址: Temporal Ensembling for Semi-Supervised Learning
代码地址: https://github.com/s-laine/tempens
会议: ICLR 2017
任务: 分类
self-ensembling 即自集成, 自己集成自己. 对于神经网络来说, 一个样本如果多次送入网络, 能够产生多个模型预测结果, 这些结果可以进行融合, 同时在不同的 batch 训练之后, 模型的参数也会发生变化, 参数可以进行融合, 因此, self-ensembling 的套路在于集成模型预测结果或者模型参数.
论文中提出两种自集成的实现: Π \Pi Π-model, Temporal ensembling
文中符号定义如下:
模型中损失函数由两个部分组成: 1.标准交叉熵损失, 仅针对有标记输入进行评估. 2.对无标记输入进行评估, 取预测向量 z i z_i zi 和 z ~ i \tilde{z}_i z~i 之间的均方差. 为了结合监督和非监督损失项, 在之后通过加权函数 w ( t ) w(t) w(t) 进行缩放操作.
训练过程的每一个 epoch 中, 一个标签样本前向传播两次, 通过 data augmentation 和 dropout 注入扰动, 由于前向传播两次, 所以得到两个预测向量 z i z_i zi 和 z ~ i \tilde{z}_i z~i, 然后计算均方误差. 基于一致性正则化, 模型希望在注入扰动后得到的结果应该与原来一致, 所以, Π \Pi Π-model 希望 z i z_i zi 和 z ~ i \tilde{z}_i z~i 尽可能一致.
对于有标签样本, 前向传播一次, 注入扰动后在预测值与真实值之间进行交叉熵计算. 最后将两个损失函数进行加权求和即为损失函数 l o s s loss loss.
Π \Pi Π-model 模型如下图所示:
需要注意的是, 由于 dropout 正则化, 训练期间的网络输出是一个随机变量. 因此, 在相同网络权重 θ \theta θ 下对相同输入 x i x_i xi 的两次评估会产生不同的结果. 此外, 高斯噪声和诸如随机平移之类的增强被评估了两次, 从而产生了额外的变化.
Π \Pi Π-model 算法流程如下图所示:
对于一个 mini-batch 中的所有 x i x_i xi:
在此实现中, 无监督损失加权函数 w ( t ) w(t) w(t) 从零开始 ramp-up, 这个权重随时间变化而变化, 即 time-dependent. 其在前 80 个 epoch 中沿着高斯曲线上升. 同时文中发现 ramp-up 的上升速度要足够慢才行, 不然, 网络很容易陷入退化的解, 无法获得有意义的数据分类.
下面代码来自 mean-teacher 中的 ramp-down 策略
def cosine_rampdown(current, rampdown_length):
"""Cosine rampdown from https://arxiv.org/abs/1608.03983"""
assert 0 <= current <= rampdown_length
return float(.5 * (np.cos(np.pi * current / rampdown_length) + 1))
与 Π \Pi Π-model 相比, 训练过程的每一个 epoch 中, 一个无标签样本只前向传播一次, 而另一次则使用之前 epoch 得到的预测结果来充当, 具体做法为用指数平滑(EMA)来计算. 这时, 每个样本在每个 epoch 只通过了一次评估, 比 Π \Pi Π-model 的速度快了近2倍.