问答系统的搭建过程一般需要多个模块联合工作才能实现整个系统的功能,但通过实践发现,每个模块归根到底都是在计算相似度,而使用范围广、有效性强的一种任务就是计算句子对的相似性,或者称为Semantic Textual Similarity/STS任务。直接使用的场景就是搭建FAQ问答系统中,最后一步就是计算问句与候选问句的相似性,最终认为相似性最大的候选问句的答案为用户问句对应的答案。
撰写本笔记的原因是作者在搭建领域FAQ问答系统时,使用SBERT的方法训练模型,即使在设置了比较大的batch_size后,模型在训练时的效果也不是很理想。前两年对比学习在CV中特别火热,在nlp领域也有一定的发展,ConSERT是美团算法团队和北邮nlp团队的共同工作,而SimCSE是普林斯顿大学nlp组的工作,两个方法都是在BERT的基础上使用了无监督的对比学习方法训练,后续也集成了NLI任务的有监督知识,最后有效提高了当时STS任务中benchmark分数。本笔记是在论文阅读后的一个总结笔记,后续完成代码阅读或实际使用后也会记录相应的内容。
论文链接
- SimCSE: Simple Contrastive Learning of Sentence Embeddings
- ConSERT: A Contrastive Framework for Self-Supervised Sentence Representation Transfer
句子嵌入或表征方法
如前文所述,大量的nlp任务都需要计算文本序列之间的相似度,就需要将文本序列先转换为向量的形式,论文中一般称为嵌入或表征;最开始使用的方法有word2vec、Glove等,随着大体量的预训练模型如BERT、RoBERTa、XL-net等流行与应用,此类模型应用到大量下游任务,其基于大量的训练文本学习到文本的表征空间能帮助处理很多下游NLP任务。
直接使用bert等预训练的语义向量的问题
论文ConSERT中提到,直接使用bert衍生出来的句子表征使用效果较差,进行STS任务时,几乎所有句子对的相似度得分都在0.6~1.0之间(如下图1(a)所示),即使有些句子对从人类的角度来看是毫不相关的。换句话说,bert衍生的原生句子表征以某种方式坍塌了,这意味着几乎所有的句子都被映射到一个小区域(或者说表征空间分布不均匀,是各向异性的),因此产生了高相似性。
SimCSE论文也将上述现象描述为bert表示空间的各向异性问题,引用了论文Representation Degeneration Problem in Training Natural Language Generation Models进行证明,说明预训练的语言模型会导致各向异性的词嵌入;而论文Improving Neural Language Generation with Spectrum Control表明,语言模型中的词嵌入矩阵的奇异值急剧衰减:除了少数占主导地位的奇异值外,其他所有的奇异值都接近于零,即相当于少数站主导地位的词向量决定了最终的相似度。
此问题也在之间的一些工作中被观察到,bert的词表征空间各向异性,高频词聚类,而低频词稀疏分散。如果采用对一个句子所有的token表征取平均的方式获得句子表征,那么那些高频词就会主导句子表示,从而导致对真实语义的偏差;最终的结果就是,直接使用BERT原始的句子表征进行语义匹配或文本检索式不合适的。
无监督学习的如何解决问题
ConSERT和SimCSE两篇论文都任务使用无监督的对比学习可将对bert的表征空间进行重构,从而改善模型对句子表征的能力,直观的结果就是在STS任务上效果更好。
ConSERT中为了证明表征空间坍塌主要是由于对token频率敏感的各向异性空间造成的假设,在应用平均池化计算句子表示时,进行了掩盖几个最频繁token嵌入的实验。移除的top-k频繁token数量与平均spearman相关性的关系如图2所示。可以观察到,当删除一些顶级频繁标记时,BERT在STS任务中的性能得到了显著提高。当删除34个最频繁的token时,获得了最佳性能(61.66),并且比原始性能(53.86)提高了7.8。对于ConSERT,发现删除一些最常见的标记只会带来小于0.3的小改进。结果表明,提出的方法重塑了BERT的原始嵌入空间,减少了常见符号对句子表示的影响。
SimCSE中根据Understanding Contrastive Representation Learning through Alignment and Uniformity on the Hypersphere论文认为一个有效的表征空间应该具有良好的对齐性和均匀性,即强相关文本应该保持接近,而不相关的随机文本应该均匀的分散在表征空间的超球面上。
论文结果表明SimCSE中的对比学习能在保持表征空间对齐性不衰减的情况下大幅度改善其均匀性;论文中使用
l
a
l
i
g
n
l_{align}
lalign和
l
u
n
i
f
o
r
m
l_{uniform}
luniform两个数值表示对齐性和均匀性,两个值都是越小越好。图3显示了SimCSE论文中使用的不同句子嵌入模型及其平均STS结果的一致性和对齐;总的来说,具有更好的对齐性和均匀性的模型性能更好。从图3中可以看到,预训练的bert模型就良好的对齐性,但均匀性较差,而SimCSE模型能在保持对其行基本不衰减的情况下,大大改善均匀性,从而在STS任务中有更高的spearman相关性
图3 SimCSE中STS任务上基于
B
E
R
T
b
a
s
e
各模型的
l
a
l
i
g
n
−
l
u
n
i
f
o
r
m
图
BERT_{base}各模型的l_{align}-l_{uniform}图
BERTbase各模型的lalign−luniform图
模型逻辑
正如前文所述,两种方法均认为无监督的对比学习可以改善bert的表示空间,提高模型在下游任务,特别是STS任务上的性能。同时,两种方法在进行对比学习训练后,都有意识的结合使用了有标签的STS数据集任务进行有监督的训练,进一步提高了模型性能。
无监督学习
无监督的对比学习在CV相较于NLP使用更广泛,主要的思路其实是通过数据增强的方式从原数据中构建一个相似数据,如此这两个数据组成正例,而原数据与batch中其他数据组成的数据对均是负例,即解决了训练需要的监督信息,ConSERT和SimCSE中的基本思路基于与此一致;当然CV中后续也出现了是只需要学习自身的模型,也没有出现坍塌现象,后续有机会再进行说明。
ConSERT
ConSERT整体思路与SimCLR(A Simple Framework for Contrastive Learning of Visual Representations,CV中经典的对比学习模型)一致,结构如图4所示,有三个主要模块:
- 数据增强:在token嵌入层,数据增强组件从输入样本中生成不同的视图
- 表征学习:一个共享的BERT编码器给每个输入的文本计算句子表征。训练过程中,句子最后一层的隐向量进行平均池化表示句子的表征
- 对比损失:BERT编码器顶部是一个对比学习损失层,最大限度地提高了一个表征与从同一句子扩增而来的表征表示的一致性,同时保持了它与同一批其他句子表征的距离
对于每个输入文本x,先将其送入数据增强模块,在该模块中两个转换T1和T2生成两个版本的token嵌入序列,
e
i
=
T
1
(
x
)
,
e
j
=
T
2
(
x
)
e_i=T_1 (x),e_j=T_2 (x)
ei=T1(x),ej=T2(x),其中
e
i
,
e
j
∈
R
L
×
d
e_i,e_j∈R^{ L×d}
ei,ej∈RL×d,L是序列的长度,d是隐变量的维度。然后,
e
i
,
e
j
e_i,e_j
ei,ej通过BERT中的多层transformer块进行编码,最后使用平均池化产生句子表征
r
i
,
r
j
r_i,r_j
ri,rj。与SimCLR中一致,使用以归一化温度尺度交叉熵损失(NTXent)作为对比目标。在每个训练步骤中,从D中随机抽取N个文本构建一个mini-batch,经过增强后得到2N个表示。训练每个数据点在2(N - 1)个批内负样本中找到对应的数据点:
公式中的sim(·)表示余弦相似度函数,τ控制温度参数在。最后对同一batch内的2N个损失进行平均,获得最终的对比损失
L
c
o
n
L_{con}
Lcon。
上文说到文本会经过两个转换T1和T2生成两个版本的序列作为正例,ConSERT中使用了四种转换,即四种数据增强方式:
- adversarial attack:在输入样本中添加扰动来生成对抗样本,本论文使用Fast Gradient Value/FGV(Adversarial Diversity and Hard Positive Generation)方式实现此策略,直接使用梯度计算扰动,速度更快。注意,该策略仅适用于与监督联合训练,因为它依赖监督损失来计算对抗性扰动
- token shuffling:目标是随机打乱输入序列中的标记的顺序,通过当保持token索引顺序不变时,将打乱的位置索引传递给嵌入层来实现此策略
- cutoff:Cutoff准确来说有三种不同的方法,分别是Token cutoff、Feature cutoff和Span cutoff(span cutoff就是将连续的多个token的表示cutoff);本论文中只使用了Token cutoff、Feature cutoff生成不同的视图
- dropout:按照特定的概率在token入层中随机删除元素,并将它们的值设为零。请注意,这种策略与Cutoff不同,因为每个元素都是单独考虑的
上面的文字描述可能不是很清晰,结合图5得到一个更直观的理解
SimCSE
SimCSE思路与ConSERT一致,但是却只是用了dropout作为数据增强方法,如图6(a)所示。换句话说,将同一个句子传递给预训练的编码器两次:通过两次应用标准 dropout,可以获得两个不同的嵌入作为“正例”。 然后,把同一小批次中的其他句子作为负例,该模型在负例中预测正例。尽管看起来非常简单,但这种方法大大优于预测下一个句子和离散数据增强(例如,单词删除和替换)等训练目标,甚至可以与以前的监督方法相媲美。通过仔细的分析,发现dropout对隐藏表征起到了最小的数据增强作用,而移除它会导致表征的塌陷。
使用一个句子集合
{
x
i
}
i
=
1
m
\lbrace{x_i}\rbrace_{i=1}^m
{xi}i=1m,设置
x
i
=
x
i
+
x_i=x_i^+
xi=xi+。让它与相同的正对一起工作的关键因素是通过对
x
i
,
x
i
+
x_i,x_i^+
xi,xi+使用独立采样的 dropout 掩码。在 Transformers 的标准训练中,在全连接层上放置了 dropout 掩码以及注意力概率(默认 p = 0.1)。论文中
h
i
z
=
f
θ
(
x
i
,
z
)
h_i^z=f_θ (x_i,z)
hiz=fθ(xi,z),其中z是dropout的随机掩码。只需将相同的输入两次输入到编码器,得到两个具有不同dropout掩码
z
,
z
′
z,z^{'}
z,z′的嵌入,在由N个句子组成的mini-batch中SimCSE的训练目标为:
为了进一步了解 dropout 噪声在无监督 SimCSE 中的作用,论文尝试了不同的 dropout 率,并观察到所有变体的表现都低于 Transformers 的默认 dropout 概率 p = 0.1。发现两个极端情况特别有趣:“无 dropout”(p = 0)和“fixed 0.1”(使用默认 dropout p = 0.1,但对数据对使用相同的 dropout 掩码);在这两种情况下,产生的嵌入对是完全相同的,这导致了显著的性能下降。在训练期间每 10 步检查一次这些模型的检查点,并可视化图 7 中的对齐性和均匀性指标,以及一个简单的数据增强模型“删除一个单词”。 很明显,从预先训练的检查点开始,所有模型都大大提高了一致性。然而,两个特殊变体的对齐性也急剧下降,而无监督SimCSE保持稳定对齐,这要归功于dropout噪声的使用。它还表明,从一个预先训练的检查点开始是至关重要的,因为它提供了良好的初始对齐。最后,“删除一个词”改进了对齐,但在一致性度量上获得的增益较小,最终性能低于无监督的SimCSE。
图7 SImCSE中无监督SimCSE、“no dropout”、“fixed 0.1”和“delete one word”四种设置的 l a l i g n − l u n i f o r m l_{align}-l_{uniform} lalign−luniform图。每10个训练步骤中可视化检查点,箭头表示训练方向。两个参数的数值越小越好
有监督知识集成
ConSERT和SimCSE通过实验验证无监督对比实验能改善bert表征空间,提高模型性能后,都进一步集成监督信息,模型性能也进一步提高。
ConSERT
ConSERT中主要使用NLI任务进行有监督训练,其为一项句子对分类任务,训练模型来区分两个句子之间关系属于矛盾、蕴涵和中性中的一种。分类目标可以表示为:
其中
r
1
,
r
2
r_1,r_2
r1,r2表示两个句子表征,论文提出了三种集成有监督信号的方法:
- joint(联合训练) —在NLI数据集中同时进行有监督和无监督训练,损失为两个任务损失的加权和,即 L j o i n t = L c e + α L c o n L_{joint}= L_{ce}+αL_{con} Ljoint=Lce+αLcon。 α α α是平衡两个目标的超参数
- sup-unsup(先进行有监督训练再进行无监督训练) —先在NLI数据集上使用目标 L c e L_{ce} Lce训练模型,再在目标数据集(如STS)上使用 L c o n L_{con} Lcon进行对比学习训练
- joint-unsup(先进行联合训练再进行无监督训练) —先在NLI数据集上使用目标 L j o i n t L_{joint} Ljoint联合训练模型,再在目标数据集(如STS)上使用 L c o n L_{con} Lcon进行对比学习训练
SImCSE
SimCSE也是使用NLI数据集作为有标签的监督数据,但是实现方式与ConSERT中不同;ConSERT中相当于是将有监督换个无监督训练视为两个部分,是通过联合损失或者二次训练集成两者,但是在SimSCE是将有监督信息应用在了无监督对比对数构造中。
SimCSE在无监督训练中是对一个句子使用两次不同的dropout构建一个正例对,与同batch中其他句子构成负例对;但是在有监督训练中,使用NLI数据集中蕴涵/entailment、中性/neutral和矛盾/contradiction三个标签,自然的将与句子有蕴含标签的句子可视为一个正例对,而将与句子有矛盾标签的句子作为hard negative example能进一提高性能,如图6(b)所示。
有监督训练中,形式上,将原来的数据对
(
x
i
,
x
i
+
)
扩展为
(
x
i
,
x
i
+
,
x
i
−
)
(x_i,x_i^+)扩展为(x_i,x_i^+,x_i^-)
(xi,xi+)扩展为(xi,xi+,xi−),其中
x
i
x_i
xi是目标文本,
x
i
+
,
x
i
−
x_i^+,x_i^-
xi+,xi−分别是NLI数据集中与目标文本对应蕴含文本和矛盾文本。在批量大小为N的mini-batch中训练目标
l
i
l_i
li表示为:
论文中尝试扩充数据集或使用dropout的无监督方法,但模型性能没有明显改善;同时考虑了双编码器框架,反而会损害性能。
总结
本笔记主要是将ConSERT和SimCSE两种在句子嵌入任务中使用对比学习的方法进行了对比分析,主要的内容也是作者在阅读完两篇论文的一个总结。这两个工作在目标任务、实现思路,使用的数据集、benchmark都非常相似,故具有很强的对比性,从数据结果上看是SimCSE表现更甚一筹,但是ConSERT也能对我们有很大启发;本笔记中主要记录是从思路、模型结构方面,没有对数据、实现细节进行描述,有兴趣的读者可以自行阅读论文,从论文中吸取对自身有帮助的信息。本笔记是作者主观总结,必然存在错误或不足,读者若发现问题请留言评论,互相学习。
以下链接是在网上无意找到的对NLP对比学习工作的总结,内容简单、易懂但很全面,有兴趣的读者也可以浏览学习;因为时间的原因,已找不到发布该链接的作者,放在本笔记中也只是以供学习,若涉及侵权,请联系本人,会立马删除。
https://docs.qq.com/mind/DVFRBekhSY2lYQW1B