CoSENT(二):特征式匹配与交互式匹配有多大差距?
By 苏剑林 | 2022-01-12 | 83257位读者 |一般来说,文本匹配有交互式(Interaction-based)和特征式(Representation-based)两种实现方案,其中交互式是指将两个文本拼接在一起当成单文本进行分类,而特征式则是指两个句子分别由编码器编码为句向量后再做简单的融合处理(算cos值或者接一个浅层网络)。通常的结论是,交互式由于使得两个文本能够进行充分的比较,所以它准确性通常较好,但明显的缺点是在检索场景的效率较差;而特征式则可以提前计算并缓存好句向量,所以它有着较高的效率,但由于句子间的交互程度较浅,所以通常效果不如交互式。
上一篇文章笔者介绍了CoSENT,它本质上也是一种特征式方案,并且相比以往的特征式方案效果有所提高。于是笔者的好胜心就上来了:CoSENT能比得过交互式吗?特征式相比交互式的差距有多远呢?本文就来做个比较。
自动阈值 #
在文章《CoSENT(一):比Sentence-BERT更有效的句向量方案》中,我们评测CoSENT所用的指标是Spearman系数,它是一个只依赖于预测结果相对顺序的指标,不依赖于阈值,比较适合检索场景的评测。但如果评测指标是accuracy或者F1这些分类指标,则必须确定一个阈值,将预测结果大于这个数的预测结果视为正、小于则为负,然后才能计算指标。在二分类的场景,我们用二分法就可以有效地确定这个阈值。
然而,搜索阈值确实并非二分类所独有,一般的多分类任务其实也存在着同样的需求,所以这里将这个问题展开来谈谈。比如对于$n$分类的预测分布$[p_1,p_2,\dots,p_n]$,我们一般是用概率最大的类别,即$\mathop{\text{argmax}}\,(p_1,p_2,\dots,p_n)$作为预测类别,但如果是类别不均衡的场景,这样做其实未必是最优的。我们可以通过验证集来搜索一个向量$[t_1,t_2,\cdots,t_n]$,然后用
\begin{equation}\mathop{\text{argmax}}\,(p_1 t_1,p_2 t_2,\dots,p_n t_n)\end{equation}
作为预测类别,这里的$[t_1,t_2,\cdots,t_n]$就相当于是多类别场景下的阈值。
那么,怎么搜索出$[t_1,t_2,\cdots,t_n]$呢?搜索目标自然是指标最大,但accuracy或者F1这些都是不可导的,因此梯度下降肯定是不考虑了;而又因为待搜索参数是一个多维向量,所以二分法也不大好用。这里介绍一种名为“Powell法”的求解方案。Powell法的数学细节比较多,这里不打算展开,简单来说,Powell法是一种求解低维无约束优化的算法,它不需要梯度,并且效率也相对较高,这里低维指的是待优化参数通常不超过100个(你总不能指望它去求解神经网络)。最关键是,Powell法在Scipy中有现成实现,在scipy.optimize.minimize
中指定method='Powell'
即可调用它。
对于上述问题,参考代码如下:
import numpy as np
from scipy.optimize import minimize
def loss(t):
"""这里的y_true.shape=[batch_size],
y_pred.shape=[batch_size, num_classes]
"""
t = (np.tanh(t) + 1) / 2
return -np.mean(y_true == (y_pred * t[None]).argmax(1))
options = {'xtol': 1e-10, 'ftol': 1e-10, 'maxiter': 100000}
result = minimize(
loss, np.zeros_like(y_pred[:1]), method='Powell', options=options
)
thresholds = (np.tanh(result.x) + 1) / 2
实验结果 #
有了自动确定阈值的方法后,我们就可以检验分类性能了。笔者在ATEC、BQ、LCQMC、PAWSX这4个数据集上做了实验,分别对比了CoSENT、Sentence-BERT和交互式(记为Interact)三种方案的效果。公平起见,每种方法都用Powell法在验证集上确定最优阈值,然后用该阈值报告测试集的效果,哪怕交互式的也是如此。
实验结果如下(指标是accuracy):
\begin{array}{c|cccc|c}
\hline
& \text{ATEC} & \text{BQ} & \text{LCQMC} & \text{PAWSX} & \text{Avg}\\
\hline
\text{BERT+CoSENT} & \textbf{85.81} & 83.24 & 86.67 & 76.30 & 83.00 \\
\text{Sentence-BERT} & 84.93 & 82.46 & 87.42 & 65.33 & 80.04\\
\text{BERT+Interact} & 85.49 & \textbf{83.88} & \textbf{87.80} & \textbf{81.30} & \textbf{84.62} \\
\hline
\text{RoBERTa+CoSENT} & 85.93 & 83.42 & 87.63 & 76.55 & 83.38 \\
\text{Sentence-RoBERTa} & 85.34 & 82.52 & 88.14 & 68.35 & 81.09 \\
\text{RoBERTa+Interact} & \textbf{86.04} & \textbf{83.62} & \textbf{88.22} & \textbf{83.33} & \textbf{85.30} \\
\hline
\end{array}
实验结果显示,从效果上来看,交互式确实是“王者”地位,但是特征式(CoSENT和Sentence-BERT/RoBERTa)的效果差距并没有笔者想象中大。客观来说,在ATEC和BQ两个任务上,交互式Interact与特征式CoSENT并无显著差异,而在LCQMC任务上,交互式Interact与特征式Sentence-BERT/RoBERTa并无显著差异。
唯一拉开明显差距的是PAWSX,在《无监督语义相似度哪家强?我们做了个比较全面的评测》、《中文任务还是SOTA吗?我们给SimCSE补充了一些实验》中我们可以发现,几乎所有无监督句向量方法都在PAWSX上失效。为什么呢?因为PAWSX的负样本几乎全是“对抗样本”,就是字面重叠度非常高但语义却不同的负样本。所以,对于这种无监督方法“全线崩溃”的“高难”负样本,哪怕用标注数据去训练,也自然需要更深层的交互才能更好地识别出来。
理论极限 #
有些读者可能会好奇:能否通过理论分析出特征式方案的理论极限呢?可能让人意外的是,这个分析其实不难,而答案是:
理论上来说,交互式能做到的效果,特征式“几乎”都能做到。
怎么得到这个结果呢?事实上用本博客以往介绍过的文章就足够了。首先,我们假定样本对的相似度在0~1之间,并且样本对是无序的,即$\text{sim}(x,y)=\text{sim}(y,x)$,那么如果有$n$个样本,那么我们每两个样本之间算相似度(不管实际的相似度是怎么算来的),就得到一个相似度矩阵$S$,它是一个“正定对称矩阵”(或者严格点,是半正定)。按照线性代数的结果,正定对称矩阵的SVD分解必然是$S=U\Lambda U^{\top}$的形式,其中$U$是正交矩阵而$\Lambda$是对角阵,那么我们有$S=U\Lambda U^{\top}=(U\sqrt{\Lambda})(U\sqrt{\Lambda})^{\top}$。这就表明了,正定对称矩阵一定可以分解为$S=BB^{\top}$的形式,这等价于说,每个样本$i$可以表示为一个$n$维向量$v_i$,使得$S_{i,j}=\langle x_i, y_j\rangle$。
至此,所有的结果都是有理论保证并且精确相等的,只不过目前的“$n$维向量”实在是太大了,所以接下来应该往降维角度想。此时,我们去年介绍过的“JL引理”(参考《让人惊叹的Johnson-Lindenstrauss引理:理论篇》)就可以登场了,它告诉我们,别管原来是多少维的,$n$个向量都可以降到$\mathcal{O}(\log n)$维,而保持内积近似不变,在《让人惊叹的Johnson-Lindenstrauss引理:应用篇》中我们还近似估计了这个量级应该是$8\log n$左右,所以对于BERT base的768维向量来说,理论上通过内积来拟合上百万个样本的两两相似度都不成问题。所以,基于内积的、维度达到几百维的“特征式”方案,理论上是可以相当精确地达到交互式效果的。
那为什么在PAWSX这样的困难数据集上两者有明显差异呢?个人认为这是“神经网络和cos指标的连续性”与“文本匹配天然存在的对抗性”之间的矛盾造成的。
神经网络本身就是一个连续函数,然后编码器负责将句子压缩到一个句向量中,其结果的连续性必然是非常好的,这里的连续性,指的是句子的微小改动,导致句向量的改动也是微小的;同时,cos的连续性也非常好,即如果$\Delta v$比较小,那么$\cos(u,v)$和$\cos(u, v+\Delta v)$的差距也很小。所以,总的来说就是“特征式”的方案连续性会非常好。但问题是,人设计出来的语言天然存在对抗性,即字面上的微小改动能导致标注结果的巨大变化,经典的就是加个“不”字导致所谓的“语义反转”,说白了就是连续性并不好。
于是,在此类任务之下,连续性非常好的“特征式”方案要去拟合对抗性明显的数据集,就会非常困难。当然,前面我们已经分析过理论上是可以拟合的,所以实际上是拟合确实能拟合,但需要训练比较多的epoch来“磨”掉特征式方案原有的连续性,但比较多的epoch也造成了更严重的过拟合。因此,CoSENT的训练loss也能降到接近于0(说明拟合能力没问题),但是验证集的效果没有交互式的好。至于交互式,模型一开始就同时接触到了两个样本,在后面的层中模型可以自行拟合和放大差异,从而在交互式方案中连续性与对抗性的矛盾并没有那么严重,因而效果更好。
文章小结 #
本文从理论和实验两个角度地探讨了特征式匹配与交互式匹配的效果差距,此外还讨论了多分类问题中阈值的自动搜索问题。
转载到请包括本文地址:https://www.spaces.ac.cn/archives/8860
更详细的转载事宜请参考:《科学空间FAQ》
如果您还有什么疑惑或建议,欢迎在下方评论区继续讨论。
如果您觉得本文还不错,欢迎分享/打赏本文。打赏并非要从中获得收益,而是希望知道科学空间获得了多少读者的真心关注。当然,如果你无视它,也不会影响你的阅读。再次表示欢迎和感谢!
如果您需要引用本文,请参考:
苏剑林. (Jan. 12, 2022). 《CoSENT(二):特征式匹配与交互式匹配有多大差距? 》[Blog post]. Retrieved from https://www.spaces.ac.cn/archives/8860
@online{kexuefm-8860,
title={CoSENT(二):特征式匹配与交互式匹配有多大差距?},
author={苏剑林},
year={2022},
month={Jan},
url={\url{https://www.spaces.ac.cn/archives/8860}},
}
January 12th, 2022
请问苏神,在其他部分相同的情况下,同为特征式,
①encoder使用【参数共享的bert(类似孪生网络)】与【参数不共享的bert双塔(类似dssm)】两种策略,准确性在理论上有优劣吗?
②参数共享的方式,可以理解为相对双塔具备一些非显式的interact吗?
③或者两种策略有不同的适用场景?比如文本对(x,y),{x}和{y}其实是不同的东西,比如(标题,正文)、(问题,答案),这种情况若用特征式,是用双塔比较好吗?
④CoSent使用了参数共享的策略,单纯是为了方便和sentence-bert对比吗?还是参数共享确实比较有优势?
提出的上述问题有重叠,您不必一一回复。
要算相似度的两个对象是同一空间的东西(比如都是query),并且你希望$\text{sim}(x,y)=\text{sim}(y,x)$,那么参数共享是一种很自然的选择。
如果你要算相似度的东西不是同一空间的,但没有明显交集,比如query和answer,虽然属于不同类型的文本,但可以认为query和answer基本没交集,这时候用参数共享通常也不错。
如果不是上述两种情形,那么用参数共享通常是不合理的。但是参数完全不共享效果通常也不好。比较合理的做法是共享前面的大部分,剩下后面小部分不共享。
非常感谢您的经验分享
关于dual encoder网络参数是否共享及共享程度对模型效果的影响,Google挂出了一篇arxiv文章,跟博主观点类似,供参考
https://arxiv.org/pdf/2204.07120.pdf
January 12th, 2022
最近在思考一个问题,用相似度做多标签分类问题:
假设原句子:小明喜欢唱歌和打游戏。
这句话与句子1:小明喜欢唱歌(对应的标签唱歌),以及句子2:小明喜欢打游戏(对应的标签打游戏),都相似。
当作多标签分类来做,用了您的多标签分类loss,acc达到90。
但是当作相似度去做,基于特征匹配的acc为0,并且loss来回震荡,不收敛(个人感觉可能是我的batch小了);基于交互的方法的acc为50%,loss趋于0。
基本模型都是bert,或者sentence-bert。
acc的计算方法是所有的标签都分对才算一个正例。
这是不是意味着如果我的标签固定,分类的方法一定比相似度的方法效果好?
您有没有做过类似的实验,把相似度的问题当作分类来做然后对比效果的差距。
你当作相似度任务时,正负样本对分别是怎么构建的?
正负样本 :句子 ,标签,选取的负标签。句子大概20个字符,标签大概2到4个字符。
正样本是标注的,负样本是按照字面相似度大于某一个阈值构建的,刚开始用triplet loss,效果也是0。感觉普通的分类问题,用相似度能解决是因为训练样本之间来开了距离,而且训练样本只属于一个簇,但是多标签是不是就不太好拉开距离,它可能属于多个簇。还有可能不属于它们其中的任意一个。
我理解你这里的“标签”是标准的单句吗?我其实是不理解你怎么既可以多标签分类,又可以文本匹配来做?这两者是怎么转化的?最好举个例子,同一组样本,在多标签分类里边是怎样的,在文本匹配中又是怎么转换的?
数据集是:句子 label_1 label_2 ...(多个标签)
label_i 是一个固定集合(这就是一个普通的多标签分类数据集)
例如:小明喜欢打游戏和唱歌 对应的标签是 打游戏 唱歌。
label set:(打游戏,唱歌,打篮球,唱戏曲)
正常情况就是多标签进行分类
预测出的结果是[1,1,0,0]为正确
如果预测出来的结果[1,0,0,0]则为错误。
评价指标是acc。
使用匹配的方式:
用句子:小明喜欢打游戏和唱歌 与 标签:打游戏 进行相似度计算——>得到 相似
用句子:小明喜欢打游戏和唱歌 与 标签:唱歌 进行相似度计算——>得到 相似
用句子:小明喜欢打游戏和唱歌 与 标签:打篮球 进行相似度计算——>得到 不相似
用句子:小明喜欢打游戏和唱歌 与 标签:唱戏曲 进行相似度计算——>得到 不相似
我的具体应用场景是,在做KBQA的时候,属性或者关系可能动态增加,用分类的方法没法满足。
这样的话我就理解了,那是你一开始的例子误导我了。
感觉应该能做到一定程度的,但目前没有类似数据集可以尝试,如果你对应的数据集可以公开,那么我可以尝试做一下。
是的,标签固定,分类方法比相似度要好,而且要好很多,如果使用相似度的方法来做分类,不仅需要标签是query类的性质(如果对标签进行query编码),而且需要处理很多细节,特别是负样本的构建,即使这样,也比分类差很多,分类的难点是标签无法动态增加。
按照我的经验,使用特征式进行语义相似度匹配时候,你的参数或者loss有问题,没有合理设置,所以才会导致这个结果,建议再仔细调整下,以免得出错误结论,
January 12th, 2022
相似矩阵S的秩会收到压缩维度$n$的制约,这就是为什么interaction-based better than encoding-based
但事实上,如果你对任意一个句向量模型(包括有监督训练好的)的协方差矩阵做SVD时,你会发现大部分的奇异值都接近于0,这意味着768维里边大部分维度都是冗余的。一方面我们说特征式的交互程度不够效果不好,另一方面又浪费了那么多维度,所以这显然是一个训练问题而不是能力问题。
这样说吧,我认为那些所谓的"浪费的维度"就是为了数据集中的难样本,对于大部分样本确实用不到这么高的维度,但是对于一些难样本,比如你举得“对抗样本”的例子,这些维度甚至可能远远不够。
首先,你得用完,然后才说不够。
我说的大量浪费维度,在PAWSX有监督训练过之后依然存在。所以,我的推论是,这是一个训练问题,不是一个能力问题。
January 13th, 2022
蘇大有沒有試過嵌入雙曲空間?
https://arxiv.org/abs/1705.08039
雙曲空間有一個性質是:
當測量點越靠近邊界的時候,點與點之間的距離會呈指數增長。
因此樹結構天然就可以嵌入雙曲空間,
而具有層級結構的語言文字應該也很適合。
越靠近原點的詞表示越抽象、越廣泛;
而越靠近邊界的詞就越特定、越明確。
那若將句子嵌入雙曲空間呢?
句子是有一群單字組成,這群單字構成了上下文,同時決定了單字的意義。
因此一個句子應該是比一個單字更特定,明確表達某個意義,
嵌入雙曲空間後,應該位在邊界的末端。
而若任兩個句子,雖然字面上高度重疊,但語意上差距很大,
例如只差一個「不」字,可能雖然句向量的夾角只差一點,
但位在雙曲空間邊界的末端,就相隔非常大的距離。
其實我認為,「夾角」跟「距離」應該是兩種不同的衡量方式。
若兩個向量夾角很小,但是離原點很遠,那他們之間的距離也會變得很長。
所以單從 cos similarity 來看的話,
無監督訓練可能特別容易讓語法結構相似的句子向量夾角很小,
從而出現語意差很大但cos相似度卻很高的情況;
但是若看向量間的距離,兩個結構很像的句子,
因為語意不同,有可能距離是差很遠的。
在此我提出一個想法是:
有沒有可能訓練時把句子結構跟語意解偶?
例如訓練的時候,用一個指標衡量句子結構的相似程度,用另外一個指標來衡量語意的相似程度。
這樣是否就有可能解決兩個句子只差一個「不」字的問題?
因為我把語法結構的部份分離了,那剩下的就是語意的相似程度。
這樣似乎可以解決你的說的:
> 即如果$\Delta v$比较小,那么$\cos(u,v)$和$\cos(u, v+\Delta v)$的差距也很小
的問題。
因為這個 $\Delta v$ 的部份被從句子結構的部份分離出來,剩下語意的成份,
若單比較語意不比較結構,兩者的差異就容易顯現出來了。
如此,端看我們的檢索任務:
若是要搜尋語意相似的句子,則使用語意的指標;
若是要搜尋結構相似的句子,則使用結構的指標;
也可以搜尋結構相似,但語意相同或不同的句子;
或結構不類似,但語意相同或不同的句子。
例如有時候使用者想搜尋一個句子,是真的想找字面上、結構上類似的句子,未必在意語意;
但有時候使用者想找的是語意上類似,字面上盡可能看起來不同的句子,類似換句話說的句子。
我想這是很合理的情境,但是在現有的相似度計算中,好像都未加以區分?
谢谢提示。之前有浏览到相关文章,一直没深入学习过,最近可以学学。
至于分解指标,我倒是想过将一个句子表示为多个低维向量$[u_1,\cdots,u_k]$,然后用所有cos的乘积$\cos(u_1, v_1)\cdots\cos(u_k,u_k)$来算相似度,或许能解决这个问题,但还没有实验。
这个做法会不会和colbert比较像,https://arxiv.org/abs/2004.12832
只不过colbert不是想乘 而是sum_max操作。
学习了,是有点相似。
關於指標分解,我初步的想法是這樣的:
可以用edit distance 作為兩個句子的結構相似度指標,
如果你說的這句話是對的:
> PAWSX的负样本几乎全是“对抗样本”,就是字面重叠度非常高但语义却不同的负样本
那這類困難樣本的 edit distance 應該比較小,
而其他比較容易的樣本,edit distance 應該比較大。
因為edit distance 衡量的是一個字串如何經過固定步驟(刪去、插入、搬移...等)變換成目標字串。步驟越少的,距離越小。
定義當兩個句子完全相同時,edit distance 為 0 時,我們可以做如下合理假設:
1. 0 < edit distance < threshold_1:
兩個句子語意相反的機率較高,因為通常語意相反只需要加上幾個否定詞,而不需要大幅修改句構
2. threshold_1 < edit distance < threshold_2:
兩個句子語意相似的機率較高,因為兩個句子如果不是一模一樣,又要他們意思相似,那就是所謂的"換句話說"。通常在換句話說的時候,人會採用比較不同的句構方式,所以edit distance反而會變大
3. edit distance > threshold_2:
兩個句字無關的機率較高
因此可以看到,我們直覺認為的語意相似度,如你上一篇所講的:
> 对于NLI数据而言,它有“蕴含”、“中立”、“矛盾”三种标签,我们自然可以认为两个“蕴含”的句子相似度大于两个“中立”的句子,而两个“中立”的句子相似度大于两个“矛盾”的句子
是「自己 > 蘊含 > 中立 > 矛盾」,其中「自己」就是同個句子自己跟自己比。
但是從 edit distance 來看,會變成「自己 < 矛盾 < 蘊含 < 中立」,此處定義的是距離越小越相似,所以符號變成小於,但重點是排列的順序跟我們的語意直覺是完全不同的。
回顧 SimCSE 這個無監督方法,會發現:
它所採用的正樣本對是 $\{自己,自己\}$,
負樣本對是 $\{自己,別人\}$,
這個"別人"是只要有字面上不一樣就算別人。
根據相似度數值的連續性,很自然的,
字面上越靠近"自己"的越相似;字面上跟自己越不同的越不相似。
這樣衡量相似度的方式應該更接近edit distance,而非 semantic distance。
如果上述推論是對的,
用edit distance來衡量相似度的順序,
應該是:
自己 > 相反 > 相似 > 無關
並非我們直覺認為的:
自己 > 相似 > 無關 > 相反
這樣就可以解釋為什麼無監督的效果不好了,因為訓練目標根本不同。
而有監督訓練效果之所以好,是因為他的標註設計本來就符合人類的語言直覺,訓練出來的結果自然是符合直覺的順序。
那要怎麼做才能夠無監督的學習到語意相似度,而非結構相似度呢?
我嘗試提出一種可能的方向:
令兩個句子的句向量為 $S_1$, $S_2$,$d_e(S_1, S_2)$ 為 edit similarity,而 $d_s(S_1, S_2)$ 為 semantic similarity。
當兩個句子結構上越相似,也就是 $d_e$ 越大時,可以認為總體相似度越大,反之亦然;而當兩個句子語意上越像似,也就是 $d_s$ 越大時,可以認為總體相似度應該也越大,反之亦然。所以定義總體相似度 $T(S_1, S_2)$ 正比於 $d_e * d_s$。
我們發現當 $d_e$ 越高時,字面的重疊度也越高,這限制了$d_s$的範圍。
例如 $S_1 = 今天天氣很好$,$S_2 = 今天天氣很好$,顯然 $d_e$ 有最大值,同時 $d_s$ 也是最大值;
而 $S_1 = 今天天氣很好$,$S_2 = 今天天氣很不錯$,顯然 $d_e$ 很高,同時 $d_s$ 也很高;
但是當句子變成:$S_1 = 今天天氣很好$,$S_2 = 今天天氣很不好$ 時,顯然 $d_e$ 很高,但 $d_s$ 必須要降低才行。可是由於大部分的樣本都是 $d_e$ 很高同時$d_s$ 也很高,而在無監督的情況下,我們也不能直接告訴他甚麼時候 $d_e$ 很高但 $d_s$ 要低,所以模型學到的大部分都是前兩個例子,而無法區分第三種例子。
我認為這很像生成模型的多樣性問題,因為計算 $d_s$ 需要 $S_1$ 跟 $S_2$ 的句向量,而encoder負責生成句向量。今天如果 $\{今天天氣很好, 今天天氣很不錯, 今天天氣很不好\}$ 這三句話的句向量差異不大,那麼無論怎麼計算,$d_s$ 數字都是非常接近的。
但是如果我們能夠增加encoder生成的多樣性,讓 $\{今天天氣很好, 今天天氣很不錯, 今天天氣很不好\}$ 這三句話的向量差異盡可能大,但是又不能大到像隨機生成毫無關聯,因此我們需要兩個loss:
1. 最大化$d_e$
2. 最大化encoder生成句向量的熵
1. 意味著encoder要盡可能幫字面上相似的句子生成相似的句向量,才能最大化$d_e$
2. 意味著encoder要盡可能生成差異大的句向量,才有可能得到差異較大的 $d_s$
我認為SimCSE 只做了1.,但沒有做到2.。
可能的改進方法是,假設句向量輸出$d$維:
前$d/2$維用字面重疊較低的negative sample做SimCSE,表示大部分的結構差異資訊都會encode到前$d/2$維,而後再用全部$d$維以字面重疊較高的negative sample做SimCSE,再加上全部$d$維最大熵的結果是,因為前$d/2$維encode了大量結構資訊,所以前$d/2$維差異很小,但是由於最大熵條件,必須盡可能增加多樣性,因此差異的部分會跑到後$d/2$維中。於是就能夠利用後$d/2$維encode非結構上的差異,我認為那應該就是語義的資訊。
其中,negative sample 的字面重疊高低,可以利用一些現有的 edit distance 演算法來估計,預先做篩選,所以這一步是無監督的。設定一個threshold ,小於這個threshold 的為重疊率高的樣本,大於的為重疊率低的樣本。
最大熵條件,參考EAE這篇 https://kexue.fm/archives/7343
實際使用上,我們可以用前$d/2$維的cos衡量結構相似度,後$d/2$維的cos 衡量語意相似度。如果用全部$d$維的cos,就是整體相似度。
補充:
1. 當兩個輸入句子字面上重疊很低
表示$d_e$很小。由於前$d/2$維是在重疊率較低的negative smaple 下訓練SimCSE,所以前$d/2$維已經 encode了大部份的資訊,沒有甚麼剩下的資訊留給後$d/2$維。又因最大熵條件,後$d/2$維會產生盡可能隨機的向量。在高維空間中,隨機向量彼此垂直的機率很高,因此cos 接近於0,相當於$d_s$接近0,表示彼此是無關的。這與我們的直覺相符,因為如果兩個句子天南地北不相干,根本就不會有字面重疊的部分,那也就是我們認為語意上無關的句子。
2. 當兩個輸入句子字面上重疊很高
表示$d_e$很大。由於前$d/2$維encode了大部份的資訊,重疊很高的部分應該都包含在前$d/2$維了。但是因為全部$d$維是在重疊率較高的negative sample 下訓練SimCSE,如果重疊的部分都包含在前$d/2$維,那要區別出重疊率很高的negative sample,就必須把資訊放到後$d/2$維,那麼後 $d/2$ 維就不可能完全隨機。但又因為最大熵條件,後$d/2$維必須產生盡可能不同的向量,結果就是,差異的部分,cos similarity 很靠近0,但不會是0,而會在0的兩側,要不就是正相關,要不就是負相關,而不會完全無關。
那如何保證語意相似為正相關,語意相反為負相關呢?因為全部$d$維是在重疊率較高的negative sample 下訓練SimCSE,而自己跟自己是最相似的,根據相似度的連續性,必然會把越難歸類在一起的sample相似度降低。而又根據前面的假設,語意相似的句子相較於相反的句子可能有較多不同的變形,在去除掉結構資訊後,將這些變形歸為同一類可具有較高的資訊壓縮比,因此語意相似的句向量其整體整體相似度cos similarity應該略大於語意相反的句向量,而若前$d/2$維貢獻了結構相似度的部分,那麼後$d/2$維就貢獻了語意相似度的部分,而又根據前面的推理,相似度不會是0,那就必然是語意相似 > 0,語意相反 < 0,這樣就確保了相似度跟我們的語意直覺相符。
感谢你的分享。
认真读了一下,前面关于PAWSX等困难样本在SimCSE效果差的分析颇为精彩,值得回味。
但是后面关于无监督句向量的构思,我觉得有点“走偏”了。
首先,不管是BERT-flow、BERT-whitening还是SimCSE,它们连数据扩增都没用到,所以它们句向量的所有信息,来源于BERT、RoBERTa本身的预训练。也就是说,预训练才是生成句向量的方式,而BERT-flow、BERT-whitening、SimCSE等只是让句向量能够用cos进行度量,但它们本身不会增加句向量的任何信息。
再回到你的构思,不管具体怎么去算相似度,你的想法本质上就是利用edit distance等字面相似度函数来增强SimCSE的训练,所以最终模型的“增益”,必然不会超过字面相似度所能带来的增益,而我们知道字面相似度基本上无助于解决困难样本问题。反过来说,如果它能,必然是预训练带来的,而不是引入字面相似度带来的。
所以,纯粹的无监督,我认为很难带来应对这种困难负样本对。比如你设计的思路,只能保证后$d/2$维encode的信息与结构信息“正交”(不相关),但具体是不是“语义”,无法保证。
因此,我认为这种指标分解之类的新设计用来设计有监督训练方案尚可,但无监督的困难本身不是在于指标的设计或者训练过程中的正则(最大熵),而是在训练任务的构建上必须保证有“有效的外部信息”补充进去。其实我逐渐感觉到,其实直接用cos也不是什么问题,问题是人们还没捋清楚用cos所必要的假设,无法引导无监督模型去满足这些假设,如果有可能,近来可能会补充一篇文章讨论这个问题。
> 预训练才是生成句向量的方式,而BERT-flow、BERT-whitening、SimCSE等只是让句向量能够用cos进行度量,但它们本身不会增加句向量的任何信息。
是的,我並沒有說我的方法可以在預訓練之上增加甚麼有用的信息。如果預訓練的句向量本身就無法encode句子的所有信息(包括結構及語義...等),那麼我上面的做法也沒有辦法幫助它encode更多信息。
> 比如你设计的思路,只能保证后d/2维encode的信息与结构信息“正交”(不相关),但具体是不是“语义”,无法保证。
我認為,若後d/2維既跟結構信息正交(無相關),也非隨機,如果不是語義,那這些資訊所表示的是甚麼呢?當然,這是建立在我假設語言中所包含的資訊只有結構跟語義兩種,當盡可能把結構信息抽出來後,剩下的應該就是語義信息。或許從語言學的角度,並不是那麼簡單就可以把語意跟結構二分,可能還牽涉到文法、時態...等。但是回歸到檢索任務的使用情境,最常用的相似度其實就兩種:一種是字面上的相似,另一種是語義上的相似。
從生成模型的角度來看,字面相似度越低,生成的文字多樣性就越高,但是我們又不希望漫無目的的隨機生成,所以我們在字面相似度低的條件下讓句子整體相似度盡可能大。若每個單字都是無關的,都是onehot encoding,當字面相似度很低時,其組成句子的整體相似度必然不可能大於字面相似度;但當每個單字藉由embedding產生詞向量後,就算字面相似度低,但只要詞向量中所帶的訊息很相似,整體相似度仍有可能大於字面相似度。因此當我們在字面相似度低的條件下最大化句子整體相似度時,就相當於找出在embedding space中所帶訊息最接近的句子,而非字面最接近的句子。
上面的想法反過來用在訓練分類模型上,就是我們想辦法無監督的從樣本中找出字面相似度低但所帶訊息相似的樣本。字面相似度可以用edit distance來計算,但所帶訊息的相似度就很難估計。因此我嘗試利用「困難樣本在不同的字面相似度中的分布情況具有明顯不同」這樣的假設,把向量分解成兩部分。這個假設是基於「困難樣本更多存在於字面相似度很高的樣本中」這樣的觀察。如果困難樣本在字面相似度高與字面相似度低的分布情況都一樣的話,那就沒有辦法用字面相似度把困難樣本分出來;但只要困難樣本在不同的字面相似度的分布有所不同,就有可能利用這個密度的差異,把字面相似跟語意相似分離開來。
大致上我理解你的想法。但是我觉得最终结果会相反,这样的训练方式反而有可能强化模型对字面相似度的依赖。
对于SimCSE来说,它没有正样本,或者说正样本是自身(虽然Dropout两次,但毕竟还是自身),而负样本则是batch内所有非自身样本。如果你刻意构造一些字面相似度很高的样本在同一个batch内学习,理论上来说,模型就会发现通过字面相似度就可以区分出正负样本出来(正样本只有自身,字面相似度为1;负样本为所有其他样本,字面相似度都小于1),所以此时的后$d/2$维,学习出来的才是字面特征,加上正交约束后,用简单样本训练的前$d/2$维,可能才包含某些语义特征。
我还是觉得,要提升这种句向量的质量,必须要注入“外部信息”,要不就是人工标注来新增数据,要不就是像SNCSE一样,用规则来构造数据。因为“语义相似”这个东西,它并不是一种客观规律,无监督只能做到一定程度,剩下的就纯粹是人的主观结果,连人都未必能制定并按照标准来判断相似性。
January 13th, 2022
苏大神,交互式的方法,第一个句子的segment是0,第二个句子segment是1吗,代码中的意思是全部为0,batch_segment_ids.append([0] * len(segment_ids))
没有哪条法律规定“交互式的方法,第一个句子的segment是0,第二个句子segment是1”,所以都可以尝试一下。我这里是为了统一,兼容没有segment_ids的那些模型,所以就不做区分。
谢谢问答,token_ids中的sep应该会有很强的信息区分2个句子
July 27th, 2022
苏神好,请问“在二分类的场景,我们用二分法就可以有效地确定这个阈值”,这里怎么用二分法确定阈值呢??
先初始化$f(a), f(b)$,其中$a < b$,然后算$f\left(\frac{a+b}{2}\right)$,一般来说会有$f\left(\frac{a+b}{2}\right) > f(a), f(b)$。要是$f(a) > f(b)$,那么就更新$b = \frac{a+b}{2}$;反过来$f(a) < f(b)$,则更新$a = \frac{a+b}{2}$。一般调参都是这样调的,没有太严格的理论保证。
August 6th, 2022
苏神您好,想请问在科研场景中,我们需要每次实验都在Dev set上确定最佳阈值吗?对于双塔模型例如SBERT,能否通过一次实验确定阈值,然后之后的所有实验直接使用这个阈值呢?
一般情况下不能,不同的数据集对应的阈值可能会差很远。
September 1st, 2022
你好,由于smicse的出现,想问下,目前交互式的结果是不是没有smicse的结果好?
simcse何德何能可以干掉交互式?
November 29th, 2022
相似度矩阵不一定是正定的吧,感觉应该是半正定更准确?
谢谢指出,已经调整描述。
June 28th, 2023
苏老师好,请问“实验结果如下(指标是accuracy)”这个表格中的交互式模型的结果 是基于各自的训练集训练之后test集的效果吗?
对,各训各的。这里 https://kexue.fm/archives/8847 有用同一个NLI数据训练后,在各个数据上测试的结果。