Siamese(孪生网络)
1. 前言:为什么要用孪生网络?
在传统的分类任务中,我们通常训练模型识别固定的类别(如:猫、狗、汽车)。但在现实场景中,我们经常面临以下挑战:
- 类别过多且不固定:例如人脸识别,公司每天都有新员工入职,不可能每加一个人就重新训练一遍分类模型。
- 样本极少 (One-Shot Learning):对于某些类别,我们可能只有一个样本,传统的深度学习难以收敛。
孪生网络 (Siamese Network) 换了一个思路:它不再学习“这是谁”,而是学习“这两个样本是否相似”。通过计算两个输入的特征向量之间的距离,它能够实现强大的泛化能力。
2. 网络概述
孪生网络由两个结构完全相同且共享权重的子网络组成。
2.1 核心架构
- 输入层:输入两个样本( 和 )。
- 编码层(子网络):两个样本分别通过相同的 CNN 架构。
- 特征映射:输出两个固定长度的特征向量 和 。
- 距离计算:计算这两个向量之间的欧几里得距离(Euclidean Distance)或余弦相似度。
- 损失函数:根据距离和标签(相同为0,不同为1)计算损失,引导模型缩小同类距离,扩大异类距离。
2.2 共享权重的意义
“孪生”一词的精髓在于两个分支的参数是实时同步(Shared Weights)的。这意味着模型对两个输入的提取逻辑完全一致,保证了特征空间的一致性。
3. 详细网络结构:PyTorch 实现
我们以人脸比对任务为例,使用简单的 CNN 作为子网络。
3.1 定义孪生网络模型
4. 关键:损失函数 (Contrastive Loss)
孪生网络通常不使用交叉熵,而是使用 对比损失 (Contrastive Loss)。其公式如下:
- : 标签。若样本相同则 ,若不同则 。
- : 两个特征向量之间的欧式距离。
- : 边距阈值。当不同类样本的距离超过这个值时,不再产生损失。
5. 训练与推理逻辑
5.1 数据准备
训练孪生网络需要构建样本对(Pairs):
- 正样本对:从同一个人的照片中随机选两张,标签设为 0。
- 负样本对:从两个不同的人中各选一张,标签设为 1。
5.2 推理过程
- 输入两个待比较的图像。
- 经过网络得到两个 128 维向量。
- 计算距离 。
- 设定一个阈值(如 0.5):
- 若 ,判定为“同一人”。
- 若 ,判定为“不同人”。
6. 总结与进阶建议
孪生网络的优势:
- 鲁棒性强:对光照、姿态变化有一定的抗干扰能力。
- 小样本友好:通过对比学习,模型能学到更本质的区分特征。
进阶方向:
- 三元组损失 (Triplet Loss):由 FaceNet 引入,输入由(原图、正例、负例)组成,比双分支的 Contrastive Loss 训练更高效。
- Swin Transformer Siamese:将子网络换成强大的 Transformer 架构。

