2018年,OpenAI的研究员Alec Radford正在思考一个问题:如何让神经网络理解图像和文本之间的关系,而不需要人工标注的百万级训练数据?传统的监督学习范式需要告诉模型"这是一只猫"、“那是一辆车”,但人类学习概念的方式似乎并非如此。我们通过比较和对比来理解世界——知道什么相似,什么不同,什么属于同一类别,什么截然相反。
这个思考催生了CLIP(Contrastive Language-Image Pre-training),一个通过"比较"学习的模型,在400百万图文对上训练后,实现了零样本图像分类的能力。CLIP的成功揭示了一个更深层的事实:对比学习不仅仅是一种训练技巧,它正在重塑神经网络获取表示能力的方式。
graph LR
A[样本X] --> B[编码器f]
B --> C[表示向量]
D[样本X+正样本] --> E[编码器f]
E --> F[表示向量]
G[样本X-负样本1] --> H[编码器f]
H --> I[表示向量]
J[样本X-负样本K] --> K[编码器f]
K --> L[表示向量]
C --> M[对比损失]
F --> M
I --> M
L --> M
M --> N[拉近正样本<br/>推开负样本]
style M fill:#e1f5fe
style N fill:#c8e6c9
从降维到对比:一个被低估了十五年的想法
对比学习的故事可以追溯到2006年,但它的起源甚至更早。Yann LeCun在一次推文中提到,对比学习(或者更准确地说,联合嵌入架构/Joint Embedding Architectures)早在1993年就被引入了。然而,真正让这个概念进入深度学习主流视野的,是Raia Hadsell、Sumit Chopra和Yann LeCun在2006年发表的论文《Dimensionality Reduction by Learning an Invariant Mapping》。
这篇论文解决的核心问题是:如何让神经网络学习一个映射函数,使得相似样本在低维空间中靠近,不相似样本则被推开?答案是一个被称为"对比损失"(Contrastive Loss)的损失函数。
给定一个样本对$(x_i, x_j)$,对比损失定义为:
$$\mathcal{L} = (1-y) \cdot \frac{1}{2} D^2 + y \cdot \frac{1}{2} \{\max(0, \epsilon - D)\}^2$$其中$D = |f(x_i) - f(x_j)|_2$是两个样本在嵌入空间中的欧氏距离,$y \in \{0, 1\}$表示样本对是否相似($y=0$表示相似,$y=1$表示不相似),$\epsilon$是一个边界参数,定义了不相似样本之间的最小距离。
这个看似简单的公式实际上蕴含了一个深刻的思想:学习不仅仅是记住标签,更是理解样本之间的关系。当$y=0$时,我们最小化距离;当$y=1$时,我们确保距离至少为$\epsilon$。这种"拉近推开"的机制,成为了后续所有对比学习方法的核心直觉。
InfoNCE:为什么交叉熵能解决对比学习的核心难题
早期的对比损失每次只比较一对样本——一个正样本对或一个负样本对。这种设计存在一个明显的局限:如何选择负样本?如果负样本太容易区分,模型学不到有用的表示;如果负样本太难区分(与锚点样本属于同一类但被错误标记为负样本),会引入噪声。
2018年,van den Oord等人在论文《Representation Learning with Contrastive Predictive Coding》中提出了InfoNCE损失,从根本上改变了这个局面。InfoNCE的洞察在于:与其单独处理每个负样本,不如把它们视为一个多分类问题。
graph TD
A[锚点样本X] --> B[编码器]
B --> C[查询向量q]
D[正样本X+] --> E[编码器]
E --> F[正键k+]
G[负样本X-1] --> H[编码器]
H --> I[负键k-1]
J[负样本X-K] --> K[编码器]
K --> L[负键k-K]
C --> M[相似度计算]
F --> M
I --> M
L --> M
M --> N[Softmax归一化]
N --> O[负对数似然损失]
style C fill:#bbdefb
style F fill:#c8e6c9
style I fill:#ffcdd2
style L fill:#ffcdd2
style O fill:#fff9c4
给定一个锚点样本$x$,一个正样本$x^+$,和$K-1$个负样本$\{x^-_1, \ldots, x^-_{K-1}\}$,InfoNCE损失定义为:
$$\mathcal{L}_{\text{InfoNCE}} = -\log \frac{\exp(f(x)^\top f(x^+)/\tau)}{\sum_{i=0}^{K-1} \exp(f(x)^\top f(x^-_i)/\tau)}$$其中$f(\cdot)$是编码器,$\tau$是温度参数,$x^-_0 = x^+$(即正样本也被包含在分母中)。
这个公式的美妙之处在于它与交叉熵损失的联系。在标准的$K$类分类问题中,交叉熵损失是:
$$\mathcal{L}_{\text{CE}} = -\log \frac{\exp(z_y)}{\sum_{k=1}^K \exp(z_k)}$$其中$z_k$是第$k$类的logit。如果我们把正样本看作"正确类别",把所有负样本看作"错误类别",InfoNCE就是交叉熵损失在对比学习框架下的自然推广。唯一的区别是:在传统分类中,$K$是数据集中的类别数;在对比学习中,$K$是负样本数量加一。
InfoNCE的这个视角解释了为什么对比学习能够有效利用大量负样本——它本质上是在解决一个极端多分类问题,类别数量等于批次中的样本数。当批次大小为4096时,模型需要从4095个"错误答案"中找到那一个"正确答案",这迫使编码器学习到真正有区分度的特征。
温度参数:控制学习动态的隐形之手
InfoNCE公式中的$\tau$(温度参数)虽然只是一个标量,却深刻影响着模型的学习动态。理解它的作用机制,是掌握对比学习的关键。
温度参数控制着softmax分布的"尖锐度"。当$\tau$很小时,$\exp(\text{sim}/\tau)$会放大相似度差异——本来相似度只差0.1的两个样本,经过温度缩放后可能差几十倍。这会导致模型过度关注最困难的负样本(hard negatives),即那些与锚点样本相似度较高但实际应该被区分开的样本。
反过来,当$\tau$很大时,softmax分布变得更平滑,模型对所有负样本"一视同仁",学习变得均匀但没有重点。
graph LR
subgraph 低温τ=0.05
A1[困难负样本] --> B1[梯度大<br/>强烈惩罚]
A2[简单负样本] --> B2[梯度小<br/>轻微惩罚]
end
subgraph 中温τ=0.1
C1[困难负样本] --> D1[梯度中等<br/>适度惩罚]
C2[简单负样本] --> D2[梯度中等<br/>适度惩罚]
end
subgraph 高温τ=0.5
E1[困难负样本] --> F1[梯度小<br/>轻微惩罚]
E2[简单负样本] --> F2[梯度小<br/>轻微惩罚]
end
style A1 fill:#ffcdd2
style A2 fill:#c8e6c9
style C1 fill:#fff9c4
style C2 fill:#fff9c4
style E1 fill:#c8e6c9
style E2 fill:#c8e6c9
2021年的CVPR论文《Understanding the Behaviour of Contrastive Loss》通过梯度分析揭示了温度参数的深层作用。对正样本对的梯度为:
$$\frac{\partial \mathcal{L}}{\partial \text{sim}(x, x^+)} = -\frac{1}{\tau} \left(1 - p_{\text{pos}}\right)$$对负样本对的梯度为:
$$\frac{\partial \mathcal{L}}{\partial \text{sim}(x, x^-_i)} = \frac{1}{\tau} p^-_i$$其中$p_{\text{pos}}$是模型预测正样本正确的概率,$p^-_i$是负样本$x^-_i$被预测为正样本的概率。
这个梯度分析揭示了一个关键洞察:温度参数直接控制了模型对困难负样本的惩罚强度。当温度较低时,困难负样本(相似度高,$p^-_i$大)会获得更大的梯度惩罚,模型更努力地将它们推开。当温度较高时,梯度分布更均匀,所有负样本获得的惩罚相似。
在实际应用中,温度参数通常设置在0.05到0.2之间。SimCLR在论文中报告$\tau=0.1$是最优值,CLIP也使用了类似的设置。但2025年的一篇论文《Temperature-Free Loss Function for Contrastive Learning》提出了一种新的方法,使用反双曲正切函数替代温度缩放,试图消除这个敏感的超参数。
负样本采样:对比学习的阿喀琉斯之踵
对比学习的性能高度依赖于负样本的质量。理想情况下,负样本应该:
- 与锚点样本不同类
- 但在嵌入空间中距离较近(是"困难"负样本)
这在有监督设置中相对容易——我们可以选择不同类别的样本作为负样本。但在无监督设置中,我们无法知道哪些样本属于同一类,这导致了两个问题:假负样本(False Negatives)和缺乏困难负样本。
假负样本问题
假设我们在训练一个图像编码器,锚点是一只金毛犬的图片。如果我们随机采样负样本,可能恰好采样到另一只金毛犬的图片。由于模型不知道这两张图片属于同一类,它会试图将它们推开,这与我们的目标相悖。
graph TD
A[锚点: 金毛犬] --> B[编码器]
B --> C[嵌入向量]
D[正样本: 同一张图片的增强] --> E[编码器]
E --> F[嵌入向量]
G[真负样本: 猫的图片] --> H[编码器]
H --> I[嵌入向量]
J[假负样本: 另一只金毛犬] --> K[编码器]
K --> L[嵌入向量]
C --> M[应该拉近]
F --> M
C --> N[正确推开]
I --> N
C --> O[错误推开!<br/>损害学习]
L --> O
style M fill:#c8e6c9
style N fill:#c8e6c9
style O fill:#ffcdd2
2020年,Chuang等人在论文《Debiased Contrastive Learning》中分析了这个问题。设$p^+_x(x')$是样本$x'$与锚点$x$同类的概率,$p^-_x(x')$是异类概率。在无监督设置中,我们从数据分布$p(x)$采样,但实际上:
$$p(x) = \eta^+ p^+_x(x) + \eta^- p^-_x(x)$$其中$\eta^+$是锚点类别在数据集中的比例,$\eta^- = 1 - \eta^+$。
当我们从$p(x)$采样负样本时,有$\eta^+$的概率采样到假负样本。Chuang等人提出的去偏损失通过重新加权来缓解这个问题:
$$\mathcal{L}_{\text{debiased}} = -\log \frac{\exp(f(x)^\top f(x^+)/\tau)}{\exp(f(x)^\top f(x^+)/\tau) + \mathbb{E}_{x^- \sim p^-_x}[\exp(f(x)^\top f(x^-)/\tau)]}$$其中分母的期望可以通过蒙特卡洛估计,并将采样偏差纳入考虑。
困难负样本挖掘
如何获得更多困难负样本?在自然语言处理中,SimCSE提供了一个优雅的解决方案。它使用语义文本相似度数据集(如NLI)中的"矛盾"关系对作为困难负样本——两个句子在语义上相关但表达相反的含义,这正是训练句子嵌入所需要的困难负样本。
在检索任务中,DPR(Dense Passage Retrieval)使用BM25检索器返回的前几名结果作为困难负样本。这些段落与查询在词法上相似,但并非真正相关,因此是高质量的困难负样本。
2020年,Kalantidis等人在论文《MoCHi: Mixing of Contrastive Hard Negatives》中提出了一种创造性的方法:通过混合现有负样本来合成新的困难负样本。给定查询$q$和排序后的负样本队列$Q = \{n_1, \ldots, n_K\}$(按与$q$的相似度降序排列),前$N$个是最困难的负样本$Q^N$。新的困难样本可以通过线性组合生成:
$$h = \frac{\alpha n_i + (1-\alpha) n_j}{|\alpha n_i + (1-\alpha) n_j|}$$其中$\alpha \in (0, 1)$。更进一步,可以混合查询本身:
$$h' = \frac{\beta q + (1-\beta) n_j}{|\beta q + (1-\beta) n_j|}$$其中$\beta \in (0, 0.5)$。这些合成样本位于原始样本之间的区域,代表了更困难的决策边界。
SimCLR与MoCo:两种范式,一个问题
2020年,对比学习领域出现了两个里程碑式的工作:SimCLR和MoCo。它们从不同角度解决了同一个问题——如何高效地获得大量负样本。
graph TB
subgraph SimCLR大批量策略
A1[样本X] --> B1[增强t]
A1 --> C1[增强t']
B1 --> D1[编码器]
C1 --> E1[编码器]
D1 --> F1[投影头]
E1 --> G1[投影头]
F1 --> H1[正样本对]
G1 --> H1
I1[批次中其他2N-2个样本] --> J1[负样本]
H1 --> K1[InfoNCE损失]
J1 --> K1
end
subgraph MoCo队列策略
A2[样本X] --> B2[查询编码器]
A2 --> C2[键编码器<br/>动量更新]
B2 --> D2[查询q]
C2 --> E2[键k+]
F2[历史批次样本] --> G2[键编码器]
G2 --> H2[队列K个负键]
D2 --> I2[InfoNCE损失]
E2 --> I2
H2 --> I2
end
style K1 fill:#fff9c4
style I2 fill:#fff9c4
SimCLR:大力出奇迹
SimCLR(Simple Framework for Contrastive Learning of Visual Representations)的核心思想非常直接:使用大批量训练,每个批次中的其他样本都作为负样本。
给定一个批次中的$N$个样本,每个样本经过两种不同的数据增强,产生$2N$个增强样本。对于一个增强样本,其对应的另一个增强版本是正样本,其余$2(N-1)$个样本都是负样本。损失函数为:
$$\mathcal{L}_{i,j} = -\log \frac{\exp(\text{sim}(z_i, z_j)/\tau)}{\sum_{k=1}^{2N} \mathbb{1}_{[k \neq i]} \exp(\text{sim}(z_i, z_k)/\tau)}$$SimCLR的关键发现包括:
- 数据增强至关重要:随机裁剪和颜色失真的组合最有效
- 投影头:在表示层之后添加一个MLP投影头用于对比学习,下游任务只使用表示层
- 大批量:批次大小从256增加到8192,性能持续提升
SimCLR需要大批量的原因很简单:更多的负样本意味着更困难的分类任务,迫使模型学习更好的表示。但这也带来了计算开销——大批量训练需要大量GPU内存。
MoCo:队列的智慧
MoCo(Momentum Contrast)提供了一个更优雅的解决方案:使用队列存储历史批次的表示,从而在不增加批次大小的情况下获得大量负样本。
MoCo维护一个FIFO队列,存储$K$个样本的键(key)表示。对于当前批次的查询(query),队列中的所有键都作为负样本。由于队列大小可以远大于批次大小,MoCo在负样本数量上具有天然优势。
MoCo的核心创新是动量编码器。由于队列是不可微的,无法通过反向传播更新键编码器。MoCo使用指数移动平均更新:
$$\theta_k \leftarrow m \theta_k + (1-m) \theta_q$$其中$\theta_k$是键编码器的参数,$\theta_q$是查询编码器的参数,$m \in [0, 1)$是动量系数(通常设为0.999)。
这个设计确保了队列中的键表示在训练过程中平滑变化,保持了表示的一致性。MoCo V2结合了SimCLR的MLP投影头和强数据增强,在不依赖大批量的情况下达到了SimCLR的性能。
对比学习在大模型时代的角色
对比学习在大模型时代扮演着越来越重要的角色,其应用已经超越了最初的视觉表示学习。
CLIP:连接视觉与语言
CLIP的核心思想非常简单:将图像和文本映射到同一个嵌入空间,使得匹配的图文对在空间中靠近,不匹配的对被推开。
graph LR
subgraph 批次数据
A[图像1]
B[文本1: 一只猫]
C[图像2]
D[文本2: 一只狗]
end
A --> E[图像编码器]
B --> F[文本编码器]
C --> E
D --> F
E --> G[I1嵌入]
F --> H[T1嵌入]
E --> I[I2嵌入]
F --> J[T2嵌入]
G --> K[相似度矩阵]
H --> K
I --> K
J --> K
K --> L[图像到文本损失]
K --> M[文本到图像损失]
L --> N[总对比损失]
M --> N
style K fill:#e1f5fe
style N fill:#fff9c4
CLIP使用两个编码器:一个图像编码器(如ViT)和一个文本编码器(如Transformer)。给定一个批次中的$N$个图文对,CLIP计算$N \times N$的相似度矩阵,对角线是匹配对的相似度。损失函数从两个角度计算:
- 图像到文本方向:每张图像应该与其对应文本最相似
- 文本到图像方向:每段文本应该与其对应图像最相似
CLIP的成功在于它学习了一个通用的视觉-语言表示,无需针对特定任务微调就能实现零样本分类。这背后的原理是对比学习有效地对齐了两个模态的语义空间。
句子嵌入:SimCSE的启示
SimCSE(Simple Contrastive Learning of Sentence Embeddings)将对比学习应用于句子嵌入学习,提出了一个极具洞察力的方法:使用dropout作为数据增强。
在无监督SimCSE中,同一个句子输入两次,由于BERT中的dropout,两次前向传播会产生不同的表示。这两个表示被视为正样本对,批次中的其他句子作为负样本。这种方法的妙处在于:
- 无需额外的数据增强策略
- Dropout自然地引入了噪声,保留了语义不变性
- 实现极其简单,但效果显著
有监督SimCSE则使用NLI数据集中的蕴涵和矛盾关系:蕴涵对作为正样本,矛盾对作为困难负样本。这展示了对比学习如何将先验知识(语义关系)融入训练过程。
密集检索:RAG的基石
检索增强生成(RAG)依赖于高质量的密集检索,而密集检索的核心正是对比学习训练的嵌入模型。
DPR(Dense Passage Retrieval)使用双编码器架构:一个查询编码器和一个段落编码器。训练时,给定一个查询$q$、一个相关段落$p^+$和若干不相关段落$\{p^-_i\}$,InfoNCE损失确保查询与相关段落的表示接近:
$$\mathcal{L} = -\log \frac{\exp(\text{sim}(f_q(q), f_p(p^+))/\tau)}{\sum_{i} \exp(\text{sim}(f_q(q), f_p(p^-_i))/\tau)}$$对比学习使得检索器能够捕捉语义相似性,而非仅仅依赖词法匹配。这是RAG系统能够回答复杂查询的基础。
表征对齐与均匀性:理解对比学习的几何本质
2020年,Wang和Isola在论文《Understanding Contrastive Representation Learning through the Lens of Alignment and Uniformity》中提出了一个优雅的理论框架,从几何角度理解对比学习。
他们指出,理想的表示应该满足两个属性:
对齐性(Alignment):相似样本的表示应该接近。这直接对应于对比损失中对正样本对的拉近操作。
均匀性(Uniformity):样本的表示应该在超球面上均匀分布。这确保了表示空间被充分利用,不同语义的样本能够被区分。
graph TB
subgraph 初始状态
A1[样本A]
B1[样本B相似]
C1[样本C相似]
D1[样本D不同]
E1[样本E不同]
style A1 fill:#bbdefb
style B1 fill:#bbdefb
style C1 fill:#bbdefb
style D1 fill:#ffcdd2
style E1 fill:#c8e6c9
end
subgraph 对齐性操作
A2[样本A] --> F[拉近相似样本]
B2[样本B] --> F
C2[样本C] --> F
F --> G[相似样本聚集]
end
subgraph 均匀性操作
H[推开所有样本]
I[样本分布均匀化]
J[最大化超球面利用]
H --> I --> J
end
subgraph 最终状态
K[相似样本聚集]
L[不同样本均匀分布]
M[表示空间充分利用]
style K fill:#c8e6c9
style L fill:#fff9c4
style M fill:#e1f5fe
end
均匀性可以用以下损失衡量:
$$\mathcal{L}_{\text{uniform}} = \log \mathbb{E}_{x,y \sim p_{\text{data}}} \left[ e^{-t |f(x) - f(y)|_2^2} \right]$$其中$t > 0$是一个缩放因子。
这个理论框架揭示了对比学习的深层机制:通过拉近正样本对实现语义聚类,通过推开负样本实现表示空间的均匀利用。均匀性确保了模型不会将所有样本映射到同一个点(模型崩塌),这是自监督对比学习需要防范的核心问题。
局限性与未来方向
尽管对比学习取得了巨大成功,它仍面临若干挑战:
批量大小依赖
SimCLR等方法需要大批量才能获得足够的负样本,这限制了其在资源受限场景下的应用。MoCo的队列机制部分缓解了这个问题,但引入了表示陈旧性(staleness)——队列中的表示来自旧版本的编码器。
假负样本问题
在无监督设置中,假负样本问题仍然是一个开放挑战。虽然去偏损失可以部分缓解,但完全消除假负样本的影响仍然困难。
语义粒度
对比学习的正负样本定义依赖于任务。在图像分类中,同一张图片的不同增强是正样本对;但在细粒度分类中,同一类别不同子类的样本可能应该被视为负样本。如何定义合适的语义粒度,是对比学习应用的关键考量。
理论理解
虽然对齐-均匀性框架提供了有价值的视角,但对比学习为什么能学到好的表示?负样本的具体作用机制是什么?这些问题的完整理论回答仍在发展中。
结语
从2006年的降维问题到今天的多模态大模型,对比学习走过了近二十年的演进历程。它的核心理念——通过"比较"学习表示——看似简单,却蕴含着深刻的认识论直觉:理解一个概念,往往需要理解它不是什么。
InfoNCE损失将这个直觉转化为数学形式,温度参数提供了控制学习动态的杠杆,而负样本采样策略决定了表示质量的上限。SimCLR的大批量策略和MoCo的队列机制从两个方向解决了负样本数量问题,CLIP和SimCSE则展示了对比学习在多模态和文本领域的强大能力。
在大模型时代,对比学习已经成为训练视觉-语言模型、句子嵌入模型和密集检索器的核心技术。它不是传统监督学习的替代品,而是一种补充范式——当我们有大量无标注数据,或者需要学习跨模态对齐时,对比学习提供了无可替代的价值。
理解对比学习,就是理解现代表示学习的核心逻辑。它告诉我们要关注的不是单个样本的标签,而是样本之间的关系;不是记住具体的类别,而是理解什么是相似,什么是不同。这或许是更接近人类学习本质的方式。
参考文献
- Hadsell, R., Chopra, S., & LeCun, Y. (2006). Dimensionality Reduction by Learning an Invariant Mapping. CVPR.
- van den Oord, A., Li, Y., & Vinyals, O. (2018). Representation Learning with Contrastive Predictive Coding. arXiv:1807.03748.
- Chen, T., et al. (2020). A Simple Framework for Contrastive Learning of Visual Representations. ICML.
- He, K., et al. (2020). Momentum Contrast for Unsupervised Visual Representation Learning. CVPR.
- Radford, A., et al. (2021). Learning Transferable Visual Models From Natural Language Supervision. ICML.
- Gao, T., Yao, X., & Chen, D. (2021). SimCSE: Simple Contrastive Learning of Sentence Embeddings. EMNLP.
- Karpukhin, V., et al. (2020). Dense Passage Retrieval for Open-Domain Question Answering. EMNLP.
- Wang, F., & Isola, P. (2020). Understanding Contrastive Representation Learning through the Lens of Alignment and Uniformity. ICML.
- Wang, F., et al. (2021). Understanding the Behaviour of Contrastive Loss. CVPR.
- Chuang, C.Y., et al. (2020). Debiased Contrastive Learning. NeurIPS.
- Kalantidis, Y., et al. (2020). Hard Negative Mixing for Contrastive Learning. NeurIPS.
- Grill, J.B., et al. (2020). Bootstrap Your Own Latent: A New Approach to Self-Supervised Learning. NeurIPS.