Skip to content

InfoNCE 损失

Li=logexp(s(qi,ki+)/τ)exp(s(qi,ki+)/τ)+m=1Mexp(s(qi,ki,m)/τ)

这里:s(qi,k) 表示相似度函数。它可以是点积,也可以是余弦相似度。τ 是温度参数,用来控制 softmax 的“尖锐程度”。

这个损失到底在做什么

可以把 InfoNCE 想成一道“单选题”。

给定一个 query(qi),模型面前有很多候选 k。其中只有一个候选 ki+ 是正确答案,其余都是错误答案。InfoNCE 做的事情非常简单:

它要求模型给“正确答案”最高分。 分数高了以后,softmax 算出来的“正确答案概率”就会更大;这个概率越大,损失就越小。

所以它本质上就是一个“在一堆候选里把正确项分出来”的多分类交叉熵。原始 CPC 论文也明确把它解释成 categorical cross-entropy:模型要正确识别哪一个样本是正样本。

公式

先定义:

zj=s(qi,kj)τ

那么 softmax 概率就是:

pj=ezjez

其中,正样本对应的概率是:

p+=exp(s(qi,ki+)/τ)jexp(s(qi,kj)/τ)

于是损失就变成:

Li=logp+

这三步可以这样理解:

分子只看“正确答案”的分数。 分母看“所有候选”的总分。 两者一除,就得到“模型认为正确答案有多大概率是对的”。

所以:

  • 如果模型真的把正样本和 query 配得很近,那么 p+ 会接近 1,损失会很小。
  • 如果模型把负样本错当成更像的候选,那么 p+ 会变小,损失就会变大。

一个很小的数字例子

假设某个 query 有 3 个候选,分数分别是:

  • 正样本:3
  • 负样本 1:1
  • 负样本 2:0

并且先取 τ=1

那么:

p+=e3e3+e1+e020.0920.09+2.72+10.84

于是损失是:

L=log0.840.17

这个值很小,说明模型分得不错。

如果反过来,正样本分数只有 1,某个负样本分数是 3,那就会变成:

p+=e1e1+e3+e02.722.72+20.09+10.11

于是:

L=log0.112.21

这个值就很大,说明模型分错得比较明显。

所以你会发现,InfoNCE 并不关心“分数绝对有多大”,它真正关心的是:

正样本的分数,是否比其他候选更大。


温度 τ

τ 控制 softmax 的“敏感程度”。

τ 比较小时,softmax 会更尖锐,模型会更关注那些“最难分”的负样本; 当 τ 比较大时,softmax 会更平缓,训练会更温和一些。

CLIP 论文里也专门把这个温度作为一个会影响 logits 范围的量,并且不是手工固定,而是直接学习一个可训练的缩放参数。

“拉近正样本、推远负样本”

zj=s(qi,kj)τ,pj=softmax(z)j

那么有:

Liz+=p+1

对负样本 j+

Lizj=pj

这组式子的意思其实很直白:

对正样本来说,梯度会把它的分数往上推; 对负样本来说,梯度会把它们的分数往下压。

而且,哪个负样本当前更“像正样本”,也就是哪个 pj 更大,哪个就会被压得更厉害。 这就是为什么大家常说 InfoNCE 会特别在意 hard negatives

如果相似度是点积 s(q,k)=qk,那还可以继续得到:

Liqi=1τ(jpjkjki+)

即:

query 会被拉向正样本,同时被推离那些高相似度的负样本。


在 CLIP 里怎么用

CLIP 不是只做“图像去找文本”,而是同时做两个方向:

  • image text
  • text image

具体来说,给定一个 batch 的 N 对图文样本,CLIP 会先把图像和文本都映射到同一个向量空间,再计算两两相似度矩阵。论文里明确写的是:它最大化真实图文对的余弦相似度,最小化错误配对的相似度,并对这些分数做 symmetric cross-entropy loss

常见写法可以记成:

zij=αcos(ii,tj)

其中 α 是可学习的缩放项。CLIP 的图像向量和文本向量会先归一化,所以这里本质上是在用“缩放后的余弦相似度”。

然后分别做两个方向的损失:

Limg=1Ni=1Nlogexp(zii)j=1Nexp(zij)Ltext=1Ni=1Nlogexp(zii)j=1Nexp(zji)

最后取平均:

L=Limg+Ltext2

所以对 CLIP 来说,一个 batch 内所有图像都要找到正确文本,所有文本也都要找到正确图像。

在 DPR 里怎么用

给定一个问题 qi,模型会有:

  • 一个正文档 pi+
  • 若干负文档 pi,1,pi,2,,pi,M

DPR 论文直接把损失写成:

Li=logexp(sim(qi,pi+))exp(sim(qi,pi+))+m=1Mexp(sim(qi,pi,m))

而且 DPR 里常用的相似度就是 inner product。论文还明确讨论了 in-batch negatives:也就是一个 batch 里别的问题对应的正 passage,可以拿来当当前问题的负样本。

所以 DPR 可以一句话记成:

给问题一个向量,给文档一个向量,让正确文档的分数在 softmax 里尽量最大。


更深一层:为什么它叫 “InfoNCE”

从论文历史上说,InfoNCE 这个名字来自 CPC。CPC 不只是把它当成一个排序损失,还给了它一个信息论视角:在一定条件下,最优打分函数对应一个密度比,而且这个损失可以给 mutual information 提供下界。原论文写成:

I(xt+k,ct)logNLN

这说明:当 InfoNCE 变小的时候,模型保留下来的“有用共享信息”会变多。

一句话记忆

InfoNCE 就是“把正确配对当成正确类别”的 softmax 交叉熵。

再直白一点:

让 query 更像正样本,不像负样本。