作者 | 对白 整理 | 对白的算法屋 编者寄语:
这可能是面试中被问到对比学习时最常考的点了。
卷友们好,我是对白。
最近在知乎上看到这样一个问题:基于对比学习(Contrastive Learning)的文本表示模型为什么能学到语义相似度?
这个问题还比较的新颖,回答的人数不超过5个,而这个问题也问得非常好,我直拍大腿,他肯定是一位精通技术的面试官,所以就连我也没有立刻回答上来。
于是,我匆忙翻出了自己的笔记本,哆哆嗦嗦地开始整理着。在一番总结与思考后,我羞涩的写下了自己人生中第一个技术回答(我的第一次QAQ),哈哈开玩笑,那让我们看一下这个问题怎样回答才能征服这位面试官吧。 写在前面
有监督训练的典型问题,就是标注数据是有限的。
目前NLP领域的经验,自监督预训练使用的数据量越大,模型越复杂,那么模型能够吸收的知识越多,对下游任务效果来说越好。这可能是自从Bert出现以来,一再被反复证明。
所以对比学习的出现,是图像领域为了解决“在没有更大标注数据集的情况下,如何采用自监督预训练模式,来从中吸取图像本身的先验知识分布,得到一个预训练的模型”
对比学习是自监督学习的一种,也就是说,不依赖标注数据,要从无标注图像中自己学习知识。
目前,对比学习貌似处于“无明确定义、有指导原则”的状态,它的指导原则是:通过自动构造相似实例和不相似实例,要求习得一个表示学习模型,通过这个模型,使得相似的实例在投影空间中比较接近,而不相似的实例在投影空间中距离比较远。
为什么对比学习能学到很好的语义相似度?
因为对比学习的目标就是要从数据中学习到一个优质的语义表示空间
众所周知,直接用BERT句向量做无监督语义相似度计算效果会很差,这个问题还没搞清楚的可以看我的这篇回答:BERT模型可以使用无监督的方法做文本相似度任务吗?
前不久的BERT-flow通过normalizing flow将向量分布映射到规整的高斯分布上,更近一点的BERT-whitening对向量分布做了PCA降维消除冗余信息,但是标准化流的表达能力太差,而白化操作又没法解决非线性的问题,有更好的方法提升表示空间的质量吗?正好,对比学习的目标之一就是学习到分布均匀的向量表示,因此我们可以借助对比学习间接达到规整表示空间的效果。
那么如何评价这个表示空间的质量呢?Wang and Isola (2020)提出了衡量对比学习质量的两个指标:Alignment和Uniformity:
- Alignment计算xi和xi 的平均距离;
- 而Uniformity计算向量整体分布的均匀程度。
我们希望这两个指标都尽可能低,也就是一方面希望正样本要挨得足够近,另一方面语义向量要尽可能地均匀分布在超球面上,因为均匀分布信息熵最高,分布越均匀则保留的信息越多。于是通过对比学习获得的语义向量,自然而然效果就更好了。
“拉近正样本,推开负样本”实际上就是在优化这两个指标。
下面来看一下语义相似度SOTA模型SimCSE,由陈丹琦发布,它将对比学习的思想引入到sentence embedding中,大幅刷新了有监督和无监督语义匹配SOTA,更让人惊叹的是,无监督SimCSE的表现在STS基准任务上甚至超越了包括SBERT在内的所有有监督模型。
另外一位网友知乎@小莲子的回答也很不错,他的思路比较逆向,希望对大家有另外一番启发。
作者:小莲子@知乎 链接:https://www.zhihu.com/question/480187938/answer/2103245373
我最近在做对比学习相关的实践,折腾了好久,调来调去效果一般,甚是烦躁。以下主要是一些个人的体会,思路会比较逆向。
回答这个问题,要从语义相似度计算的一般范式说起。计算句子A和句子B的语义相似度,通常来说,基于交互的方案结果更准确:
如果一共有N个句子,那么就需要进行 N × (N-1) 次相似度计算。在绝大多数的工程落地场景中,这样的计算开销都是无法被接受的。因此,建模只能转向基于表示的“两步走”方案:
每个输入句子,先要经过一个编码器进行量化,再由一个轻量级的判定模块进行相似度输出。这样设计的好处是,偏“重”的编码部分可以离线计算并缓存结果,只需计算 N 次。相似度判定部分,虽然仍是 N × (N-1) 次计算,但采用的是余弦等非神经网络的形式,即使放在线上实时进行也可以承受。
这样“前重后轻”的结构,缺乏两个句子间的深度交互。前置神经网络在编码时,无法提前获知当前句子将和什么样的目标句子做比较,难以判断语义建模的重点是在哪个文本片段。比如,以下是 SemEval-2016 的一组标题:
A: Mandela's condition has 'improved'(曼德拉的状态有所好转) B: Mandela's condition has 'worsened over past 48 hours'(曼德拉在过去48小时每况愈下)
单看 A 句,如果编码器将句子抽象为“曼德拉的状况波动”,似乎也可以接受,但是结合 B 句一起看,就出现了严重的信息取舍错误。
总结来说,由于使用了不可学习的余弦相似度作为度量,并且完全去除了编码部分的交互耦合,基于表示的方案无法进行 task-specific 式的模型学习。语义相似度的求解,转换成了一个单纯的特征映射过程:编码器提取输入句子的语义信息,再将它投影到向量空间中。‘
这有点像传统机器学习领域的问题。在理想情况下,所有句子在该空间的分布,应当满足 alignment 和 uniformity。即,语义相似的句子彼此聚集,语义无关的句子均匀分布。
为了达成这一目标,模型需要尽可能多地提前认识各种各样的数据。鉴于训练数据不好找,只能自行构造,于是诞生了“自监督训练”,“对比学习”也是其中的一种形式。这套流程最早是从计算机视觉里来的,用于图像向量化:
通过人为进行数据增强,让模型抵抗表层噪声,聚焦核心信息。回到 NLP 里,也有类似方法:
自监督通常主要有两类,一种是生成式,比如经典的 Mask-LM;一种是这里用的分类式。对于某个句子 X,按照上述流程构建“正例对”(X,X'),从 batch 里随机一个其他句子构建“负例对”(X,Y)。如此一来,便可以批量生产训练数据。
我自己在实践的时候,起初比较偷懒,就是这样直接处理的。正例对的相似度为1,负例对的相似度为0。但是,学习效果很差,和以往单句场景的经验完全不一致。我猜测,真正的标注训练数据相比,构造而成的“伪样本对”有两个隐患:
1. 针对性不强:正样本由数据增强生成,丰富度有限;负样本随机配对,暗含[任意组合都输出0]的错误诱导;
2. 标签不准确:没有经过人工校对,正样本的相似度未必就是1,很有可能只有0.5或者干脆就完全相反;负样本也极有可能随机到语义相似的句子;
因此,需要明确分类标签的交叉熵,就不适合作为相似度自监督任务的损失函数。我们需要一种更宽松的约束条件,来达成更准确的学习目标。对比学习正是如此,它的核心诉求是:
配套的损失函数,有点像排序问题,是一个多路的softmax交叉熵,称为 InfoNCE。假设有1个正例组合(X,X')和N个负例组合(X,Y):
在 loss->0的时候,log内部->1,分子和分母互相逼近,由于含有共同的部分(X,X'),会让正例得分越来越大,负例越来越小,从而拉开彼此的差距。也就是常说的“正例拉近,负例推远”,正好契合语义特征空间 alignment 和 uniformity 的目标。
现在,不知道大家是否知道正确答案了,有不懂得可以留言哦。
我是你们的对白,我们一起加油!
你好,我是对白,硕士毕业于清华,现大厂算法工程师,拿过八家大厂的SSP级以上offer。
高中荣获全国数学和化学竞赛二等奖。
本科时独立创业五年,成立两家公司,并拿过总计三百多万元融资(已到账),项目入选南京321高层次创业人才引进计划。创业做过无人机、机器人和互联网教育,保研后选择退居为股东。
我每周至少更新一篇原创,分享自己的算法技术、创业心得和人生感悟。