又是Dropout两次!这次它做到了有监督任务的SOTA
©PaperWeekly 原创 · 作者 | 苏剑林
单位 | 追一科技
研究方向 | NLP、神经网络
关注 NLP 新进展的读者,想必对四月份发布的 SimCSE [1] 印象颇深,它通过简单的“Dropout 两次”来构造正样本进行对比学习,达到了无监督语义相似度任务的全面 SOTA。无独有偶,最近的论文《R-Drop: Regularized Dropout for Neural Networks》提出了 R-Drop,它将“Dropout两次”的思想用到了有监督任务中,每个实验结果几乎都取得了明显的提升。此外,笔者在自己的实验还发现,它在半监督任务上也能有不俗的表现。
论文标题:R-Drop: Regularized Dropout for Neural Networks
论文链接:https://arxiv.org/abs/2106.14448
代码链接:https://github.com/dropreg/R-Drop
《中文任务还是 SOTA 吗?我们给 SimCSE 补充了一些实验》[1] 中,我们已经对 SimCSE 进行了介绍。简单来说,SimCSE 是 NLP 的一种对比学习方案,对比学习的标准流程是同一个样本通过不同的数据扩增手段得到的结果视为正样本对,而 batch 内的所有其他样本视为负样本,然后就是通过 loss 来缩小正样本的距离、拉大负样本的距离了。
在实现上,SimCSE 也相当简单,所谓“Dropout 两次”,只需要将样本重复地输入到模型,然后计算相应的 loss 就行了,如上图所示。由于 Dropout 本身的随机性,每个样本的 Dropout 模式都是不一样的,所以只要单纯地重复样本,就可以实现“Dropout 两次”的效果。
R-Drop
2.1 分类问题
2.2 一般形式
实验效果
我们先来看看 R-Drop 的实验结果。
官方实现:https://github.com/dropreg/R-Drop
个人实现:https://github.com/bojone/r-drop
有中文监督任务上,笔者实验了两个文本分类任务(CLUE 榜单的 IFLYTEK 和 TNEWS)。
相比于对抗学习等复杂正则化方法,R-Drop 的实现难度可谓是相当低了,这里以 bert4keras 为例,简单介绍一下如何将一个普通的训练脚本改为带 Dropout 的模式。
首先,是数据生成部分,改动如下:
class data_generator(DataGenerator):
"""数据生成器
"""
def __iter__(self, random=False):
batch_token_ids, batch_segment_ids, batch_labels = [], [], []
for is_end, (text, label) in self.sample(random):
token_ids, segment_ids = tokenizer.encode(text, maxlen=maxlen)
# batch_token_ids.append(token_ids)
# batch_segment_ids.append(segment_ids)
# batch_labels.append([label])
for i in range(2):
batch_token_ids.append(token_ids)
batch_segment_ids.append(segment_ids)
batch_labels.append([label])
# if len(batch_token_ids) == self.batch_size or is_end:
if len(batch_token_ids) == self.batch_size * 2 or is_end:
batch_token_ids = sequence_padding(batch_token_ids)
batch_segment_ids = sequence_padding(batch_segment_ids)
batch_labels = sequence_padding(batch_labels)
yield [batch_token_ids, batch_segment_ids], batch_labels
batch_token_ids, batch_segment_ids, batch_labels = [], [], []
from keras.losses import kullback_leibler_divergence as kld
def categorical_crossentropy_with_rdrop(y_true, y_pred):
"""配合上述生成器的R-Drop Loss
其实loss_kl的除以4,是为了在数量上对齐公式描述结果。
"""
loss_ce = K.categorical_crossentropy(y_true, y_pred) # 原来的loss
loss_kl = kld(y_pred[::2], y_pred[1::2]) + kld(y_pred[1::2], y_pred[::2])
return K.mean(loss_ce) + K.mean(loss_kl) / 4 * alpha
最后把模型的 Dropout 打开,并用这个 data_generator 和 categorical_crossentropy_with_rdrop 来训练模型就行了。
个人理解
我们假定这个结果能泛化到一般情况。上式告诉我们,带 Dropout 的模型的正确步骤是“模型融合”:
对同一个输入多次传入模型中(模型不关闭 Dropout),然后把多次的预测结果平均值作为最终的预测结果。
但我们一般情况下的预测方式显然不是这样的,而是直接关闭 Dropout 进行确定性的预测,这等价于预测模型由“模型平均”变成了“权重平均”:
这里的 1 指的是全 1 向量。所以,我们训练的是不同 Dropout 的融合模型,预测的时候用的是关闭 Dropout 的单模型,两者未必等价,这就是 Dropout 的训练预测不一致问题。
本文开头就提到 R-Drop 与 SimCSE 的相似性,事实上它还跟另外一个方法相当相似,那便是“虚拟对抗训练(Virtual Adversarial Training,VAT)”。(不过 R-Drop 也没引 VAT,难道就只有笔者觉得像吗??)
关于 VAT 的介绍,大家可以参考笔者之前的文章泛化性乱弹:从随机噪声、梯度惩罚到虚拟对抗训练。简单来说,VAT 也是通过一个正则项,使得模型对扰动更加鲁棒,增强模型本身的连续性(小的变化不至于对结果产生大的影响)。它们不同的地方在于加扰动的方式,VAT 只把扰动加入到输入中,并且通过对抗的思想提升扰动的针对性;R-Drop 的扰动则可以施加到模型的每一层中,并且扰动是随机的。
一个比较直接的疑问是,如果我的模型够复杂,单靠交叉熵这一项,不能使得模型对 Dropout 鲁棒吗?KL 散度那一项造成了什么直接的区别?
不同的 Dropout 下,目标类的得分都大于非目标类的得分。
而不能做到:
不同的 Dropout 下,每个类的得分一致。
本文小结
参考文献
更多阅读
#投 稿 通 道#
让你的文字被更多人看到
如何才能让更多的优质内容以更短路径到达读者群体,缩短读者寻找优质内容的成本呢?答案就是:你不认识的人。
总有一些你不认识的人,知道你想知道的东西。PaperWeekly 或许可以成为一座桥梁,促使不同背景、不同方向的学者和学术灵感相互碰撞,迸发出更多的可能性。
PaperWeekly 鼓励高校实验室或个人,在我们的平台上分享各类优质内容,可以是最新论文解读,也可以是学术热点剖析、科研心得或竞赛经验讲解等。我们的目的只有一个,让知识真正流动起来。
📝 稿件基本要求:
• 文章确系个人原创作品,未曾在公开渠道发表,如为其他平台已发表或待发表的文章,请明确标注
• 稿件建议以 markdown 格式撰写,文中配图以附件形式发送,要求图片清晰,无版权问题
• PaperWeekly 尊重原作者署名权,并将为每篇被采纳的原创首发稿件,提供业内具有竞争力稿酬,具体依据文章阅读量和文章质量阶梯制结算
📬 投稿通道:
• 投稿邮箱:hr@paperweekly.site
• 来稿请备注即时联系方式(微信),以便我们在稿件选用的第一时间联系作者
• 您也可以直接添加小编微信(pwbot02)快速投稿,备注:姓名-投稿
△长按添加PaperWeekly小编
🔍
现在,在「知乎」也能找到我们了
进入知乎首页搜索「PaperWeekly」
点击「关注」订阅我们的专栏吧
关于PaperWeekly
PaperWeekly 是一个推荐、解读、讨论、报道人工智能前沿论文成果的学术平台。如果你研究或从事 AI 领域,欢迎在公众号后台点击「交流群」,小助手将把你带入 PaperWeekly 的交流群里。