度量学习对比损失:Siamese 与对比损失原理
度量学习与对比损失:从孪生网络到特征空间塑造
度量学习(Metric Learning)的目标是学习一个映射函数,将原始数据(如图像、文本)嵌入到一个低维特征空间中,使得在该空间里,相似样本的距离近,不相似样本的距离远。这种学习方式不依赖固定的类别标签,而是直接优化样本对或三元组之间的相对距离,因此特别适用于人脸验证、图像检索、签名鉴定等需要度量相似度的任务。
在最经典的范式下,度量学习通过对比损失(Contrastive Loss) 来训练孪生网络(Siamese Network)。本文将深入解析这一组合的原理、数学定义、训练技巧以及直观理解,帮助初学者从零构建起对度量学习核心机制的认识。
孪生网络:共享权重的双流架构
什么是孪生网络?
孪生网络不是一种全新的网络结构,而是一种权重共享的训练框架。它由两个完全相同的子网络(通常是卷积神经网络)组成,这两个子网络接受两个不同的输入,并输出它们在特征空间中的表示。因为两份输入的流程共享同一组参数,就像一对“孪生体”,故而得名。
输入1 → 子网络 ← 共享权重 → 子网络 ← 输入2
| |
输出向量1 输出向量2
\ /
距离度量(如欧氏距离)
|
对比损失
为什么需要权重共享?
- 对称性:如果交换两个输入的顺序,输出的距离应保持不变。共享权重天然保证了这种对称性。
- 参数效率:两个输入使用同一套规则编码,避免了学习两套不同映射函数可能带来的不一致。
- 可比性:只有将输入映射到同一个空间,距离比较才有意义。
子网络的结构可以灵活选择:CNN用于图像,LSTM用于序列,Transformer用于更通用的模态。训练时,输入以成对的形式组织:正样本对(两张属于同一类或同一人的图片)和负样本对(两张不同类/不同人的图片)。
对比损失:一个直接且优雅的优化目标
对比损失(Contrastive Loss)最早由Yann LeCun等人提出,用于降维和孪生网络训练。其核心思想是:如果两个样本相似,就让它们的编码向量在特征空间里靠近;如果不相似,就推远一定距离,当距离超过某个边界时就不再施加额外的推力。
数学上,给定一对样本 ((X_a, X_b)),其二进制标签 (Y) 为:
- (Y = 1):二者相似(正例)
- (Y = 0):二者不相似(负例)
设 (D) 为两个样本特征向量之间的欧氏距离: [ D = | f(X_a) - f(X_b) |_2 ] 其中 (f(\cdot)) 表示孪生网络的嵌入函数。
对比损失定义为: [ L(X_a, X_b, Y) = Y \cdot D^2 + (1 - Y) \cdot \max(0, m - D)^2 ] 或者更紧凑地写成: [ L = Y \cdot D^2 + (1 - Y) \cdot [\max(0, m - D)]^2 ]
参数 (m > 0) 称为边界(Margin),是一个超参数。
损失函数的直观拆解
- 当 (Y = 1)(相似对):损失退化为 (L = D^2)。优化器会尽可能将 (D) 推向 0,使两个正样本在特征空间中重合。
- 当 (Y = 0)(不相似对):损失只在 (D < m) 时非零,此时 (L = (m - D)^2),惩罚两个负样本靠得太近。一旦 (D \ge m),损失降为 0,模型不再继续将它们推远。这种“边际”设计避免了模型过度关注已经分离得很好的负对,让训练精力集中在难分的负对和需要拉近的正对上。
为什么采用平方形式?
- 平方项使得梯度与距离线性相关(对于正例)或与 ((D - m)) 线性相关(对于负例),训练稳定。
- 与均方误差形式一致,易于实现和优化。
对比损失的梯度与优化行为
从梯度角度理解对比损失能更清楚地看到它如何塑造特征空间。
相似对(正例)的梯度
对于 (L = D^2),距离 (D) 的梯度为: [ \frac{\partial L}{\partial D} = 2D ] 梯度大小与距离成正比,距离越大,拉近的力度越强;当样本已经非常接近时,梯度很小,不会过度调整。
不相似对(负例)的梯度
当 (D < m) 时,(L = (m - D)^2),梯度为: [ \frac{\partial L}{\partial D} = -2(m - D) ] 梯度为负值,意味着朝着增加 (D) 的方向更新(推远)。梯度绝对值随 (D) 靠近 (m) 而减小;当 (D = m) 时,梯度刚好为 0;若 (D > m),梯度归零,停止更新。
这种难例聚焦机制使得训练更高效:优化器主动忽略那些已经轻松分离的负对,反向传播的能量集中在那些仍然“纠缠”在一起的负对和需要进一步靠拢的正对上。
超参数边界 (m) 的选择策略
边界 (m) 设定了“足够远”的基准。其取值对模型泛化能力影响巨大:
- (m) 太小:负对极易满足 (D \ge m),模型几乎没有机会学习有分辨力的特征,导致正负样本混淆。
- (m) 太大:所有负对都远未达到边界,模型一直被惩罚,训练会陷入不稳定,甚至导致所有样本被压缩到一个极小的球面中以保持正样本近,而过大的 (m) 使得负样本需要极大的推远力,可能破坏整体结构。
经验法则:观察特征空间的初始平均距离(通常接近某种范数的期望),然后设置 (m) 为该值的 2~5 倍。还可以在验证集上通过网格搜索结合最近邻分类准确率来选择。在一些人脸识别任务中,(m) 可设于 0.5~2.0 之间(依赖于特征是否归一化)。
与三元组损失的对比(简要)
常有人将对比损失与三元组损失(Triplet Loss)混淆。两者目标相同,但输入形式不同:
- 对比损失:成对输入+相似性标签,适合“是/否”验证场景。
- 三元组损失:锚点、正例、负例三元组输入,直接优化关系:(D_{anchor,pos} + \alpha < D_{anchor,neg})。
对比损失的优势在于训练简单,不用精心构建三元组,但可能面临正负样本不平衡时正对损失被淹没的问题。实际应用中,常将对比损失作为基础模块,或结合难例挖掘策略使用。
实现要点与稳定训练技巧
1. 距离度量的选择
欧氏距离是最常用的,但也可以使用余弦距离(需配合特征归一化)。当使用余弦距离时,建议将特征向量约束到单位超球面上,此时 (D) 变为角度距离,对比损失依然有效。
2. 特征归一化
将嵌入向量的 L2 范数固定为 1(如 (f(X) = \frac{g(X)}{|g(X)|_2}))可以:
- 防止特征维度过大,避免 (D) 的无界增长。
- 让边界 (m) 的设计更稳定(此时最大归一化欧氏距离为 2,余弦距离在 [0,2] 之间)。
- 结合温度参数进一步调节分布。
3. 难例挖掘
简单的随机配对会导致大量已经满足条件的负对((D > m))贡献零梯度,模型学习缓慢。需要在线难负样本挖掘:在每个批次内,只选择那些 (D < m) 的负对计算损失,或从这些难负对中挑选最具挑战性的部分。
对于正对,通常所有相似对都参与计算,但也可对正对中距离异常大的样本对给予更高权重。
4. 配对策略与数据增强
- 同类配对:从同一类别随机选择两个不同样本。
- 异类配对:随机从不同类别选择两样本,但需借助难例挖掘提高效率。
- 利用数据增强生成正对(同一图片两次不同增强),这是自监督对比学习的基础思路,此时所有变换后的图像都视为正例。
一个简化的PyTorch实现示例
为了将理论落地,以下给出对比损失的核心代码框架(基于PyTorch),供理解与快速实验。
import torch
import torch.nn as nn
import torch.nn.functional as F
class ContrastiveLoss(nn.Module):
def __init__(self, margin=1.0):
super(ContrastiveLoss, self).__init__()
self.margin = margin
def forward(self, output1, output2, label):
"""
output1, output2: 形状 (batch_size, 特征维度) 的嵌入向量
label: 0 表示不相似,1 表示相似,形状 (batch_size,)
"""
# 计算欧氏距离
euclidean_distance = F.pairwise_distance(output1, output2)
# 相似对的损失: D^2
loss_pos = label * torch.pow(euclidean_distance, 2)
# 不相似对的损失: max(0, m - D)^2
loss_neg = (1 - label) * torch.pow(
torch.clamp(self.margin - euclidean_distance, min=0.0), 2
)
# 总损失取平均
loss = torch.mean(loss_pos + loss_neg)
return loss
训练循环中,需保证 output1 和 output2 通过同一个模型(或共享参数)得到,label 根据样本对的关系设定。
应用场景与局限
典型应用:
- 人脸验证 / 签名验证:比对两张图像是否来自同一人。
- 图像检索:用对比损失训练编码器,使得查询图与相关图距离近,与不相关图距离远。
- 商品匹配:判断两个商品是否属于同一款式。
- 自监督对比学习(如SimCLR)的基础形式,使用增强样本作为正对。
局限与注意事项:
- 对负样本采样敏感:随机采样可能导致大量平凡负对,模型学不到强判别力,必须配合难例挖掘。
- 类别极度不平衡时,正对数量远小于负对,损失被负对主导,可引入正对损失权重或降低负对贡献。
- 边界 (m) 需要根据任务和特征尺度精心调整,且不具有自适应能力。
总结
对比损失与孪生网络的结合,以一种简洁而强大的方式实现了“相似靠近,不似远离”的度量学习范式。通过共享权重架构保证编码空间的统一,再利用Margin机制实现对难负例的自适应聚焦,使得模型能快速学习出具有判别力的嵌入表示。对于想要深入理解度量学习和现代对比学习(如对比预测编码、MoCo等)的读者,掌握对比损失是必不可少的一步。
建议初学者尝试在MNIST或CIFAR-10上搭建简单的孪生网络,并观察不同边界 (m) 下嵌入空间t-SNE可视化后的分布变化,从而获得直观感受。