AI-深度学习

嵌入式视觉模型进阶 16:外观特征与 ReID:怎样比较两个目标

展开合集目录
  1. 嵌入式视觉模型进阶 01:怎样读懂一个实际模型
  2. 嵌入式视觉模型进阶 02:卷积进阶:分组、深度、逐点与空洞卷积
  3. 嵌入式视觉模型进阶 03:MobileNet:深度可分离卷积与倒残差
  4. 嵌入式视觉模型进阶 04:通道注意力与 MobileNetV3
  5. 嵌入式视觉模型进阶 05:ShuffleNet:通道拆分与重排
  6. 嵌入式视觉模型进阶 06:结构重参数化:训练分支怎样合为一个卷积
  7. 嵌入式视觉模型进阶 07:Backbone、Neck、Head 与多尺度特征
  8. 嵌入式视觉模型进阶 08:FPN 与 PAN:怎样融合不同尺度的信息
  9. 嵌入式视觉模型进阶 09:检测头:分类、位置与置信度
  10. 嵌入式视觉模型进阶 10:检测训练:标签分配与损失计算
  11. 嵌入式视觉模型进阶 11:完整 YOLOv8 推理:从图片到原图目标框
  12. 嵌入式视觉模型进阶 12:训练自己的检测器与错误分析
  13. 嵌入式视觉模型进阶 13:检测器导出对照与其他结构路线
  14. 嵌入式视觉模型进阶 14:跟踪基础:运动预测、匹配与轨迹生命周期
  15. 嵌入式视觉模型进阶 15:ByteTrack 思路:用低分框恢复已有轨迹
  16. 嵌入式视觉模型进阶 16:外观特征与 ReID:怎样比较两个目标
  17. 嵌入式视觉模型进阶 17:目标跟随:从轨迹到云台控制接口
  18. 嵌入式视觉模型进阶 18:视频系统:队列、时间戳与异步流水线
  19. 嵌入式视觉模型进阶 19:人脸处理流程:检测、关键点与对齐
  20. 嵌入式视觉模型进阶 20:特征识别:人脸向量、相似度与阈值
  21. 嵌入式视觉模型进阶 21:人体关键点与姿态估计
  22. 嵌入式视觉模型进阶 22:OCR 检测:从文字区域到矫正图片
  23. 嵌入式视觉模型进阶 23:OCR 识别:序列模型与 CTC
  24. 嵌入式视觉模型进阶 24:完整 OCR 流程与识别错误分析
  25. 嵌入式视觉模型进阶 25:轻量语义分割与实例分割
  26. 嵌入式视觉模型进阶 26:工业异常检测:缺陷样本少时怎么办
  27. 嵌入式视觉模型进阶 27:深度估计与图像恢复:两个专题入口
  28. 嵌入式视觉模型进阶 28:面向 NPU 的计算图与算子兼容
  29. 嵌入式视觉模型进阶 29:量化、蒸馏与剪枝的实际取舍
  30. 嵌入式视觉模型进阶 30:综合项目:检测、跟踪与云台跟随验收
嵌入式视觉模型进阶 16:外观特征与 ReID:怎样比较两个目标的封面

第 16 / 30 课。 前置:上一课。本篇的运行范围以实验说明和验证记录为准,构造样例不代表真实任务精度或板端性能。

从类别分数换成特征向量

分类 head 输出有限类别的分数;ReID 编码器输出描述外观的向量。比较两个向量需要统一预处理、权重和特征维度,不能拿不同模型的坐标空间直接计算相似度。

常见做法对向量 L2 归一化,再计算点积,等价于余弦相似度。零向量没有可靠方向,应拒绝而不是除零。相似度也不是天然的同一人概率。

外观与运动一起使用

仅靠外观会把穿着相近的不同目标合并,仅靠位置在交叉遮挡时容易交换身份。可以先用运动和类别排除不可能的配对,再在剩余候选中组合几何与外观代价。

代码用两个正交方向构造身份特征,故意交换几何最优匹配,观察外观信息如何恢复关联。它不包含训练好的 ReID 网络,因此不代表真实行人识别效果。

特征库不能无条件更新

若每帧把新框特征写入轨迹,错误框会污染历史,随后更容易继续错配。可根据检测质量、遮挡程度、匹配分数和更新时间选择更新,或维护有限长度特征库。

指数滑动平均必须在更新后重新归一化;其系数控制新观测与历史的权衡。长期离开场景后重新识别需要更强的验证策略,不能直接沿用帧间关联阈值。

练习与验收

让两个特征越来越相似,比较最佳匹配与次佳匹配差距。再输入全零向量确认被拒绝。真实项目需按不同摄像头、光照和遮挡统计误关联,阈值只在验证集选择。

参考结论:相似度差距过小时应允许不匹配,强制给每个检测一个旧 ID 会隐藏歧义。新增外观模型还会增加裁剪、推理、特征缓存与跨设备数据搬移成本。

配套实验与运行记录

实验:外观特征与 ReID:怎样比较两个目标

查看完整代码:main.py
"""通过归一化向量、相似度与运动门控理解外观关联。"""

import numpy as np
from scipy.optimize import linear_sum_assignment


def normalize(x):
    norm = np.linalg.norm(x, axis=-1, keepdims=True)
    if np.any(norm < 1e-12):
        raise ValueError("zero embedding")
    return x / norm


def main():
    tracks = normalize(np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]))
    observations = normalize(np.array([[0.05, 1.0, 0.0], [1.0, 0.05, 0.0]]))
    cosine = tracks @ observations.T
    geometry = np.array([[0.1, 0.4], [0.4, 0.1]])
    cost = 0.2 * geometry + 0.8 * (1 - cosine)
    rows, cols = linear_sum_assignment(cost)
    assert cols.tolist() == [1, 0]
    print("cosine", cosine.tolist(), "matches", list(zip(rows.tolist(), cols.tolist())))
    updated = normalize(0.9 * tracks[0] + 0.1 * observations[1])
    assert abs(np.linalg.norm(updated) - 1) < 1e-12
    try:
        normalize(np.zeros((1, 3)))
    except ValueError:
        print("zero embedding rejected")
    else:
        raise AssertionError("zero embedding accepted")


if __name__ == "__main__":
    main()
下载代码

在项目根目录执行;下载包解压后,在解压目录执行 python3 main.py。

cd 'content/posts/AI-深度学习/嵌入式视觉模型进阶/16-外观特征与 ReID/code' && python3 main.py

在本篇代码目录执行 python3 main.py。依赖安装、可选入口见包内 README.md;实际运行结果见 verification.md。下载包包含本课使用的辅助模块与样例。

参考与进一步阅读

原始论文或官方文档用于核对结构、接口和适用范围。本篇代码是围绕教学目标编写的最小实验;除明确注明的完整入口外,不视为对应论文模型的完整复现。


完整进阶目录 · 入门系列 · 上一篇 · 下一篇