PRW数据集大家应该不陌生做行人重识别ReID的人基本都绕不开它。但我发现很多刚入门的朋友对它的理解还停留在“拿来跑一下”的层面对里面的人体框怎么来的、评估协议到底怎么算的、为什么检测结果要和检索结果放在一起看其实是一笔糊涂账。这篇就把PRW数据集从头到尾拆开讲清楚包括数据集结构、标注格式、评估指标、踩坑点以及一条可以直接复现的基线和可视化流程。PRWPerson Re-identification in the Wild是2016年前后由清华大学等单位发布的大规模行人检索数据集主打街景监控下的真实场景。跟早期那些在实验室或者固定机位下采集的数据集不太一样PRW的素材来自6个不同的摄像头覆盖多个时段和角度行人姿态、遮挡、光照变化都挺大所以它更贴近实际安防场景。对研究者来说它是做端到端行人检索不分检测和检索两步评估的一个重要测试集对做工程落地的朋友来说用它来验证检测跟踪检索串联的系统表现也有很高的参考价值。1. 数据集的来历与设计思路1.1 发布背景与规模参数PRW数据集基于一个更大的视频数据集PISCPerson Search in the Wild构建原始视频来自6个固定摄像头覆盖一个人流相对密集的校园或者街道环境。公开版PRW总共提供了11816帧高清视频帧这些帧并不全是连续帧而是从原始视频里抽出来的、经过挑选的有效画面主要目的是减少相邻帧之间的大量重复行人框让标注和评估更有意义。在行人框和身份标注方面PRW提供了34304个人体框这些框由人工标注同时还附带了一部分自动检测的结果文件。独立的行人身份ID大约有932个其中被划分出来用于query查询的标注行人约450个剩下的作为gallery底库和训练集的一部分。从规模上说它比早期的VIPeR、CUHK03都要大不少但跟后来的大规模数据集例如Market1501的扩展版、MSMT17比数据量又不算夸张所以它在学术界被广泛应用有一个很现实的原因单卡就能跑迭代速度快大家对比实验不会太吃力。1.2 为什么强调“Wild”和端到端PRW名字里的“Wild”不是随便加的。早期ReID数据集比如VIPeR虽然图片也来自不同相机但行人框基本是手工裁剪好的你拿到手就是一个一个标准尺寸的行人图像模型只需要做图像检索不需要考虑“图里有没有行人、人在哪儿”的问题。但在实际监控中第一步永远是检测检测框不准、漏检、误检后面检索做得再好也没用。PRW和另一个同期的数据集CUHK-SYSU都是最早把“检测检索”这两个环节放到一个框架里评估的一批数据集目标是让算法在真实视频帧上直接输出“这个人在哪、是不是目标身份”而不是喂给它已经切好的图。这就带来了评测逻辑上的关键变化你做PRW的时候跑的不仅仅是一个ReID模型而是一个完整的人员搜索系统。输入是整帧图像和一条query给定目标行人的裁剪图输出是这一帧里所有目标行人的位置和身份判断。这个过程里检测器漏掉的人是不可能被找回的所以检测质量直接决定ReID指标的上限。我在实操中经常看到有人用现成检测器跑PRWmAP比论文里低一截多半就是检测框质量差异导致的后面会详细说。2. 数据组织与标注体系拆解2.1 目录结构与标注文件说明PRW数据集解压后的目录结构很直接网上能找到的压缩包版本可能有细微差别但核心内容基本一致PRW/ ├── frames/ # 原始视频帧按摄像头和时间组织 │ ├── 0001/ # 摄像头1的画面帧 │ ├── 0002/ # 摄像头2的画面帧 │ └── ... ├── annotations/ # 标注文件 │ ├── train_test_split/ │ ├── query_box/ # query裁剪图 │ └── ... └── evaluation/ # 评估脚本和协议文件 └── ...frames目录存放的是1080p左右分辨率的jpg帧图片文件命名一般是“摄像头ID_帧号.jpg”的形式比如“0001_001234.jpg”就表示摄像头1的第1234帧。这里要注意一个坑PRW的帧号不是连续的时间戳序号而是原视频的帧计数中间可能有跳帧。你如果自己去解析视频、对齐时间很容易对不上直接读官方给的帧图片是最省事的。annotations目录下的标注格式和Market1501那种纯文本命名规则不太一样。PRW的标注文件通常包含以下内容train_test_split.json训练、验证、测试的人员ID划分。query_box/query行人图像这些是手工标注的高质量裁剪图。annotation.json或者类似命名完整的人体框标注包含每张帧里所有行人的边界框和对应的身份ID。pool.txt或者类似文件gallery行人框的ID列表用于约束测试范围。2.2 标注内容边界框、ID与检测结果PRW的标注核心是一个JSON结构里面按帧组织每一帧下面挂一个pedestrian列表每个行人包含框坐标和身份ID{ 0001_001234.jpg: { pedestrian: [ {box: [x, y, w, h], id: 123}, {box: [x, y, w, h], id: -1} ] } }这里的ID含义要注意正数ID表示这个行人在标注集合中拥有独立身份可以作为gallery或者训练样本ID为-1表示这张帧里虽然有这个行人但标注方没有给他分配可查询的身份标签在训练时通常当作负样本忽略或者作为背景干扰项处理。除了人工标注的行人框PRW还提供了一个自动检测器的输出通常是基于AlexNet或者VGG的Faster R-CNN检测结果文件名一般叫pool.txt每行信息类似0001_001234.jpg 0 12 34 56 78 0.98依次是帧名、类别编号、检测框坐标(x, y, w, h)、置信度分数。这个文件的存在非常有价值因为它给所有研究者提供了一个统一的检测输入大家在这个检测结果之上评估各自的ReID算法指标才有可比性。很多论文里报告的PRW结果用的就是这个固定检测结果你在复现论文数据时也应该优先用这个文件而不是自己重新跑检测器。2.3 训练、验证与测试划分逻辑PRW的ID划分有一个规定好的协议训练集和测试集按身份ID严格隔离也就是说测试集中出现的行人身份不会出现在训练集里。这是ReID领域的铁律如果不隔离模型记住ID而不是学习泛化特征指标轻松刷爆但没有实际意义。官方划分中query包含约450个身份每个身份在query_box里给出一张手工裁剪的参考图用于检索。gallery则来自所有测试帧中用检测器检测出来的行人框并且这些框对应的身份必须是query ID集合里面的人同时一个ID可能出现在多帧多位置。评估时算法需要在整帧画面中找到query这个人并输出他在画面中的位置框以及查询排名结果。这里有个容易忽略的地方PRW的query数量不大但gallery规模不小而且测试视频帧和gallery框是一一对应的。这意味着你预测的时候如果检测器在某帧里漏掉了目标那目标在这帧的gallery里就没有候选框检索直接失败。所以端到端行人检索任务的mAP天然受检测召回率制约。我们后面跑基线时会再验证这一点。3. 评估协议与评价指标3.1 端到端行人检索任务模式PRW主推的评测任务是“end-to-end person search”跟传统ReID最大的区别在于输入和评估粒度。传统ReID你给模型一个query图模型在gallery图库中查找gallery里的每张图都已经裁剪好了而且每张图只包含一个人。PRW的gallery不是一堆裁剪图而是直接关联到视频帧里的检测框模型输出结果时需要判断“这一帧里的这些检测框哪些是query这个人”。实操中这个任务表现为给定一条query一张目标行人的裁剪图和一组测试帧算法首先对每一帧运行检测器得到候选框然后对每个候选框提取特征跟query特征做相似度排序最后输出按相似度降序排列的(帧名框坐标相似度)列表。评估脚本根据这个列表计算mAP和top-k准确率。3.2 核心指标mAP与top-k准确率PRW最常用的两个指标是mAPmean Average Precision和top-k准确率。先解释mAP的计算逻辑。对每一条query系统输出一个排序好的候选列表其中包含正样本真正是目标ID的检测框和负样本其他行人或误检框。AP是排序列表的Precision-Recall曲线下面积mAP就是对所有query取平均。mAP很敏感它惩罚“把正样本排到很后面”的行为哪怕最终前几名里没有一个对只要后面找回了目标AP都会明显下降。所以在PRW上mAP反映的是整体排序质量是端到端检索能力最核心的指标。top-k准确率则比较直观在排序列表的前k个结果里只要出现一个正样本就算命中。官方评估中一般报告top-1和top-5准确率。这两个指标跟mAP的区别在于它们只关心“最高排名结果是否命中”对后续排名的质量不敏感。实际中可能出现mAP一般但top-1很高的情况这通常发生在gallery里目标只出现一次、且首次命中排名靠前时。3.3 评估脚本的两种模式PRW官方评估脚本一般支持两种模式reid模式和detection模式。前者假设你已经有了检测候选框和特征只评估检索排序后者会结合检测结果一起评估也就是所谓的端到端模式。自己写评估脚本时最需要注意的坑是正样本判定的匹配规则。官方协议中检测框与标注框的IoU大于等于0.5就算匹配并且一个标注框只能被一个检测框匹配如果两个检测框都和同一个标注框高度重叠只有IoU最大的那个算正样本。你是用官方检测结果还是自定义检测结果都要严格遵循这个规则否则指标结果会异常偏高或偏低。还要注意query_image的“禁区”在gallery中如果某个候选框和query来自同一帧且是同一个人的框不会把query本身放进gallery所以正常情况下query图不参与检索。但如果你自己临时拼接数据比如把query图插入了gallery那评估时要把这个对应关系显式排除否则top-1会被自己命中刷高。4. 从下载到跑通一条PRW基线4.1 下载与目录整理PRW数据集的官方项目页面通常会提供百度网盘或者直接下载链接但版本不一定统一。我在实操中习惯先把目录统一成下面这个样子后面写代码会顺手很多PRW/ ├── frames/ # 所有测试帧 ├── query_box/ # query裁剪图 ├── annotations/ # 标注文件 └── evaluation/ # 官方评估代码建议把官方评估脚本原样保留在本地不要随便改它。很多论文的PRW数据对比代码里都是直接import官方评估函数你如果自己魔改了匹配规则后面对比就会失真。4.2 解析标注文件并做可视化拿到数据后第一件事不是马上训模型而是把标注可视化一遍确认自己的标注解析代码是正确的。我一般用Python和OpenCV写一个简单的可视化脚本import json import cv2 import os frame_dir PRW/frames ann_file PRW/annotations/annotation.json with open(ann_file, r) as f: ann json.load(f) def draw_frame(frame_name, pedestrians): img cv2.imread(os.path.join(frame_dir, frame_name)) for ped in pedestrians: x, y, w, h [int(v) for v in ped[box]] color (0, 255, 0) if ped[id] 0 else (0, 0, 255) cv2.rectangle(img, (x, y), (x w, y h), color, 2) cv2.putText(img, str(ped[id]), (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2) return img for frame_name, data in list(ann.items())[:10]: img draw_frame(frame_name, data[pedestrian]) cv2.imshow(PRW, img) cv2.waitKey(0)绿色框表示有可查询ID的行人红色框表示负样本或者未标注ID的行人。跑一遍这个可视化你能直观看到数据集中遮挡、姿态变化、分辨率差异有多严重这些情况会直接影响ReID特征的鲁棒性。如果后续发现某个行人框特别小那么检测器在他身上的召回率低就很正常不必强求所有行人都能检索成功。4.3 用预训练模型跑一轮baseline这里推荐一个相对省力的baseline方案用现成的行人重识别预训练模型比如基于ResNet50训练在Market1501或者MSMT17上的模型提取特征配合官方提供的检测框结果做一轮最简单的余弦相似度检索。流程大致如下读取query_box/下的所有query图提取特征得到query特征矩阵。读取官方检测结果pool文件按帧裁剪出所有检测框逐框提取特征。对每个query计算它和所有gallery特征的余弦相似度按从高到低排序。将排序列表交给官方评估脚本得到mAP和top-1。特征提取代码很直观import torch from torchvision import transforms, models model models.resnet50(pretrainedTrue) # 这里通常去掉最后的全连接层用全局池化后的2048维特征 model torch.nn.Sequential(*list(model.children())[:-1]) model.eval().cuda() transform transforms.Compose([ transforms.Resize((256, 128)), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) def extract_feature(img_path): img cv2.imread(img_path)[:, :, ::-1] # BGR转RGB img Image.fromarray(img) img transform(img).unsqueeze(0).cuda() with torch.no_grad(): feat model(img) return feat.squeeze(0).cpu().numpy()这里要注意不同预训练模型对输入尺寸和归一化的要求不同Market1501系列模型一般用256x128CUHK03系列可能用160x64你换模型的时候要同步改预处理。我初期就吃过亏用MSMT17的模型跑PRW结果因为resize尺寸不一致特征分布偏到离谱指标比论文低了一大截。5. 实操体验与常见坑点5.1 常见问题速查表根据我自己和周围同事的踩坑经验整理了一张PRW数据集的常见问题对照表问题现象可能原因解决办法mAP比论文低5个点以上检测器用的是自跑的而不是官方检测结果换成官方提供的检测结果文件重新评估top-1特别高但mAP很低正样本在排序中靠后靠后续排名召回优化ReID特征的判别性或者调整损失函数可视化出现框偏移标注框格式不是(x,y,w,h)可能是(x1,y1,x2,y2)先打印一两行标注确认格式再解析训练收敛慢训练集和测试集划分时没按官方协议ID混了严格使用train_test_split.json的划分query检索结果大量来自同一帧同一目标在连续多帧中重复出现评估和实际应用时可加入帧间去重逻辑加载annotation.json报错官方文件是python2序列化编码或者类型不兼容用json.load解析注意检查dict key类型5.2 个人心得与建议PRW和CUHK-SYSU是我个人比较推荐的入坑数据集组合。PRW的难度比CUHK-SYSU略高一点因为摄像头更多、场景更多元、遮挡更严重而且它的评价协议更强调检测和检索的联合优化。如果你的目标是刷高点我建议先把检测器换成强一点的模型比如用Cascade R-CNN或者DINO系列做检测再配上目前主流的ReID训练策略比如Bag of Tricks、Circle Loss或者TransReID整体mAP能比老论文里的基线高不少。不过要注意自己换检测器后报告结果时必须说明“检测器为XX检测框来自YY”否则对比不严谨。另外提醒一句PRW的query图像质量整体不算高一小部分query本身分辨率极低人眼都很难辨认。这类样本对模型来说几乎是不可学习的属于数据固有的噪声。你在分析自己模型失败case时先排除掉这些“先天难题”不然容易误判模型的真实能力。最后分享一个小技巧PRW的评估非常依赖检测框的坐标精度同一张帧里目标旁边的误检框如果跟真值重叠超过0.5会被当成正样本这其实是检索的一个陷阱。我在工程落地时会在检测阶段稍微调高置信度阈值牺牲一点召回率来换取更高精度的框坐标结果mAP反而更稳。学术刷点的话可以试试在检测结果后加一个轻量级的框回归微调网络通常能带来1-2个点的mAP提升。
