副标题 / 摘要
InfoNCE 是现代对比学习的核心损失,SimCLR 则把它推向实用化。本文用公式、步骤与最小实验,带你理解“批内负样本 + 增强视图”的训练逻辑。
- 预计阅读时长:18~22 分钟
- 标签:
infonce、simclr、self-supervised - SEO 关键词:InfoNCE, SimCLR, 对比学习, 自监督
- 元描述:讲清 InfoNCE 的数学目标与 SimCLR 的训练结构,含可运行代码示例。
系列导航
- (1/4)对比损失 Contrastive Loss
- (2/4)三元组损失 Triplet Loss
- (3/4)InfoNCE + SimCLR(本文)
- (4/4)CLIP 对比学习目标
目标读者
- 希望入门自监督对比学习的读者
- 需要理解 SimCLR 训练流程的工程实践者
- 想把对比学习迁移到业务数据的开发者
背景 / 动机
有标注数据昂贵,而无标注数据充足。
InfoNCE 让我们用“正负样本对齐”替代人工标签,
SimCLR 则证明:只要数据增强和 batch 够大,效果可以接近监督学习。
核心概念
- 正样本视图:同一图像的两种增强视图。
- 批内负样本:同一 batch 中其他样本视为负样本。
- 投影头:把表示映射到对比空间,提高对比学习效果。
A — Algorithm(题目与算法)
用通俗语言说明主题内容
InfoNCE 的核心是“在一堆负样本里找到正确配对”。
SimCLR 则把“正确配对”定义为同一张图像的两个增强视图。
基础示例(1)
- 图像 A 经过两种增强得到 A1 与 A2
- 目标:A1 与 A2 相似度最大化
基础示例(2)
- A1 在 batch 中看到 B1、C1 等视为负样本
- 目标:A1 与 A2 的相似度高于 A1 与其他样本
实践指南 / 步骤
- 设计增强策略(裁剪、翻转、颜色扰动)。
- 构造两份增强视图作为正样本对。
- 编码器 + 投影头输出对比向量。
- 使用 InfoNCE 计算对比损失并训练。
可运行示例(最小 SimCLR 实验)
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
torch.manual_seed(42)
class TwoCrops:
def __init__(self, base_transform):
self.base = base_transform
def __call__(self, x):
return self.base(x), self.base(x)
def info_nce(z1, z2, temp=0.5):
z1 = F.normalize(z1, dim=1)
z2 = F.normalize(z2, dim=1)
logits = z1 @ z2.T / temp
labels = torch.arange(z1.size(0), device=z1.device)
loss1 = F.cross_entropy(logits, labels)
loss2 = F.cross_entropy(logits.T, labels)
return (loss1 + loss2) / 2
class Encoder(nn.Module):
def __init__(self, out_dim=128):
super().__init__()
self.backbone = nn.Sequential(
nn.Conv2d(3, 32, 3, padding=1),
nn.ReLU(),
nn.AdaptiveAvgPool2d(1),
nn.Flatten(),
)
self.proj = nn.Sequential(
nn.Linear(32, 128),
nn.ReLU(),
nn.Linear(128, out_dim),
)
def forward(self, x):
x = self.backbone(x)
return self.proj(x)
base_tf = transforms.Compose(
[
transforms.RandomResizedCrop(32, scale=(0.6, 1.0)),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
]
)
dataset = datasets.FakeData(
size=512,
image_size=(3, 32, 32),
num_classes=10,
transform=TwoCrops(base_tf),
)
loader = DataLoader(dataset, batch_size=128, shuffle=True)
model = Encoder()
opt = torch.optim.Adam(model.parameters(), lr=1e-3)
for epoch in range(1, 6):
total = 0.0
for (x1, x2), _ in loader:
z1 = model(x1)
z2 = model(x2)
loss = info_nce(z1, z2, temp=0.5)
opt.zero_grad()
loss.backward()
opt.step()
total += loss.item()
print(f"epoch={epoch} loss={total/len(loader):.4f}")
C — Concepts(核心思想)
方法类型
InfoNCE 与 SimCLR 属于自监督对比学习,通过增强视图构造正样本对。
关键公式(InfoNCE)
设正样本对 (i, j),相似度 s_{ij},则:
$ L_i = -\log \frac{\exp(s_{ij}/\tau)}{\sum_{k=1}^{N} \exp(s_{ik}/\tau)} $
通过 batch 内其他样本形成负样本集合。
解释与原理
- 更多负样本 → 更强的判别信号。
- 投影头只用于对比学习,最终特征取 backbone 输出。
- 温度参数控制相似度分布的尖锐度。
E — Engineering(工程应用)
场景 1:医学影像预训练
- 背景:标注成本高,数据却很多。
- 为什么适用:自监督可先学到通用表征。
- 代码示例(Python):
import torch
import torch.nn.functional as F
images = torch.randn(16, 3, 224, 224)
features = F.normalize(images.mean(dim=[2, 3]), dim=-1)
print(features.shape)
场景 2:冷启动检索
- 背景:新领域缺少标签。
- 为什么适用:SimCLR 表征可用于检索初始化。
- 代码示例(Python):
import torch
import torch.nn.functional as F
vecs = F.normalize(torch.randn(100, 64), dim=-1)
query = F.normalize(torch.randn(1, 64), dim=-1)
idx = (query @ vecs.T).topk(k=3).indices
print(idx)
场景 3:小样本分类迁移
- 背景:下游标注少,直接训练易过拟合。
- 为什么适用:先自监督预训练,再微调少量标签。
- 代码示例(Python):
import torch
backbone = torch.nn.Linear(128, 64)
head = torch.nn.Linear(64, 10)
params = list(backbone.parameters()) + list(head.parameters())
print(len(params))
R — Reflection(反思与深入)
- 时间复杂度:每个 batch 需计算
N x N相似度矩阵。 - 空间复杂度:相似度矩阵
O(N^2),大 batch 会显著占用显存。 - 替代方案:
- MoCo:用队列扩展负样本而不增大 batch。
- BYOL/SimSiam:去除显式负样本。
- 工程可行性:SimCLR 实现简单,但对 batch 大小敏感。
常见问题与注意事项
- 增强策略过弱会导致学习不到不变性。
- 温度参数不合适会造成训练不稳定。
- 只看 loss 可能误判效果,需要下游验证。
最佳实践与建议
- 优先验证“增强是否合理”。
- 如果显存不足,考虑梯度累积或 MoCo 类方案。
- 训练后用少量标签验证表征质量。
S — Summary(总结)
核心收获
- InfoNCE 是现代对比学习的核心公式。
- SimCLR 用增强视图构造正样本对,简洁且有效。
- batch 内负样本数量决定了训练信号强度。
- 投影头可以提升对比学习效果而不影响下游特征。
推荐延伸阅读
- SimCLR 论文:A Simple Framework for Contrastive Learning of Visual Representations
- MoCo 论文:Momentum Contrast for Unsupervised Visual Representation Learning
- BYOL/SimSiam 相关工作
参考与延伸阅读
小结 / 结论
InfoNCE 是对比学习的“通用目标函数”,SimCLR 则提供了最直接的训练模板。
理解两者,就能把自监督对比学习迁移到自己的数据上。
行动号召(CTA)
把示例中的 FakeData 换成你的真实数据,观察增强策略对效果的影响。