使用Detectron2提取deepSORT跟踪所需128维特征向量问题咨询
特征提取逻辑调整说明
你当前代码中得到的feats为检测框对应的原始RoI特征,默认Detectron2的RoI Box Head输出维度为1024,和deepSORT要求的128维不符,需做如下调整:
第一步:新增128维特征投影层
可以在现有检测模型的RoI头后新增一个线性投影层,将1024维特征映射到128维,示例代码如下:
import torch.nn as nn # 初始化128维投影层,需和检测模型放在同一个设备上 feat_proj = nn.Linear(1024, 128).to(model.device) # 如果需要端到端训练,可将该层挂载到模型中,加入训练参数列表 model.roi_heads.reid_head = feat_proj
如果有预训练的行人重识别权重,可以直接用来初始化该投影层,不用额外训练也能拿到可用的特征。
第二步:修改推理代码提取128维特征
调整你的推理逻辑,在拿到原始RoI特征后过投影层即可得到目标特征,修改后代码如下:
image = cv2.imread('my_image.jpg') height, width = image.shape[:2] # 若你的检测模型是用RGB数据训练的,需在此处加cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image = torch.as_tensor(image.astype("float32").transpose(2, 0, 1)) inputs = [{"image": image, "height": height, "width": width}] with torch.no_grad(): images = model.preprocess_image(inputs) features = model.backbone(images.tensor) proposals, _ = model.proposal_generator(images, features, None) features_ = [features[f] for f in model.roi_heads.box_in_features] box_features = model.roi_heads.box_pooler(features_, [x.proposal_boxes for x in proposals]) box_features = model.roi_heads.box_head(box_features) predictions = model.roi_heads.box_predictor(box_features) pred_instances, pred_inds = model.roi_heads.box_predictor.inference(predictions, proposals) pred_instances = model.roi_heads.forward_with_given_boxes(features, pred_instances) pred_instances = model._postprocess(pred_instances, inputs, images.image_sizes) # 原始1024维RoI特征 raw_roi_feats = box_features[pred_inds] # 投影得到128维重识别特征,供deepSORT使用 reid_feats = feat_proj(raw_roi_feats) # 可选:做L2归一化,符合deepSORT的特征输入要求 reid_feats = torch.nn.functional.normalize(reid_feats, p=2, dim=1)
注意事项
- 提取的
reid_feats顺序和pred_instances[0]['pred_boxes']的输出顺序完全对应,可直接配对输入到deepSORT的匹配模块 - 若需要端到端训练优化跟踪效果,需将投影层加入训练参数,同时增加重识别损失(如三元组损失、交叉熵损失)和检测损失联合训练
- 若不想新增投影层,也可直接修改deepSORT源码中的特征维度配置为1024,直接使用原始
raw_roi_feats作为跟踪特征,缺点是会增大匹配阶段的计算量 - 如果不想修改检测模型结构,也可将检测得到的框从原图中裁剪出来,单独用预训练的重识别模型提取128维特征,该方案开发成本低但推理效率更低
内容的提问来源于stack exchange,提问作者Smadar
相关产品推荐
相关产品推荐

