4.3.1. 对比学习生成句子向量的最新进展
目录
[TOC]
4.3.1.1. SimBert
simbert以UniLM为模型结构,UniLM融合了NLU和NLG,NLU部分使用双向transformer,NLG部分采用单向transformer。如下图:

simbert同时训练相似句的生成和匹配,匹配部分直接使用一个batch内其他样本作为负样本,整个batch的CLS组成的矩阵norm之后取内积可得到(batch_size,batch_size)的矩阵,利用softmax进行分类(注意对角线掩码)。训练的数据采集自百度知道,利用简单的方式构建相似问,形成有监督训练的样本。
def compute_loss_of_similarity(self, inputs, mask=None):
_, _, y_pred, _ = inputs
y_true = self.get_labels_of_similarity(y_pred) # 构建标签
y_pred = K.l2_normalize(y_pred, axis=1) # 句向量归一化
similarities = K.dot(y_pred, K.transpose(y_pred)) # 相似度矩阵
similarities = similarities - K.eye(K.shape(y_pred)[0]) * 1e12 # 排除对角线
similarities = similarities * 30 # scale
loss = K.categorical_crossentropy(
y_true, similarities, from_logits=True
)
return loss

4.3.1.2. SimBert v2
SimBERT=BERT+UniLM+对比学习
RoFormer-Sim=RoFormer+UniLM+对比学习+BART+蒸馏
- 模型结构换成了RoFormer
- 训练数据同样来源百度知道
- 同一个问题的答案是相似的(强)
- 同一篇章的句子是相似的(弱)
- 470万一般句子,3000万问句
- 随机token替换[MASK],BART是“输入带噪声的句子,输出原句子”,SimBertv2是“输入带噪声的句子,输出原句子的一个相似句”
- 以上方法增强了生成能力,却降低了匹配能力,也许是因为引入噪声语义不准确或与预测阶段不同,解决之道:RoFormer-Sim训练完后,通过蒸馏把SimBERT的检索效果转移给RoFormer-Sim。对于同一批句子,SimBERT句向量$u1,u2,⋯,un$,RoFormer-Sim为$v1,v2,⋯,vn$,则:
为了防止生成能力遗忘,损失函数为 ,作者蒸馏训练了5000 step
RoFormer主要的idea
提出了一种旋转式位置编码RoPE
更好的处理长文本和线性Attention
Bart在引入噪声方面的贡献:
- 随机将token替换成[MASK](原bert)
- 随机删去token
- 随机将一段连续的token(称作span)替换成一个[MASK],span的长度服从 λ=3 的泊松分布。span长度为0等价于插入一个[MASK]。
- 将一个document的句子打乱
- 从document序列中随机选择一个token作为document的开头
4.3.1.3. ConSERT

数据增强方式
- 打乱词序(Token Shuffling):将Position Ids进行Shuffle
- 裁剪(Cutoff)
- Token Cutoff:随机将Token Embedding整行置零。
- Feature Cutoff:随机将Embedding的Feature维度整列置为零。
- Dropout:Embedding层中每个元素以一定概率置为零。
以下数据增强方式由于不一定保持语义一致且开销大,未使用:
- 回译:利用机器翻译模型,将文本翻译到另一个语言,再翻译回来。
- CBERT:将部分词替换成[MASK],利用BERT去恢复,生成增强句子。
- 意译:利用相似句生成模型生成同义句。
数据增强消融实验结果:
- 组合:Token Shuffle和Feature Cutoff(72.74)。
- 单个:Token Shuffle > Token Cutoff >> Feature Cutoff ≈ Dropout >> None

训练目标
一个batch内由数据增强的句子作为正例,其他作为负例
是一个超参数,ConSERT取0.1,排除对角线。
4.3.1.4. SimCSE
ConSERT只对Embedding层进行干扰,SimCSE对每一层都进行干扰,但SimCSE干扰方式只有Dropout一种。
无监督学习和ConSERT无差,不再赘述。
有监督采用度量学习正负例组成三元组,损失函数为:

4.3.1.5. ESimCSE
SimCSE 用Dropout干扰无法影响句子长度,使得模型认为句子长度相仿的语义更相似,ESimCSE使用重复单词的方法改变句子长度。
另外单独用一个encoder作为动量encoder,此encoder参数的更新方式为(论文中$\lambda 取 0.995 $):
使用一个定长队列存储历史负例,不断更新这个队列,增加模型可见的负例。

4.3.1.6. PromptBert
主要思想:通过不同模板产生的语义向量构造正样本,同一批次中的其他样本作为负样本。
损失函数,为了消除Prompt模板影响,会减去模板语义向量,$h{i}-\hat{h}{i}$和$hi^{\prime}-\hat{h}{i}^{\prime}$分别是两种模板生成的句子
例如【吃饭了的意思是 [mask] 】 [mask]位置的向量减去
【[x] [x] [x] 的意思是 [mask]】 [mask]位置的向量
注意利用[x] 补位
4.3.1.7. 引用
- (2020.5)simbert:https://kexue.fm/archives/7427
- (2021.3)ConSERT: A Contrastive Framework for Self-Supervised Sentence Representation Transfer
- (2021.6)RoFormer-Sim(simbert v2):https://spaces.ac.cn/archives/8454
- (2022.3)SimCSE: Simple Contrastive Learning of Sentence Embeddings
- (2022.8)PromptBERT: Improving BERT Sentence Embeddings with Prompts
- (2022.9)ESimCSE: Enhanced Sample Building Method for Contrastive Learning of Unsupervised Sentence Embedding

