公司动态

相似度校准与图聚类:开放集动物重识别的两大关键路径

📅 2026/8/27 4:59:27
相似度校准与图聚类:开放集动物重识别的两大关键路径
Calibrated Similarity 和 Graph Clustering 是开放集动物重识别Open-Set Animal Re-Identification里两条关键的技术路径。过去看到这类标题我第一反应是这不就是在分类任务上多加了一步聚类吗但真正在野外数据上跑过之后会发现问题远不是“先识别再聚类”那么简单。开放集动物重识别的本质是要在一个不断增长、充满噪声的个体档案库中回答两个问题这个个体是不是已经见过如果没见过它是不是值得建立新档案这两个问题一旦同时出现相似度就不只是“算子”而是一种需要校准的证据聚类也不只是“后处理”而是判断身份边界的主要手段。1. 野外动物个体识别的核心难点不在“识别”而在“开放”1.1 一个比“物种分类”更真实的任务很多刚接触动物识别的人会把任务想成“识别出这是哪种动物”但一线调研人员拿到的问题往往是另一类这个相机位点拍到的个体和上周在另一个位点拍到的个体是不是同一只尤其在外形差异细微的物种上比如雪豹的斑纹、鲸豚的尾鳍、藏酋猴的面部纹理单张图片很难直接判断。所谓 Animal Re-Identification就是要基于图像或视频建立个体级别的一致性判断。但这还不是最棘手的地方。更棘手的是动物个体档案不是固定的。今天你用一个包含 200 个个体的封闭库训练模型明天野外又拍到了 30 个新个体这些新个体并没有出现在训练类别里。如果模型只能输出“属于这 200 类中的某一类”那新个体就会被强行塞进一个错误身份。这类场景在术语上叫 Open-Set测试时可能出现训练时从未见过的身份类别。标题里的 Open-Set Animal Re-Identification指的就是这个更贴近实际、也更有挑战的设置。另一个常被忽略的现实因素是从采集到归档之间存在延迟。自然保护区的红外相机或社区监测影像往往是几个月才回收一次。这意味着今天的“识别任务”不是一次性对已知数据做分类而是要持续对新增影像进行判断某张图是匹配到已有档案里的某只个体还是代表一个全新个体。如果系统没有开放集能力就无法支撑这种持续更新的工作流。1.2 为什么闭集分类思路在这里天然失效闭集分类的标准做法是训练一个带 Softmax 的神经网络输出维度等于训练类别数推理时取最大概率对应的类别。这个流程在人脸或车辆识别中的封闭场景很成熟但要搬到动物个体识别上会出现几个结构性问题。对比维度闭集分类开放集重识别类别数量固定训练时确定动态增长测试时可能出现新身份新个体处理无法表达“不认识”需要判断“是否见过”并决定是否建档输出形式类别概率分布相似度分数 身份簇结构核心难点类间区分类内域偏移 未知类检测适用场景物种识别、固定人员库动物个体长期监测、野生动物档案第一个体类别数不稳定。个体档案不是静态的每月都有新个体加入。每加一个新个体如果按闭集分类来做就需要重新调整最后全连接层并重新训练或者微调模型。当个体数量从几百涨到几千甚至上万时这种做法的时间和算力成本会快速膨胀。第二模型对“陌生个体”没有表达能力。Softmax 会把概率分布分配到所有已知类上面对一个未见过的个体它无法输出“不认识”只能输出概率最高的那个已知身份。哪怕把阈值调得很高也只是把不确定性转嫁到阈值选择上并没有真正建模“新个体”这一类。第三闭集模型低估了域偏移的影响。同一只动物在不同相机、不同光线、不同角度下表观差异可能大于不同个体在同条件下拍摄的差异。闭集分类学到的决策边界依赖训练集的拍摄条件一旦测试域变化特征分布也会偏移并在相似度空间里留下不可控的错位。这也是我在实际项目里体会最深的模型在训练集上分类精度不错但换到新的红外相机点位错误率就会明显上升。因此开放集重识别往往不能停留在分类输出端做阈值而要回到特征和相似度层面对“是否见过”这个判断题做更精细的控制。2. 拆解标题里的两把钥匙相似度校准与图聚类2.1 相似度校准让不同查询之间的分数具备可比性很多方案的第一步都是提取特征并计算相似度比如用 ImageNet 预训练模型或自监督模型提取全局描述子再用余弦相似度判断两张图的接近程度。问题在于余弦相似度在同一个数据集内部可以做相对比较跨查询、跨批次、跨相机时分数分布并不稳定。有的查询和所有候选都比出 0.8 的高分有的查询即使和正确匹配也只能到 0.65。如果用同一个全局阈值去截断必然造成一部分身份被漏掉另一部分身份被误并。Calibrated Similarity 要解决的就是这种“分数不可比”的问题。常见思路包括温度缩放把原始相似度除以一个标度参数再送入判定函数也包括对每个查询或每个个体做归一化比如把相似度向量转成排名、用 Top-K 距离做相对化处理还可以为每个个体学习一个自适应的阈值让“属于该个体”的标准随该个体的拍摄质量变化。这些东西在闭集分类里不常用因为闭集只关心最大概率对应的类但在开放集里阈值本身就是身份决策的一部分如果相似度没有校准后续聚类和判定都会失真。需要说明的是Calibrated Similarity 并不等同于“调一个更高的阈值”。它更接近对证据本身的修正在同一个尺度上表达“这张图和这个档案有多像”并且把不同个体、不同拍摄条件下的差异消化掉。如果原始特征分布就是偏斜的单纯提高阈值会同时带来高漏检和高误报校准目标是把相似度的分布变得可解释让阈值在一个可控范围内起作用。2.2 图聚类从两两比较升级到群体关系推断做过重识别的人都知道成对比对只是很小的一个环节。实际数据里一张查询图会同时和几十上百张档案图比较得到一组相似度但最终判断不应该是这一组分数里的最大值而应该看这些档案图之间是否存在一致的身份结构。这里就需要图建模把每一张图片或每一个检测框看作节点节点之间的边权重是校准后的相似度然后在图上做聚类让同一个身份的图像聚成一簇。图聚类的好处是可以借助“群体关系”来处理单张图片不清晰的情况。比如某张正脸图与个体 A 的相似度只有 0.7但它却与个体 A 的其他三张图都有 0.7 以上且互相相似的连接聚类算法就可能把这条弱证据放到 A 的身份簇里而不是被当成一个新个体。这种“由簇投票”的思路比只看单条查询最高分要稳健得多。实际工作中常见的选择包括 DBSCAN、谱聚类、Louvain 社区发现也有专门为图结构身份聚类设计的算法。每种算法的密度假设不同需要结合数据分布做实验。需要强调的是图聚类在开放集里不只是后处理它本身就是对新类别的推断孤立点和小簇通常对应着“未见过的个体”和大簇相连但边界模糊的节点则是需要人工复核的疑难样本。少了这一步一个单纯的相似度模型是没法回答“要不要建新档案”的。2.3 两者为什么要组合在一起只看校准相似度系统缺少对全局结构的利用只看图聚类面对噪声和域偏移时又缺少可靠的边权重。两者组合本质上是把“怎么判断相似”和“怎么判断身份”分开处理。校准负责让相似度在数值上可用图聚类再基于这些分数构建身份边界。这样设计的好处是便于模块化调优相似度分布不正常先修校准聚类过碎或过黏再调聚类参数。两个环节都有明确的观察指标而不是混在一起黑盒调参。我在读这类题目时的一个判断是Calibrated Similarity Graph Clustering 的组合真正回答了开放集重识别里的两个关键问题分数不稳定时用什么做证据出现孤立点和异常簇时如何把它们归为新人还是噪声。没有校准聚类结果会被离群的高/低分干扰没有聚类校准后的相似度仍然会被逐条比较的局部最优误导。3. 从论文思路到可运行流程搭建一套开放集重识别系统3.1 数据准备是个体档案不是简单打标签先不要急着训练模型。落到真实项目第一步是把数据组织成个体档案。和闭集分类的“文件名类别标签”不同开放集重识别要求你能区分“哪些图属于同一个身份”。通常做法是建立一个个体表格每条记录包含个体 ID、图像路径、拍摄时间、地点、相机位点等元信息。个体 ID 不需要在模型训练时全部出现训练阶段可以只用一部分已知个体做特征学习测试阶段再把新图像和整个档案库做比对。数据质量需要特别关注。同一只动物在不同季像、不同拍摄角度、遮挡严重的情况下表观差异很大如果档案里的同一个个体的图像过少聚类时很难形成稳定簇。我一般建议每个身份至少保留 5 到 10 张不同拍摄条件下的图像同时要把明显低质量的数据剔除或者至少标记出来避免在特征空间里引入大量噪声。这个过程没有捷径但它决定了后续所有环节的上限。3.2 特征提取与相似度计算特征提取可以使用预训练的视觉模型比如 ResNet、ViT 或专门做 ReID 训练的模型。实际项目中我会先用一个在 ImageNet 或自监督任务上预训练过的模型作为基座用数据集的已知个体做微调或者直接从模型倒数第二层抽取归一化特征。这一步产出的特征维度通常不需要太高512 或 1024 维已经能支持中小规模的个体库。相似度计算一般用余弦相似度。代码结构可以参考这样的形式import numpy as np from sklearn.preprocessing import normalize def cosine_similarity_matrix(query_feats, gallery_feats): query_feats normalize(query_feats, axis1) gallery_feats normalize(gallery_feats, axis1) return np.dot(query_feats, gallery_feats.T)这里需要注意的是特征归一化。不归一化直接点积结果会受到向量长度影响而在 ReID 场景里向量的模长往往和图像质量呈弱相关却不代表身份相似性。所以先把特征归一化再做余弦相似度是更稳妥的起点。在真实部署时你还需要考虑相机的域差异。同一只个体在不同相机里的特征分布可能会有系统性偏移。如果数据足够可以给相机位点学习一个校正向量如果数据不足至少要在评估时按相机分组分析而不是把所有的错误平均掉。注意不要一上来就把相似度阈值和聚类参数拉满先用几十条已知身份的样本确认输入、特征和分数分布是否正常。3.3 相似度校准的典型做法最简单的校准是在训练集或者验证集上统计正负样本对相似度的分布然后选择一个分位点作为基础阈值。但这仍然是一个全局阈值。更进一步可以用温度缩放类方法对相似度做非线性变换def calibrate_similarity(sim, temperature1.0): calibrated sim / temperature return calibrated温度参数可以用一个小的验证集来估计目标是让“同身份样本对”和“不同身份样本对”的分数分布重叠最小。除了温度缩放也可以把相似度转换成排名对每个查询取它与档案库中每张图相似度的排名再对排名做平滑这样能缓解不同个体图像数量不均衡带来的影响。更精细一点的做法是给每个个体学习一个自适应的分数偏移量。比如某个个体在档案库里只有姿态单一的照片那么它对查询图的平均相似度可能会系统性偏低校准模块可以学习一个个体级的偏置项把这个偏差补回来。这个方法在大型动物个体库上往往比单一全局阈值有效但它需要充足的历史验证数据不能在小数据集上盲目使用。3.4 用图聚类做开放集判定有了校准后的相似度矩阵就可以构建图结构。假设我们有 N 张待判定图像包括查询图和档案图就构建一个 N×N 的相似度矩阵只保留超过一定阈值的边然后跑聚类。这里给出一个常见的 DBSCAN 示例from sklearn.cluster import DBSCAN # clustering_matrix 是 N×N 的相似度矩阵转成距离后输入 distance_matrix 1 - clustering_matrix clustering DBSCAN(eps0.4, min_samples2, metricprecomputed) labels clustering.fit_predict(distance_matrix)聚类结果会给出每个样本的簇标签。簇大小为 1 的孤立点通常是新个体噪声或极难样本簇大小适中且簇内平均相似度较高的可以视为稳定身份簇。接下来的开放集判定规则可以是如果一个查询图落入了某个已有身份簇且置信度足够就认为它属于该身份如果它自己组成一个孤立簇或很小簇就标记为“候选新个体”如果它与多个簇都有连接但归属不清晰就进入人工复核队列。这个阶段需要特别留意“边界样本”。聚类算法不会告诉你某条边是否可靠所以最好保留每条样本的簇内平均相似度和第二大簇相似度作为一个置信度分数。后面人工复核时可以按置信度排序优先检查最可疑的数据。3.5 一个评价与闭环流程整个流程可以沉淀为这样几个步骤从待处理图像中抽取特征。用已有档案库和查询图构建相似度矩阵。对相似度做校准得到可比较的分数。在图上聚类形成身份簇。根据簇大小、密度和置信度生成“已知身份”“候选新个体”“人工复核”三类结果。人工修正后把新确认的身份和图像合并进档案库。这看起来像是一个标准流程但真正能长期运转的系统必须把每一步都记录成日志。我一般会保存每次运行的特征版本、模型版本、校准参数和聚类参数否则几个月后档案库更新了你很难复现一次旧结果也很难判断识别率下降是因为模型退化还是因为数据分布变化。4. 开放集评估与工程化的常见坑点4.1 传统评估指标为什么不够用很多研究者在论文里会报 Rank-1 或 mAP这些指标在闭集重识别里是标准。但在开放集设置里仅仅报 Rank-1 是不够的它默认查询图像一定对应着档案库中的某一个身份而开放集里可能并没有正确答案。正确评估需要考虑两个方向已知身份是否被正确识别以及新个体是否被正确检测出来。指标类型常见指标关注点已知身份识别Rank-1、Rank-5、mAP查询图是否在候选库中正确命中未知个体检测未知检测召回率、误检率新个体是否被识别为“陌生”而不是强行匹配综合判定F1、开放集识别率识别与建档之间的平衡聚类质量簇纯度、兰德指数、NMI身份簇是否干净、稳定如果只看平均精度很容易掩盖少数个体的表现。动物个体数据的不均衡非常严重有些个体的样本很多模型容易学得好但野外调查人员更关心的往往是那些只有一两张图像的罕见个体。后者在聚类时经常被当作孤立点引起高漏检。所以评估时务必要按每个个体的样本数分组分开看常见个体和罕见个体的表现。4.2 按这个顺序排查输入、特征、相似度、聚类、标签如果开放集重识别系统表现不好不建议直接调聚类参数。建议按下面的顺序排查先看输入。图像是否裁剪正确、分辨率是否足够、目标框是否有抖动、是否存在同一目标被多次识别成不同框的问题。很多异常结果都来自检测框偏移。再看特征。特征提取的输入尺寸和预处理是否一致模型是否在相似的数据分布上预训练同一个个体的图像在特征空间中是否确实相对靠近。可以拿几个已知身份做 t-SNE 可视化直观判断。然后看相似度。分数分布是否有明显的偏斜是否受到相机位点、时间段的影响。可以画出正负样本对的分数直方图看校准前后是否真的把正确匹配和错误匹配拉开。再看聚类。如果聚类过碎可能是相似度阈值过低或簇密度参数过严如果聚类过黏可能是阈值过高导致不同身份被连在一起。可以尝试调整 eps、min_samples 或谱聚类中的簇数范围。最后看标签。开放集数据里人工标注错误很常见。有时候“模型错了”其实是档案库里的参照标注错了。最笨的办法是抽查错误样本把原图和档案图直接对比确认是不是同一个个体的表观差异过大还是因为人为标注错误。4.3 实际落地时的三个避坑建议第一不要把相似度阈值定成一个固定值然后就再也不改了。数据在增长相机在替换个体外观在不同季节也在变化固定阈值会在三个月后变得不适用。更好的做法是建立周期性的校准流程比如每个月根据新累积的人工复核结果重新统计分数分布。第二人工复核不是可有可无的步骤。在开放集里新个体检测的代价是误建档案。一旦把两个相似的不同个体合并成一个身份后续所有识别都会在这个错误身份上继续叠错。因此对于“候选新个体”至少要安排一次人类核对而不是让算法自动决定。少用全局固定阈值多用按个体或按相机分组校准的分数否则新个体加入后误并率会迅速上升。第三注意记录所有版本的“档案库快照”。新的个体加入后旧图像的聚类归属可能发生改变。如果不保存历史快照就无法回溯“某个个体最早是在哪一天、基于什么证据被纳入档案”。这在生态保护项目中尤其重要因为每个个体身份往往关联着长期跟踪记录一旦被污染对下游分析的影响是累积的。5. 这套方案能走多远适用边界与长期价值5.1 适合什么场景不适合什么场景这样说可能更清楚Calibrated Similarity Graph Clustering 这套组合适合那些“身份外观在短期内相对稳定、图像采集能覆盖多个视角、并且有足够的历史数据做校准”的项目。比如自然保护区的相机监测、动物园的个体档案管理、水族馆鲸豚个体的长期跟踪以及畜牧业中对特定个体的健康状态追踪。这些场景的共同点是个体档案有起点也有持续的人工复核算法不需要在一开始就做到百分之百。相反如果目标是“野外无标注视频流里自动识别所有个体且完全没有人工介入”这套方法会非常脆弱。原因很简单开放集识别永远需要回答“阈值放到哪里”的问题而没有人工标签你就无法稳定地校准这个阈值。另一个不适合的场景是外观变化极快的物种比如某些动物在繁殖期、换毛期、冬毛期的外观可能完全不同如果特征模型没有专门针对跨季节变化做训练聚类会把同一个个体拆成多个簇再把不同个体在某一期的相似外观黏到一起。5.2 从论文想法到规模化工程还差哪几块拼图论文里可以只做一个离线评估但在工程上我看到的差距通常体现在这几个地方一是增量学习能力。新个体不断加入模型和特征库需要在不重头训练的前提下更新否则维护成本会越来越高。二是检索效率。当档案库达到几十万张图时全量计算相似度矩阵开始变得昂贵需要引入近似最近邻检索ANN再在检索到的局部图上做聚类。三是质量监控。相似度分布的漂移、相机状态的退化、聚类簇的平均纯度这些指标需要可视化监控而不是等用户投诉了才知道。还有一个容易被低估的点数据管理。开放集重识别系统本质上是一个数据闭环系统每一次人工复核都被用于改进阈值或模型。如果原始图像、个体 ID、特征向量、模型版本、人工复核结果分散在不同表格里系统很快就会失去可信度。哪怕算法再漂亮没有干净的数据链路也很难长期输出可靠结果。5.3 一条可以带走的方法论从这篇文章的题目里可以提炼出一个对多数身份识别场景都有参考价值的流程把“判断结果”拆成“证据校准”和“结构推断”两层。先用校准让分数可比再在图结构上推断身份边界最后用人工复核校准闭环。这个方法不只适用于动物也适用于其他开放集个体识别问题比如车辆重识别、行人重识别、商品个体识别甚至日志异常检测里对“已知模式”和“未知模式”的划分。回到一开始的判断开放集动物重识别真正难的不是“识别”而是“如何知道该不该把一次匹配当成一个新身份的开始”。相似度校准和图聚类只是把这个问题拆成了可操作的两半。有了这个框架即使将来有更新的特征提取器、更强的聚类算法你仍然会先问同一个问题当前得到的相似度是否真的具备跨图像的可比性这些可比分数又能不能在图上形成稳定的身份边界只要这两个问题回答清楚开放集识别就不再是一个模糊的难题而是一条可以持续迭代的技术路径。