深入解析 InfoNCE Loss:对比学习的基石
在现代机器学习领域,尤其是无监督学习和表示学习中,对比学习(Contrastive Learning)已经成为一种非常流行的方法。它的核心在于通过构造正样本和负样本对,学习数据的潜在表示。其中,InfoNCE Loss 是一种广泛使用的损失函数,不仅在《Representation Learning with Contrastive Predictive Coding》中被提出,还被大模型如 CLIP(Contrastive Language-Image Pretraining)所采用。今天,我们将深入探讨 InfoNCE Loss 的原理、数学推导以及它为何如此强大。
第一次被提出的原论文:https://arxiv.org/pdf/1807.03748
什么是 InfoNCE Loss?
InfoNCE 全称是 Info Noise-Contrastive Estimation Loss,是一种基于噪声对比估计(Noise-Contrastive Estimation, NCE,具体可以参考笔者的另一篇博客:噪声对比估计(Noise-contrastive estimation, NCE):如何高效估计未归一化统计模型的参数?)的损失函数。它最初由 Michael Gutmann 和 Aapo Hyvärinen 在 2010 年提出,用于估计未归一化的概率分布,而在对比学习中,它被用来最大化正样本对之间的相似性,同时最小化与负样本的相似性。
在《Contrastive Predictive Coding (CPC)》论文中,作者将其用于无监督表示学习,目标是让模型从高维数据中提取有用的表示。简单来说,InfoNCE Loss 的核心思想是:通过对比正样本和一组负样本,训练模型区分“相关”和“不相关”的数据对,从而捕获数据的深层语义信息。
其数学定义如下:
L N = − E X [ log f k ( x t + k , c t ) ∑ x j ∈ X f k ( x j , c t ) ] \mathcal{L}_{\text{N}} = -\mathbb{E}_{X} \left[ \log \frac{f_k(x_{t+k}, c_t)}{\sum_{x_j \in X} f_k(x_j, c_t)} \right] LN=−EX[log∑xj∈Xfk(xj,ct)fk(xt+k,ct)]
其中:
- ( X = { x 1 , … , x N } X = \{x_1, \ldots, x_N\} X={x1,…,xN}) 是一个样本集,包含一个正样本(来自 ( p ( x t + k ∣ c t ) p(x_{t+k} | c_t) p(xt+k∣ct)))和 ( N − 1 N-1 N−1) 个负样本(来自 ( p ( x t + k ) p(x_{t+k}) p(xt+k)))。
- ( f k ( x t + k , c t ) f_k(x_{t+k}, c_t) fk(xt+k,ct)) 是一个评分函数,表示正样本对 (( x t + k , c t ) x_{t+k}, c_t) xt+k,ct)) 的匹配程度。
- ( ∑ x j ∈ X f k ( x j , c t ) \sum_{x_j \in X} f_k(x_j, c_t) ∑xj∈Xfk(xj,ct)) 是正样本和所有负样本评分的总和。
这个形式看起来像是分类问题的交叉熵损失,但它实际上是在解决一个更复杂的任务:估计数据的条件分布与独立分布之间的密度比。
InfoNCE Loss 的直觉
为了理解 InfoNCE Loss,我们先从它的目标说起。在 CPC 中,模型希望通过预测未来的潜在表示(latent representation)来学习数据的结构。具体来说:
- ( c t c_t ct) 是当前时刻的上下文表示(由自回归模型生成)。
- ( x t + k x_{t+k} xt+k) 是未来的观测数据。
- 模型的目标是让 ( c t c_t ct) 和 ( x t + k x_{t+k} xt+k) 之间的表示保留尽可能多的互信息(Mutual Information, MI)。
直接建模 ( p ( x t + k ∣ c t ) p(x_{t+k} | c_t) p(xt+k∣ct))(条件概率分布)在高维数据中非常困难,因为它需要生成数据的每一个细节。而 InfoNCE Loss 的巧妙之处在于,它不直接建模 ( p ( x t + k ∣ c t ) p(x_{t+k} | c_t) p(xt+k∣ct)),而是估计一个密度比:
f k ( x t + k , c t ) ∝ p ( x t + k ∣ c t ) p ( x t + k ) f_k(x_{t+k}, c_t) \propto \frac{p(x_{t+k} | c_t)}{p(x_{t+k})} fk(xt+k,ct)∝p(xt+k)p(xt+k∣ct)
这个密度比衡量的是 ( x t + k x_{t+k} xt+k) 在给定 ( c t c_t ct) 的条件下出现的可能性,相比它独立出现的可能性。如果 ( x t + k x_{t+k} xt+k) 和 ( c t c_t ct) 高度相关,这个比值会很大;如果不相关,则接近 1 或更小。
通过最大化正样本的评分 ( f k ( x t + k , c t ) f_k(x_{t+k}, c_t) fk(xt+k,ct)) 相对于所有样本评分之和的比例,InfoNCE Loss 实际上是在训练模型识别“真正相关的样本对”。
数学推导:为何它有效?
让我们一步步推导 InfoNCE Loss 的工作原理。
1. 分类任务的视角
InfoNCE Loss 可以看作一个分类问题:给定上下文 ( c t c_t ct) 和样本集 ( X X X)(包含一个正样本和多个负样本),模型需要正确识别哪个是正样本。假设正样本是 ( x t + k x_{t+k} xt+k),损失函数是交叉熵的形式(下文有详细解释):
L N = − E X [ log f k ( x t + k , c t ) ∑ x j ∈ X f k ( x j , c t ) ] \mathcal{L}_{\text{N}} = -\mathbb{E}_{X} \left[ \log \frac{f_k(x_{t+k}, c_t)}{\sum_{x_j \in X} f_k(x_j, c_t)} \right] LN=−EX[log∑xj∈Xfk(xj,ct)fk(xt+k,ct)]
这里的 ( f k ( x t + k , c t ) ∑ x j ∈ X f k ( x j , c t ) \frac{f_k(x_{t+k}, c_t)}{\sum_{x_j \in X} f_k(x_j, c_t)} ∑xj∈Xfk(xj,ct)fk(xt+k,ct)) 可以看作模型预测正样本的“概率”。优化这个损失就是在最大化正样本的预测概率。
2. 最优解与密度比
论文中证明,当 ( f k ( x t + k , c t ) f_k(x_{t+k}, c_t) fk(xt+k,ct)) 达到最优时,它会逼近密度比 ( p ( x t + k ∣ c t ) p ( x t + k ) \frac{p(x_{t+k} | c_t)}{p(x_{t+k})} p(xt+k)p(xt+k∣ct))。我们来看看这个推导:
假设 ( X X X) 中有一个正样本 ( x t + k x_{t+k} xt+k)(来自 ( p ( x t + k ∣ c t ) p(x_{t+k} | c_t) p(xt+k∣ct)))和 ( N − 1 N-1 N−1) 个负样本(来自 ( p ( x t + k ) p(x_{t+k}) p(xt+k)))。对于正样本正确分类的概率,最优解是贝叶斯公式推导出的条件概率:
p ( d = i ∣ X , c t ) = p ( x i ∣ c t ) ∏ l ≠ i p ( x l ) ∑ j = 1 N p ( x j ∣ c t ) ∏ l ≠ j p ( x l ) p(d=i | X, c_t) = \frac{p(x_i | c_t) \prod_{l \neq i} p(x_l)}{\sum_{j=1}^N p(x_j | c_t) \prod_{l \neq j} p(x_l)} p(d=i∣X,ct)=∑j=1Np(xj∣ct)∏l=jp(xl)p(xi∣ct)∏l=ip(xl)
化简后:
p ( d = i ∣ X , c t ) = p ( x i ∣ c t ) p ( x i ) ∑ j = 1 N p ( x j ∣ c t ) p ( x j ) p(d=i | X, c_t) = \frac{\frac{p(x_i | c_t)}{p(x_i)}}{\sum_{j=1}^N \frac{p(x_j | c_t)}{p(x_j)}} p(d=i∣X,ct)=∑j=1Np(xj)p(xj∣ct)p(xi)p(xi∣ct)
当 ( f k ( x t + k , c t ) = p ( x t + k ∣ c t ) p ( x t + k ) f_k(x_{t+k}, c_t) = \frac{p(x_{t+k} | c_t)}{p(x_{t+k})} fk(xt+k,ct)=p(xt+k)p(xt+k∣ct)) 时,InfoNCE Loss 的预测概率正好匹配这个最优值,表明它确实在估计密度比。
3. 与互信息的关系
具体可以参考笔者的另一篇博客:什么是互信息(Mutual Information, MI)?互信息与 InfoNCE Loss:对比学习的深层联系
InfoNCE Loss 的另一个强大之处在于,它与互信息(Mutual Information, MI)有直接联系。互信息的定义是:
I ( x t + k , c t ) = ∑ x , c p ( x , c ) log p ( x ∣ c ) p ( x ) I(x_{t+k}, c_t) = \sum_{x, c} p(x, c) \log \frac{p(x | c)}{p(x)} I(xt+k,ct)=x,c∑p(x,c)logp(x)p(x∣c)
论文中证明了一个下界:
I ( x t + k , c t ) ≥ log ( N ) − L N I(x_{t+k}, c_t) \geq \log(N) - \mathcal{L}_{\text{N}} I(xt+k,ct)≥log(N)−LN
这意味着,最小化 ( L N \mathcal{L}_{\text{N}} LN) 实际上是在最大化 ( I ( x t + k , c t ) I(x_{t+k}, c_t) I(xt+k,ct)) 的下界。随着负样本数量 ( N N N) 增加,这个下界会越来越紧。因此,InfoNCE Loss 不仅能区分正负样本,还能让表示保留更多的共享信息。
在 CPC 中的实现
在 CPC 中,InfoNCE Loss 被具体化为一个 log-bilinear 模型:
f k ( x t + k , c t ) = exp ( z t + k T W k c t ) f_k(x_{t+k}, c_t) = \exp(z_{t+k}^T W_k c_t) fk(xt+k,ct)=exp(zt+kTWkct)
其中:
- ( z t + k = g enc ( x t + k ) z_{t+k} = g_{\text{enc}}(x_{t+k}) zt+k=genc(xt+k)) 是未来观测的潜在表示。
- ( c t = g ar ( z ≤ t ) c_t = g_{\text{ar}}(z_{\leq t}) ct=gar(z≤t)) 是当前上下文的表示。
- ( W k W_k Wk) 是预测 ( k k k) 步未来的线性变换。
通过这种形式,模型将高维数据压缩到潜在空间,并在潜在空间中进行预测和对比,从而避免直接处理复杂的 ( p ( x t + k ∣ c t ) p(x_{t+k} | c_t) p(xt+k∣ct))。
在 CLIP 中的应用
具体可以参考笔者的另一篇博客:InfoNCE 在 CLIP 中的应用原理(代码实现):为什么用交叉熵F.cross_entropy来实现?
CLIP(由 OpenAI 提出)也使用了类似的 InfoNCE Loss 来联合训练图像和文本表示。它的目标是让匹配的图像-文本对(正样本)得分更高,而不匹配的(负样本)得分更低。具体来说:
- 对于一个批次中的图像 ( I i I_i Ii) 和文本 ( T i T_i Ti),CLIP 计算它们的嵌入相似度(如余弦相似度)。
- InfoNCE Loss 被应用到图像到文本和文本到图像两个方向,确保双模态表示对齐。
这种方法让 CLIP 在零样本分类等任务中表现出色,证明了 InfoNCE Loss 在跨模态学习中的普适性。
总结
InfoNCE Loss 是对比学习中的一颗明珠,它通过对比正负样本对,巧妙地估计密度比并最大化互信息。它的优点包括:
- 高效性:无需建模高维数据的完整分布。
- 通用性:适用于图像、文本、音频等多种模态。
- 理论支持:与互信息有明确的数学联系。
从 CPC 到 CLIP,InfoNCE Loss 已经成为无监督和自监督学习的基石。理解它的原理,不仅能帮助我们更好地设计模型,还能启发我们在更多场景中探索对比学习的潜力。
如何拉近正样本,拉远负样本的距离?
详细解释为什么 InfoNCE Loss 可以看作交叉熵的形式,以及它如何通过优化最大化正样本的预测概率并拉远负样本的距离。
为什么是交叉熵的形式?
InfoNCE Loss 的表达式是:
L N = − E X [ log f k ( x t + k , c t ) ∑ x j ∈ X f k ( x j , c t ) ] \mathcal{L}_{\text{N}} = -\mathbb{E}_{X} \left[ \log \frac{f_k(x_{t+k}, c_t)}{\sum_{x_j \in X} f_k(x_j, c_t)} \right] LN=−EX[log∑xj∈Xfk(xj,ct)fk(xt+k,ct)]
这个形式与分类任务中的交叉熵损失非常相似。我们可以从分类问题的角度来理解它:
-
分类任务的设定:
- 假设你有一个样本集 ( X = { x 1 , x 2 , … , x N } X = \{x_1, x_2, \ldots, x_N\} X={x1,x2,…,xN} ),其中 ( x t + k x_{t+k} xt+k ) 是正样本(与上下文 ( c t c_t ct ) 相关),其余 ( N − 1 N-1 N−1 ) 个样本是负样本(与 ( c t c_t ct ) 无关)。
- 模型的任务是从 ( X X X ) 中正确识别出正样本 ( x t + k x_{t+k} xt+k )。这本质上是一个多分类问题:从 ( N N N ) 个候选样本中挑出“正确”的那一个。
-
预测“概率”:
- 在 InfoNCE 中,( f k ( x t + k , c t ) f_k(x_{t+k}, c_t) fk(xt+k,ct) ) 表示正样本对 ( ( x t + k , c t ) (x_{t+k}, c_t) (xt+k,ct) ) 的匹配得分(通常是通过某种相似性函数计算的,比如点积或余弦相似度)。
- 分母 ( ∑ x j ∈ X f k ( x j , c t ) \sum_{x_j \in X} f_k(x_j, c_t) ∑xj∈Xfk(xj,ct) ) 是所有样本(一个正样本加 ( N − 1 N-1 N−1 ) 个负样本)的得分总和。
- 因此,( f k ( x t + k , c t ) ∑ x j ∈ X f k ( x j , c t ) \frac{f_k(x_{t+k}, c_t)}{\sum_{x_j \in X} f_k(x_j, c_t)} ∑xj∈Xfk(xj,ct)fk(xt+k,ct) ) 可以看作模型预测 ( x t + k x_{t+k} xt+k ) 是正样本的“概率”。它是一个归一化的值,介于 0 和 1 之间,类似于 softmax 函数的输出。
-
交叉熵的连接:
- 在标准的分类问题中,交叉熵损失衡量的是模型预测概率分布与真实分布之间的差异。对于一个多分类问题,真实标签是一个 one-hot 向量(比如 (
[
1
,
0
,
0
,
…
,
0
]
[1, 0, 0, \ldots, 0]
[1,0,0,…,0] ) 表示第一个类别是正确的),交叉熵损失是:
L = − ∑ i = 1 N y i log ( p i ) L = -\sum_{i=1}^N y_i \log(p_i) L=−i=1∑Nyilog(pi)
其中 ( y i y_i yi ) 是真实标签(1 或 0),( p i p_i pi ) 是模型预测的概率。 - 在 InfoNCE 的场景中,我们假设正样本 (
x
t
+
k
x_{t+k}
xt+k ) 的标签是 1,其余负样本的标签是 0。因此,理想的真实分布是只有正样本的“概率”为 1,其余为 0。InfoNCE Loss 的形式:
− log f k ( x t + k , c t ) ∑ x j ∈ X f k ( x j , c t ) -\log \frac{f_k(x_{t+k}, c_t)}{\sum_{x_j \in X} f_k(x_j, c_t)} −log∑xj∈Xfk(xj,ct)fk(xt+k,ct)
正是交叉熵的一种特例:它只对正样本的预测概率取负对数,等价于在 one-hot 标签下的交叉熵损失。
- 在标准的分类问题中,交叉熵损失衡量的是模型预测概率分布与真实分布之间的差异。对于一个多分类问题,真实标签是一个 one-hot 向量(比如 (
[
1
,
0
,
0
,
…
,
0
]
[1, 0, 0, \ldots, 0]
[1,0,0,…,0] ) 表示第一个类别是正确的),交叉熵损失是:
-
期望的引入:
- ( E X \mathbb{E}_{X} EX ) 表示对样本集 ( X X X ) 的期望,因为每次训练时正样本和负样本的组合是从数据分布中随机采样的。加上期望后,InfoNCE Loss 成为对所有可能样本组合的平均交叉熵损失。
因此,InfoNCE Loss 的形式本质上是将对比学习任务转化为一个分类问题,并用交叉熵来优化模型,使其学会区分正样本和负样本。
如何最大化正样本的预测概率并拉远负样本的距离?
InfoNCE Loss 的优化目标是通过最小化 ( L N \mathcal{L}_{\text{N}} LN ),间接实现两个效果:
- 最大化正样本的预测概率。
- 拉远负样本的距离(即减小负样本的得分影响)。
我们逐步分析这个过程:
1. 最大化正样本的预测概率
- 损失函数中的核心项是 ( f k ( x t + k , c t ) ∑ x j ∈ X f k ( x j , c t ) \frac{f_k(x_{t+k}, c_t)}{\sum_{x_j \in X} f_k(x_j, c_t)} ∑xj∈Xfk(xj,ct)fk(xt+k,ct) ),我们希望这个“概率”尽可能接近 1(因为正样本是正确的选择)。
- 要让这个分数接近 1,分子 ( f k ( x t + k , c t ) f_k(x_{t+k}, c_t) fk(xt+k,ct) )(正样本的得分)必须远大于分母中其余负样本的得分之和 ( ∑ x j ≠ x t + k f k ( x j , c t ) \sum_{x_j \neq x_{t+k}} f_k(x_j, c_t) ∑xj=xt+kfk(xj,ct) )。
- 最小化 ( − log -\log −log ) 的形式意味着最大化这个分数本身(因为 ( − log ( x ) -\log(x) −log(x) ) 是单调递减函数,( x x x ) 越大,( − log ( x ) -\log(x) −log(x) ) 越小)。因此,优化 ( L N \mathcal{L}_{\text{N}} LN ) 会推动模型增加 ( f k ( x t + k , c t ) f_k(x_{t+k}, c_t) fk(xt+k,ct) ),也就是提高正样本对的匹配得分。
2. 拉远负样本的距离
- 分母 ( ∑ x j ∈ X f k ( x j , c t ) \sum_{x_j \in X} f_k(x_j, c_t) ∑xj∈Xfk(xj,ct) ) 包含了正样本和所有负样本的得分总和。如果负样本的得分 ( f k ( x j , c t ) f_k(x_j, c_t) fk(xj,ct) )(其中 ( x j ≠ x t + k x_j \neq x_{t+k} xj=xt+k ))很高,分母会变大,导致正样本的“概率”变小,损失 ( − log -\log −log ) 项变大。
- 为了最小化损失,模型必须尽量减小负样本的得分 ( f k ( x j , c t ) f_k(x_j, c_t) fk(xj,ct) )。在表示学习中,( f k f_k fk ) 通常是某种相似性度量(比如 ( z t + k T W k c t z_{t+k}^T W_k c_t zt+kTWkct )),减小负样本得分意味着在潜在空间中拉远负样本与上下文 ( c t c_t ct ) 的距离,或者说让它们的表示更不相似。
- 这样,正样本的得分相对更高,负样本的干扰更小,模型就能更好地聚焦于“相关”的数据对。
3. 几何视角:潜在空间的分离
- 如果我们把 (
f
k
(
x
,
c
t
)
f_k(x, c_t)
fk(x,ct)) 看作潜在表示之间的内积(比如 (
z
x
T
z
c
z_x^T z_c
zxTzc )),优化 InfoNCE Loss 就是在潜在空间中调整表示:
- 正样本对 ( ( x t + k , c t ) x_{t+k}, c_t) xt+k,ct) ) 的表示 ( z t + k z_{t+k} zt+k ) 和 ( z c t z_{c_t} zct ) 被拉近(内积变大)。
- 负样本对 ( ( x j , c t ) (x_j, c_t) (xj,ct) ) 的表示 ( z j z_j zj ) 和 ( z c t z_{c_t} zct) 被推远(内积变小)。
- 这种“拉近正样本、推远负样本”的过程,正是对比学习的核心思想:让模型学会区分相关和不相关的数据对。
4. 动态平衡
- InfoNCE Loss 的美妙之处在于,它通过一个统一的损失函数同时实现了这两个目标。分子和分母的比值形式确保了正样本得分和负样本得分的相对关系不断被优化,而不需要显式地分开处理正样本和负样本的损失。
举个例子说明
假设 ( f k f_k fk ) 是余弦相似度,样本集 ( X X X ) 有 1 个正样本和 2 个负样本:
- 正样本得分:( f k ( x t + k , c t ) = 0.9 f_k(x_{t+k}, c_t) = 0.9 fk(xt+k,ct)=0.9 )。
- 负样本得分:( f k ( x 1 , c t ) = 0.5 f_k(x_1, c_t) = 0.5 fk(x1,ct)=0.5 ),( f k ( x 2 , c t ) = 0.4 f_k(x_2, c_t) = 0.4 fk(x2,ct)=0.4 )。
- 分母:( 0.9 + 0.5 + 0.4 = 1.8 0.9 + 0.5 + 0.4 = 1.8 0.9+0.5+0.4=1.8 )。
- “概率”:( 0.9 1.8 = 0.5 \frac{0.9}{1.8} = 0.5 1.80.9=0.5 ),损失:( − log ( 0.5 ) ≈ 0.693 -\log(0.5) \approx 0.693 −log(0.5)≈0.693 )。
优化目标是减小这个损失:
- 如果模型提高正样本得分到 0.95,同时降低负样本得分到 0.3 和 0.2:
- 分母变为 ( 0.95 + 0.3 + 0.2 = 1.45 0.95 + 0.3 + 0.2 = 1.45 0.95+0.3+0.2=1.45 ),
- “概率”变为 ( 0.95 1.45 ≈ 0.655 \frac{0.95}{1.45} \approx 0.655 1.450.95≈0.655 ),损失减小到 ( − log ( 0.655 ) ≈ 0.423 -\log(0.655) \approx 0.423 −log(0.655)≈0.423 )。
- 这说明正样本的预测概率上升了,负样本的影响减少了。
总结
InfoNCE Loss 通过交叉熵的形式,将对比学习转化为一个分类任务。优化这个损失会:
- 最大化正样本的预测概率:通过增加 ( f k ( x t + k , c t ) f_k(x_{t+k}, c_t) fk(xt+k,ct) ) 提高分子。
- 拉远负样本的距离:通过减小 ( ∑ x j ≠ x t + k f k ( x j , c t ) \sum_{x_j \neq x_{t+k}} f_k(x_j, c_t) ∑xj=xt+kfk(xj,ct) ) 降低分母中负样本的贡献。
这种机制让模型在潜在空间中学习到更有区分度的表示,非常适合无监督和自监督学习任务。
后记
2025年3月29日20点35分于上海,在grok 3大模型辅助下完成。