导读:本文是“数据拾光者”专栏的第四十七篇文章,这个系列将介绍在广告行业中自然语言处理和推荐系统实践。本篇从理论到实践分享了当前NLP中对比学习SOTA的ESimCSE模型,对于想将对比学习应用到NLP场景的小伙伴可能有帮助。
摘要:本篇从理论到实践分享了当前NLP中对比学习SOTA模型ESimCSE。首先回顾了无监督SimCSE以及存在的两个问题;然后重点详解了ESimCSE,包括ESimCSE介绍、通过词重复优化正例构建、通过动量对比优化负例构建和模型实验效果展示;最后源码实践了ESimCSE。对于想将对比学习应用到NLP场景的小伙伴可能有帮助。
下面主要按照如下思维导图进行学习分享:
01
背景介绍
1.1 回顾下SimCSE
之前分享过一篇文章《广告行业中那些趣事系列35:NLP场景中的对比学习模型SimCSE》,里面介绍了丹琦女神的SimCSE模型。这里简单回顾下对比学习的核心原则:通过构造相似实例和不相似实例获得一个表示学习模型,通过这个表示学习模型可以让相似的实例在投影的向量空间中尽可能接近,不相似的实例在向量空间中尽可能远离。对比学习最早出现在CV场景中,后来引入到NLP场景。NLP场景中应用对比学习最难的是如何构造相似实例和不相似实例,SimCSE采用一种基于dropout mask的方式构造正负例。SimCSE包括有监督和无监督两种模型结构,本篇主要讨论无监督SimCSE。无监督SimCSE模型将一个batch内同一条样本经过两次dropout mask操作得到正样本,和batch内其他样本得到负样本,下面是无监督SimCSE模型结构图:
图1 无监督SimCSE模型结构图
NLP场景中虽然可以通过样本回译、随机替换等样本增强的方法构造正负例,但是整体来看效果不是很理想。SimCSE模型作者提出了一种通过随机采样dropout mask的操作来构造相似样本,具体操作是在标准的Transformer中会在全连接层和注意力求和操作上进行dropout mask操作,模型训练的时候会将一条样本x复制两份,然后将这两条样本放到同一个编码器中就可以得到两个不同的表示向量z和zi。这么做的原因是BERT内部每次dropout时都会随机生成一个不同的dropout mask,不需要改变原始的BERT模型,只需要把样本喂给模型两次,就可以得到两个不同dropout mask的结果,这样就得到了相似样本对。这种方式的好处是相似样本的语义完全一致,只是生成的embedding不同而已,可以认为是数据增强的最小形式。这种方式简单且高效,并且取得了不错的效果。
1.2 SimCSE存在的两个问题
虽然SimCSE取得不错的效果,但是存在两个问题:
- 第一个问题是正例的构建方法有待提升,基于dropout mask构造正例的方法会使模型倾向于将长度相近的语句认定为相似。因为模型训练的时候会将一条样本复制两份放入BERT(BERT内部每次dropout时都会随机生成一个不同的dropout mask),同一条样本衍生出的正例对长度是相同的,而batch内其他的样本构建的负例对长度可能是不同的,这样会使模型将样本长度作为识别正负例的重要特征,导致模型倾向于将长度相近的语句认定为相似。
- 第二个问题是负例的构建方法有待提升。因为SimCSE是基于负例的对比学习方法,理论上batch内负例越多模型学习的效果越好,但是batch size设置过大会导致性能下降。
02
详解ESimCSE
2.1 ESimCSE介绍
ESimCSE是Arxiv上一篇论文《ESimCSE: Enhanced Sample Building Method for Contrastive Learning ofUnsupervised Sentence Embedding》中提出的,从论文题目可以看出是一种加强版的SimCSE,核心内容是通过词重复(word repetition)和动量对比(momentum contrast)优化SimCSE构建正负例的方法,下面是无监督ESimCSE模型结构图:
图2 无监督ESimCSE模型结构图
2.2 通过词重复优化正例构建
SimCSE模型训练的时候会将一条样本复制两份放入BERT(BERT内部每次dropout时都会随机生成一个不同的dropout mask),同一条样本衍生出的正例对长度是相同的,而batch内其他样本构建的负例对长度可能是不同的,这样会使模型将样本长度作为识别正负例的重要特征,导致模型倾向于将长度相近的语句认定为相似。ESimCSE模型作者在标准文本语义相似度STS任务中对比了长度小于3和大于3时语句对的spearman系数,当长度差异大于3时无监督SimCSE模型的效果大幅度降低,下面是STS数据集上不同长度差异下SimCSE模型效果对比表:
图3 STS数据集上不同长度差异下SimCSE模型效果对比表
从上表中可以发现语句对长度差异大于3时候无监督SimCSE模型效果下降非常明显,相比于长度差异小于等于3时下降了0.1224。为了缓解语句长度差异对模型的影响,作者尝试了随机插入、随机删除和词重复三种方法构建正例,下面分别展示了三种策略语义相似度的差别:
图4 随机插入、随机删除和词重复构建正例展示
从上图中可以看出,通过随机插入和随机删除的方法得到的样本和原样本语义相似度下降明显,相似度仅为0.77左右。通过词重复的方式构建正例,不仅可以很好的保持文本语义相似度,而且还能缓解语句长度差异对模型效果的影响。
2.3 通过动量对比优化负例构建
上面通过词重复的方式优化正例构建,下面主要优化负例构建。因为SimCSE是基于负例的对比学习,batch内某个样本和自己构建正例,和其他样本则为负例,所以batch里样本数越多负例也就越多,对应的模型也会学习的更好。但是batch size设置过大并不一定是好的选择,从参考资料1中可以看出对于无监督SimCSE模型来说,随着batch size增加模型性能也大幅度降低,最优batch size是64,下图是batch size对模型性能的影响:
图5 batch size对模型性能的影响
为了有效的扩展负例对,同时缓解扩展batch size时GPU内存的限制,计算机视觉主要通过动量对比(momentum contrast)的方式,具体做法是维护一个固定大小的队列(一般比batch大很多),从而可以重用邻近batch中编码句子的embedding。通过这种方式,如果队列大小是batch size的5倍,那么负例的量级也就扩大了5倍,从而可以更充分的学习。如果队列满了,则会删除最早进入队列语句的embedding。下面是使用动量对比前后的展示图:
图6 使用动量对比前后的展示
如上图所示,batch size设置为64,假如动量对比队列的大小为5*64。对于一条样本来说,如果不使用动量对比,负例对为63;如果使用动量对比,那么负例对就变成了(64*5-1)。当队列满了之后,有新的batch数据进入队列时,最早的batch数据就会移出队列。
2.4 ESimCSE模型效果展示
分别对比了在不同版本的BERT模型和STS测试集下无监督SimCSE和ESimCSE模型效果,整体来看ESimCSE有不错的效果提升,下面是效果展示图:
图7 对比不同BERT模型权重下SimCSE和ESimCSE模型效果
为了进一步查看词重复和动量对比对ESimCSE模型效果的贡献,作者进行了消融实验。从实验结果来看,词重复和动量对比对ESimCSE均有不错的效果提升,两者组合得到的效果更优。下面是ESimCSE模型消融实验结果图:
图8 ESimCSE模型消融实验结果
03
源码实践ESimCSE
SimCSE源码实践可以参考苏神的github:
https://github.com/bojone/SimCSE
ESimCSE相比于SimCSE主要增加了词重复和动量对比,源码可以使用如下的github:
https://github.com/xianghuisun/nlp-basictasks/blob/main/ESimCSE.ipynb
04
总结及反思
本篇从理论到实践分享了当前NLP中对比学习SOTA模型ESimCSE。首先回顾了无监督SimCSE以及存在的两个问题;然后重点详解了ESimCSE,包括ESimCSE介绍、通过词重复优化正例构建、通过动量对比优化负例构建和模型实验效果展示;最后源码实践了ESimCSE。对于想将对比学习应用到NLP场景的小伙伴可能有帮助