Contrastive Learning NLP Papers


https://zhuanlan.zhihu.com/p/363900943
上方链接有两个论文:

  1. 解决NMT的单词遗漏[acl2019]
  2. 常识推理的对比性自我监督学习

对比学习+聚类(Contrastive Clustering)

1 对比学习有多火?文本聚类都被刷爆了…
上方链接是 聚类+对比学习 来更好的对文本聚类。
聚类关注高层级的语义概念,对比学习增强的语句对更关注句子级别的。

2 我的另一篇博客Contrastive Clustering
分布对特征矩阵的行和列进行聚类和对比学习


SimCSE(已开源)

Dropout来实现对比学习的数据增强(SimCSE)

说了:对比表示学习有用,主要是因为它优化了两个目标:

  1. 正例之间表示保持较近距离
  2. 机样例的表示应分散在超球面上。

提出这两个目标分别可以用指标alignment和uniformity来衡量:
在这里插入图片描述
alignment计算正例对之间的向量距离的期望

越相似的样例之间的alignment程度越高。因为alignment使用距离来衡量,所以距离越小,表示alignment的程度越高。

uniformity评估所有数据的向量均匀分布的程度,越均匀,保留的信息越多

可以想象任意从表示空间中采样两个数据 和 , 希望他们的距离比较远。他们的距离越远,证明空间分布越uniform。所以uniformity的值也是越低越好。

SimCSE也采用这两个指标来衡量生成的句子向量,并证明了文本的语义空间也满足:alignment值越低且uniformity值越低,向量表示的质量越高,在STS任务上的Spearman相关系数越高。

博客:理解对比学习和SimCSE,就看这6个知识点


多模态运用对比学习

博客、论文:吊打BERT、GPT、DALL·E,跨模态榜单新霸主诞生!

构建图片文字pairs,针对pairs做数据增强,再运用对比学习。

用对比学习来优化句子向量的表示

论文、博客:美团在ACL2021上提出基于对比学习的文本表示模型,效果提升8%
论文发现:直接从BERT导出的句向量表示往往被约束在一个很小的区域内,表现出很高的相似度,因而难以直接用于文本语义匹配。Bert导出的句向量(不经过Fine-tune,对所有词向量求平均)质量较低,甚至比不上Glove的结果。

该论文用数据增强的方式为:对Embedding层做数据增强
并得出结论:Token Shuffle > Token Cutoff >> Feature Cutoff ≈ Dropout >> None
在这里插入图片描述
Contrastive Loss Layer为进行对比学习的层。

batch_size的对比学习损失函数

论文:Simpler, Faster, Stronger: Breaking The log-K Curse On Contrastive Learners With FlatNCE
由于对比学习希望拉大正负样本对的得分差,通常直接用交叉熵作为损失:
− log ⁡ e s t ∑ i e s i = log ⁡ ( ∑ i e s i ) − s t -\log \frac{e^{s_{t}}}{\sum_{i} e^{s_{i}}}=\log \left(\sum_{i} e^{s_{i}}\right)-s_{t} logiesiest=log(iesi)st
− log ⁡ e s t ∑ i e s i = log ⁡ ∑ i e s i e s t = log ⁡ ( 1 + ∑ i ≠ t e s i e s t ) = log ⁡ ( 1 + ∑ i ≠ t e s i − s t ) -\log \frac{e^{s_{t}}}{\sum_{i} e^{s_{i}}}=\log \frac{\sum_i e^{s_i}}{e^{s_t}}=\log(1 + \frac{\sum_{i \neq t}e^{s_i}}{e^{s_t}})=\log \left(1+\sum_{i \neq t} e^{s_{i}-s_{t}}\right) logiesiest=logestiesi=log(1+esti=tesi)=log1+i=tesist
其中, e s t e^{s_t} est为正样本对的得分, e s i e^{s_i} esi为所有样本对的得分,当然,除了一个正样本,其他都是负样本。

ξ = ∑ i ≠ t e s i − s t \xi=\sum_{i \neq t} e^{s_{i}-s_{t}} ξ=i=tesist,即使是一开始, e s t e^{s_t} est一般也较大于 e s i e^{s_i} esi,则 e s i − s t ≈ 0 e^{s_{i}-s_{t}} \approx 0 esist0 又因为batch_size较小,所以 i i i也较少,则 ξ ≈ 0 \xi\approx0 ξ0

ξ \xi ξ接近0,损失函数也接近0,对应的的梯度也接近0,但梯度更新量不接近0,因为  梯度   梯度  ⊗  梯度  × 学 习 率 \frac{\text { 梯度 }}{\sqrt{\text { 梯度 } \otimes \text { 梯度 }}} \times 学习率  梯度  梯度   梯度 ×,更新量就会保持着 学 习 率 学习率 的数量级。

对比学习希望 e s t e^{s_t} est e s i e^{s_i} esi相差大,即 e s i − s t → 0 e^{s_{i}-s_{t}} \rightarrow 0 esist0,即 s i − s t → − ∞ s_{i}-s_{t} \rightarrow-\infty sist,但对比学习的打分( s i {s_i} si)通常是余弦值除以温度参数,所以它是有界的, s i − s t → − ∞ s_{i}-s_{t} \rightarrow-\infty sist是无法实现的。然而, ξ \xi ξ的计算本身就存在浮点误差,当 ξ \xi ξ很接近于 0 时,浮点误差可能比精确值还要大,然后 log ⁡ ( 1 + ξ ) \log(1+\xi) log(1+ξ)的计算也会存在浮点误差,再然后梯度的计算也会存在浮点误差,这一系列误差累积下来,很可能导致最后算出来的梯度都接近于随机噪声了,而不能提供有效的更新指引。

解决方法:

对函数做一阶展开: log ⁡ ( 1 + ∑ i ≠ t e s i − s t ) ≈ ∑ i ≠ t e s i − s t \log \left(1+\sum_{i \neq t} e^{s_{i}-s_{t}}\right) \approx \sum_{i \neq t} e^{s_{i}-s_{t}} log1+i=tesisti=tesist, ξ \xi ξ就相当于损失函数, ξ \xi ξ乘以一个常数,其梯度不变,则梯度更新量不变,这样, ξ \xi ξ就变大了。

我们使其乘以 ξ \xi ξ的倒数, s g ( ξ ) sg(\xi) sg(ξ)是stop_gradient,不计算导数的意思。
∇ θ ( ξ sg ⁡ ( ξ ) ) = ∇ θ ξ ξ = ∇ θ log ⁡ ξ \nabla_{\theta}\left(\frac{\xi}{\operatorname{sg}(\xi)}\right)=\frac{\nabla_{\theta} \xi}{\xi}=\nabla_{\theta} \log \xi θ(sg(ξ)ξ)=ξθξ=θlogξ
推导上式的时候,注意分母的 ξ \xi ξ为常数。

我们把损失函数变为: log ⁡ ( ∑ i ≠ t e s i − s t ) = log ⁡ ( ∑ i ≠ t e s i ) − s t \log \left(\sum_{i \neq t} e^{s_{i}-s_{t}}\right)=\log \left(\sum_{i \neq t} e^{s_{i}}\right)-s_{t} logi=tesist=logi=tesist
l o g ∘ s u m ∘ e x p log\circ sum \circ exp logsumexp通常可以有效地计算,浮点误差不会占主导。

实验结果

在这里插入图片描述
作者提出的FlatNCE在小batch_size上效果比较好,在大batch_size上收敛的也比较快。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值