孪生网络:衡量样本相似度
判断「这两张图是不是同一个人」「这两句话意思是否相近」,往往很难写成一条固定的规则。直接做分类又会遇到类别太多、每类样本太少的问题。孪生网络(Siamese Network)的思路是:不去预测类别,而是直接学习一个「相似度」函数,让模型告诉我们两个输入有多像。
为什么需要学出来的相似度
传统做法常用像素距离或手工特征衡量相似,但在姿态、光照、措辞变化很大时并不可靠。孪生网络把相似度本身当作学习目标:只要给成对的样本(同类或异类)做监督,模型就能从数据里学会对任务真正有用的距离度量,而不是依赖人写的特征。这也让它天然适配少样本场景——即使某个类别只有几张图,只要能比对新旧样本即可判断。
网络结构:两个共享权重的分支
孪生网络由两个结构相同、权重共享的子网络组成,各自把输入映射为一个嵌入向量,再用一个距离度量(如余弦距离或欧氏距离)比较这两个向量:
def siamese_forward(net, a, b):
# net: 两个分支共享同一套权重
emb_a = net.encode(a) # 输入 a 编码为向量
emb_b = net.encode(b) # 输入 b 编码为同一空间向量
dist = cosine_distance(emb_a, emb_b)
return dist # 距离越小表示越相似
权重共享是关键:它保证两个分支对同类特征给出一致的表示,否则左右不对称会让相似度失去意义。
对比损失如何训练
训练时用成对标签:同类标 0、异类标 1。对比损失(Contrastive Loss)鼓励同类嵌入靠近、异类嵌入拉开到一定边界之外。另一类常见做法是三元组损失(Triplet Loss),用一个锚点、一个正例、一个负例,让正例比负例更近。两者都迫使同类样本在嵌入空间聚拢、异类散开,从而把「相似」这件事学进向量本身。
典型用途
孪生网络广泛用于人脸验证、签名鉴别、商品以图搜图、句子语义匹配等「成对判断」任务。它的优势在于训练一次即可得到通用的相似度度量,后续新增类别不必重新训练分类头,只要拿新样本去比对即可,特别适合类别开放或样本稀少的场景。
小结
孪生网络用一对权重共享的子网络把两张输入编码到同一向量空间,再用对比或三元组损失拉开异类、拉近同类,从而学到可复用的相似度度量。它把问题从分类转为比较,因此在少样本、开放类别与成对匹配任务上尤为实用。
参考与延伸阅读
- Bromley et al. Signature Verification using a Siamese Time Delay Neural Network(NeurIPS 1993)。孪生网络早期奠基工作,用于签名鉴别。已核验。
- Schroff, Kalenichenko, Philbin. FaceNet: A Unified Embedding for Face Recognition and Clustering(CVPR 2015)。系统使用三元组损失做人脸嵌入。已核验。
- 具体损失函数与采样策略(难例挖掘等)以各开源实现文档为准,不同框架的默认超参可能不同。待核实。