共计 1817 个字符,预计需要花费 5 分钟才能阅读完成。
为什么需要对比损失
传统分类任务中,交叉熵损失函数通过优化预测标签与真实标签的差异来训练模型。其数学形式为:

$$\mathcal{L}{CE} = -\sum^N y_i \log(p_i)$$
但在多模态学习中,我们需要对齐不同模态(如图像和文本)的特征空间。这时交叉熵面临两个核心问题:
- 需要预先定义的固定类别体系
- 无法直接建模模态间细粒度关系
对比损失的核心思想
对比学习通过拉近正样本对、推开负样本对的距离来学习特征表示。给定一批 N 个图像 - 文本对,每个图像有 1 个正文本和 N - 1 个负文本。InfoNCE 损失函数定义为:
$$\mathcal{L}{InfoNCE} = -\frac{1}{N}\sum$$}^N \log\frac{\exp(s_{i,i}/\tau)}{\sum_{j=1}^N \exp(s_{i,j}/\tau)
其中 $s_{i,j}$ 是第 i 个图像与第 j 个文本的相似度,$\tau$ 是温度系数。
温度系数的魔法
温度系数控制着相似得分的分布陡峭程度:
- 较大 $\tau$ 会平滑分布,使模型关注更多困难负样本
- 较小 $\tau$ 会锐化分布,使模型更关注高相似度对
经验取值通常在 0.01 到 0.5 之间,需要通过验证集调整。
PyTorch 实现详解
import torch
import torch.nn as nn
import torch.nn.functional as F
class ContrastiveLoss(nn.Module):
def __init__(self, temperature=0.07):
super().__init__()
self.temperature = temperature
self.cos_sim = nn.CosineSimilarity(dim=2)
def forward(self, img_emb, txt_emb):
# 特征归一化
img_emb = F.normalize(img_emb, dim=1)
txt_emb = F.normalize(txt_emb, dim=1)
# 计算相似度矩阵
logits = self.cos_sim(img_emb.unsqueeze(1), txt_emb.unsqueeze(0)) / self.temperature
# 创建标签(对角线为正样本)labels = torch.arange(logits.size(0), device=img_emb.device)
# 计算交叉熵损失
loss_i = F.cross_entropy(logits, labels)
loss_t = F.cross_entropy(logits.T, labels)
return (loss_i + loss_t) / 2
完整训练流程
def train_one_epoch(model, loader, criterion, optimizer, device):
model.train()
total_loss = 0
for images, texts in loader:
images = images.to(device)
texts = texts.to(device)
# 混合精度训练
with torch.cuda.amp.autocast():
img_feats = model.encode_image(images)
txt_feats = model.encode_text(texts)
loss = criterion(img_feats, txt_feats)
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss += loss.item()
return total_loss / len(loader)
工程实践建议
- 批处理大小:
- 更大的批次提供更多隐式负样本
- 但会占用更多显存,需在二者间平衡
-
推荐从 256 开始尝试
-
特征归一化:
- 必须对特征进行 L2 归一化
- 可防止梯度爆炸 / 消失
-
使相似度保持在 [-1,1] 范围
-
混合精度训练:
- 使用 torch.cuda.amp 自动管理精度
- 对损失值添加梯度缩放
- 可提升 30% 训练速度
关键参数参考
| 参数 | 推荐值 | 作用 |
|---|---|---|
| 温度系数 | 0.07 | 控制相似度分布 |
| 批大小 | 256 | 影响负样本数量 |
| 特征维度 | 512 | 表征空间大小 |
| 学习率 | 3e-4 | 优化器步长 |
延伸思考
对比损失的思想可以扩展到:
- 视频 - 文本检索
- 跨语言翻译
- 分子结构 - 性质预测
与 Triplet Loss 相比,对比损失:
– 能同时利用多个负样本
– 对采样策略更鲁棒
– 但对计算资源要求更高
建议在计算资源允许时优先选择对比损失。
正文完
发表至: 未分类
近一天内
