简介VeRi数据集是面向车辆识别任务的专业数据资源适合计算机视觉与深度学习方向的研究者、开发者及学生可用于车辆检测、车型分类、车辆重识别与检索等研究场景。整个压缩包共包含2000个文件主体为jpg车辆图片辅以txt与xml标注文件压缩后整体大小约945.51MB下载使用方便。该资源已有4208人浏览/学习在车辆视觉领域具有较高关注度。数据大多来自真实监控视角覆盖车型、颜色、角度、光照与距离的变化图像质量贴近监控实景能够体现目标尺度变化、遮挡与复杂背景等实际挑战并配有车辆类别、唯一标识及边界框等标注可直接用于卷积神经网络或迁移学习模型的训练与评估也适合在TensorFlow、PyTorch等框架下开展实验。借助该数据集研究人员可客观比较不同算法在车辆检测、分类和重识别任务上的表现并为智慧交通、智能安防等真实应用提供扎实的数据基础。 我第一次真正在项目里用上VeRi.zip是在做园区车辆轨迹关联的时候。当时要解决一个很实际的问题同一辆车从A摄像头开到B摄像头中间隔着绿化带、阳光角度也变了算法怎么判断这是同一辆车网上翻了一圈车辆再识别的开源数据集VeRiVehicle Re-Identification几乎是被提到最多的一个尤其是那个低调的 .zip 压缩包——解压之后装着一整套已经按车辆ID、摄像头ID和拍摄帧号组织好的图片简直像为复现论文量身定制的。简单说VeRi 的任务是给你一张摄像头拍到的车辆照片query你得从几十个摄像头拍下的海量图片gallery里把同一辆车找回来哪怕它换了角度、换了光照、甚至隔了几个小时。这个数据集是北京交通大学团队在真实场景下采集的20个摄像头、24小时持续拍摄覆盖了超过700辆车的5万多张图片。对做行人ReID想转车辆ReID、做车辆结构化分析、或者只想在标准数据集上练手对比指标的人来说VeRi.zip 几乎是一条必经之路。1. 项目背景VeRi 到底解决什么问题1.1 车辆再识别任务与数据集定位车辆再识别英文叫 Vehicle Re-Identification简称 Vehicle ReID。它和你更熟悉的车辆检测、车牌识别不太一样检测是“框出车在哪里”车牌识别是“读出这个车牌号”而 ReID 是“认出这是哪一辆车”。难度也就藏在这里——同款车型在监控里看起来一模一样厂商、型号、颜色都相同但你要区分它们反过来同一辆车在不同摄像头下因为角度、遮挡、光线、模糊又可能变得“六亲不认”。中间还不能只依赖车牌因为很多时候画面分辨率不够或者车牌角度根本拍不到。VeRi 数据集的价值恰好就是把这些真实条件全部记录下来。它不是封闭停车场里摆拍出来的数据而是部署在真实道路、真实监控画面里的抓拍结果。每辆车会出现在多个摄像头视野内并且附带了摄像头ID和时间戳信息。这意味着你不仅能做“看脸认车”还能结合时空约束做跨摄像头轨迹分析这正是实际安防、交通、智慧园区场景里特别需要的能力。我第一次拿到 VeRi.zip 的时候第一反应是“这数据量好像不大”。确实相比 COCO 那种几十万张的物体检测数据集VeRi 的5万多张图片规模不算夸张。但它的结构化程度非常高车辆ID、摄像头ID、时间帧全部编码在文件名里训练集、查询集、候选集划分得清清楚楚。对复现论文、对比算法效果来说这种精打细算的数据集反而比海量但杂乱的资源更好用。1.2 VeRi 与其他车辆数据集的差异我把常见几个车辆数据的定位拉了一张表方便大家理解为什么 VeRi 在 ReID 任务里如此高频出现。数据集规模采集方式主要用途VeRi-776776辆车5万张图20个真实监控摄像头24小时车辆再识别、跨摄像头追踪CompCars约16万张车图网络图片监控图片混合车型识别、属性分析PKU-VD约1万辆车20万张图真实监控、2个数据集版本车辆再识别、车型分类VeRi-Wild4万辆车40万张图真实监控大规模车辆再识别、跨场景验证VeRi 在“真实监控多摄像头时空标注”这个组合上做得比较均衡既比最早期的数据集大又比 VeRi-Wild 更容易上手和调试。很多论文的 baseline 都是在 VeRi 上先跑通的。顺便提一句有些初学者会把 VeRi 当作车辆检测数据集来用找里面的车框去训练 YOLO 或者 Faster R-CNN这其实走偏了。VeRi 里的图片主体就是车本身已经完成了“检测裁剪”这一步你要做的不是再画框而是提取特征、做检索。想训练检测器应该去找 COCO、UA-DETRAC 这类带边界框标注的数据集。把数据集的任务边界搞清楚能少走很多弯路。2. 数据解剖目录结构、命名规则与评测协议2.1 解压后的文件组织与命名规则拿到 VeRi.zip 之后第一步是解压。我见过社区里流传的版本目录结构可能略有差异但最常见的组织方式是三个文件夹image_query查询图片、image_train训练图片、image_test测试候选图片外加一个 label 相关的说明文件。网上有些打包版本还会附上官方的 train_test_split 目录或者 .txt 划分文件。文件名是理解数据的关键它的编码规则很直接典型格式类似0002_c004_00005720.jpg用下划线拆开三个字段分别是字段片段含义示例说明0002车辆ID同一辆车的所有图片共享同一个IDc004摄像头IDc004 表示第4号摄像头拍摄00005720帧号/时间戳在视频流中的帧序号可用于时间先后推断这个命名设计的妙处在于不需要额外的标注文件仅通过文件名就能完成标签提取和时序分析。我在写数据处理脚本时基本只用一次 os.path.basename 加 split(_) 就拿到全部关键信息。车辆ID不一定是连续编号训练集和测试集的ID范围也有区分所以千万不要凭数字大小臆断一切以文件名为准。有些版本可能还会带一个train_test_split目录里面通常是按车辆ID划分的 train.txt、test.txt、query.txt 等文本文件。如果你拿到的是这种目录优先读这些文件来构造数据集而不是自己按照片数量比例切分因为论文的对比实验需要遵循官方的评测协议自己乱切会破坏可比性。2.2 训练集、查询集与候选集的评测关系VeRi 的评测协议核心是区分 Query 和 Gallery 两个概念。Query 是你要查的那辆车的图片通常来自某个摄像头的一次抓拍Gallery 是搜索池里面是其他摄像头拍下的海量图片你的算法需要让 Query 在 Gallery 中检索出同一辆车的图片。评测时mAP平均精度均值和 CMC Top-1/Top-5 是两大标配指标。mAP 评估的是排序列表的综合质量CMC 评估的是“前 N 个结果里正确车辆是否出现”的能力。这里有一个容易忽略的细节在计算指标前如果 Query 本身也在 Gallery 里要把这张图片和它自身的匹配结果排除掉。原因是“自己跟自己比相似度一定最高”如果不排除Top-1 会虚高整个指标就没有意义了。VeRi 官方给出的 query 和 gallery 划分基本不会出现这种重叠但如果你想从大库里自定义评测集就必须做这一步过滤。另外很多刚接触 ReID 的人会把“训练集车辆ID”和“测试集车辆ID”搞混。ReID 有一个铁律训练集里见过的车辆ID在测试时绝对不会出现。如果 Vehicle ID 出现在训练集评测阶段又来考它模型就直接记住了指标会高得离谱。所以构造数据加载器时train 和 test 的车辆ID映射表要分开建立。2.3 摄像头与时空信息的价值我在实际做跨摄像头追踪的时候VeRi 的摄像头ID和时间戳字段帮了大忙。普通的 ReID 只依赖视觉特征而 VeRi 可以额外构建时空模型如果同一辆车在 c001 摄像头出现后10秒内出现在 c002 摄像头那这两个图片关联的概率就比较高如果两个摄像头物理距离很远时间差又只有几秒那基本不可能。这就是为什么 VeRi 能支持比单纯视觉检索更高的准确率上限。当然玩转这些附加信息前最好先把纯视觉的 baseline 做扎实。我先用 ResNet50 提取特征只靠视觉相似度检索mAP 能到 60% 左右后面加入摄像头转移概率和时间差惩罚项mAP 又提升了一截。VeRi 这个数据集对算法改进特别友好因为每一步都能有可解释的收益。3. 实操落地从解压到训练的核心步骤3.1 下载、解压与目录整理我在拿到 VeRi.zip 后习惯先建一个干净的工作目录把数据和代码分离。命令很简单mkdir -p ~/datasets/veri cd ~/datasets/veri # 假设你已下载了 VeRi.zip unzip VeRi.zip -d . # 解压后检查目录结构 tree -L 1 .看到 image_train、image_query、image_test 三个目录后说明数据完整。我建议顺手统计一下每个目录的图片数和车辆ID数提前确认数据完整性# 统计训练集中车辆ID数 ls image_train | cut -d_ -f1 | sort -u | wc -l这一步看起来简单但我真遇到过解压过程中文件缺失的情况少了几张图导致训练和论文报告的指标对不上排查了大半天才发现是数据不完整。所以无论从哪里拿到的压缩包先做完整性核验永远是值得的。3.2 自定义 Dataset 类从文件名到训练样本PyTorch 写数据加载器时我把文件名解析和标签映射写在 Dataset 的__init__里避免每次迭代都重复解析。核心思路是每个文件夹里的图片路径、车辆ID、摄像头ID、文件名全部读出来存成列表然后根据是否为训练模式决定返回哪些元信息字段。下面是一个可以直接改用的简化版本支持训练和测试两种模式import os from PIL import Image from torch.utils.data import Dataset class VeRiDataset(Dataset): def __init__(self, root, modetrain, transformNone): self.root root self.mode mode self.transform transform folder_map { train: image_train, query: image_query, test: image_test } image_dir os.path.join(root, folder_map[mode]) self.data [] self.vids set() for fname in sorted(os.listdir(image_dir)): if not fname.endswith(.jpg): continue parts fname.split(_) vid parts[0] # 车辆ID cam parts[1] # 摄像头ID例如 c004 frame parts[2].split(.)[0] self.data.append({ img_path: os.path.join(image_dir, fname), vid: vid, cam: cam, frame: frame }) self.vids.add(vid) # 车辆ID映射字符串转整数标签 self.vid2label {vid: idx for idx, vid in enumerate(sorted(self.vids))} def __len__(self): return len(self.data) def __getitem__(self, idx): item self.data[idx] img Image.open(item[img_path]).convert(RGB) if self.transform: img self.transform(img) label self.vid2label[item[vid]] cam item[cam] return img, label, cam, item[vid]这个类不仅返回图片和标签还把摄像头ID一并返回。原因有两个一是评测时需要按摄像头划分数据二是训练时如果你想插入“跨摄像头困难样本挖掘”摄像头ID是必备上下文。把信息一次性打包好后面写训练逻辑会省事很多。3.3 训练配置与评测细节训练 ReID 模型时最常用的框架是“分类损失 度量学习损失”联合训练。我用的是 ResNet50 预训练模型把最后一层全连接改成数据集车辆ID数同时保留一个 512 维特征向量用于做检索。损失函数用交叉熵加三元组损失三元组损失能拉近同类特征、推开异类特征交叉熵则保证分类边界稳定。训练参数上我建议输入尺寸设为 256×256 或 224×224batch size 用 PK 采样P 个车辆ID每个车辆ID取 K 张图常见配置是 P16、K4也就是一个 batch 共64张图。学习率初始 3e-4采用 warmup cosine 衰减。数据增强不要太猛车辆结构性强过强的颜色抖动反而会破坏关键外观信息我通常只用随机水平翻转和轻微随机擦除。评测阶段用模型提取 query 和 gallery 图片的特征然后做 L2 归一化计算余弦相似度矩阵。mAP 计算逻辑网上有不少现成实现但一个关键点在于匹配时按“车辆ID是否相同”判断不是按图片ID也不是按摄像头ID。有些新手在写评测时把摄像头ID当成标签结果指标完全对不上这个坑一定要避开。4. 常见问题与排查技巧实录4.1 最容易踩的三个坑第一个坑把 VeRi 当成检测数据集来用。VeRi.zip 里的图片主体就是车辆通常不需要再做目标检测这里存放的是“检测后裁剪结果”。如果你要做端到端的检测识别流程需要额外搭配检测数据集。第二个坑训练集和测试集的车辆ID混用。ReID 数据集的划分原则是“测试车辆ID绝不在训练集中出现”。我见过有人为了增加训练数据把测试集的一部分图片也挪去训练最后测试指标高得像作弊但部署到新场景时立刻露馅。在 VeRi 上做实验必须严格使用官方划分最多你在自己的扩展实验里另做一套规则但要标注清楚。第三个坑评测时没过滤 query 自身。如果自定义评测集query 图片同时出现在 gallery 中必须过滤掉这张图片本身否则 Top-1 永远是 1.0mAP 也会虚高。VeRi 官方划分一般没问题但严谨起见评测脚本里最好还是加一个“排除同文件名”的判断。4.2 指标异常速查表现象可能原因处理建议mAP 远低于论文结果图像尺寸不一致、特征未归一化统一 resize 尺寸评测前对特征做 L2 归一化Top-1 很高但 mAP 很低检索排序列表整体质量差前几名对但后面乱检查是否缺少难样本挖掘调节三元组损失的 margin训练 loss 不下降学习率过大、标签映射错乱先跑少量 step确认车辆ID数量和数据长度正确验证阶段报错数据集中有损坏图片遍历所有文件用 PIL 打开校验删除坏图跨摄像头追踪效果差未使用时间戳/摄像头ID信息在视觉特征基础上加入摄像头转移概率或时间差惩罚4.3 调参建议与硬件配置参考我自己的经验是先在 VeRi 上跑通一个小模型比如 ResNet50作为 baseline再去尝试更复杂的 Transformer 或者重排序方法。VeRi 规模中等单张 RTX 3090 大概几个小时就能训练完一个基础版本调试成本不高特别适合做快速迭代。Hardware 方面batch size 64 的话12GB 显存够用如果分辨率提高或者 batch 加大最好上 24GB 显存。数据加载时提前把所有图片的路径缓存在内存中num_workers 设成 4 到 8能明显提高 GPU 利用率。我自己还习惯用混合精度训练FP16VeRi 这种规模的数据集收益虽然没那么夸张但能省一些时间也是好的。另外如果发现训练时准确率一直在低位徘徊先别急着改模型结构。我吃过一次亏把大量时间花在换 loss 上最后发现是图像读取时没有统一 RGB 通道顺序有些图被当成 BGR特征完全学歪了。遇到问题先检查数据流水线再调模型和超参这个顺序能省下无数个晚上。5. 扩展方向与个人体会5.1 从 VeRi 迁移到更大规模场景把 VeRi 上的 baseline 跑通后想进一步提升算法在真实复杂场景下的鲁棒性我建议试试 VeRi-Wild 或者 VeRi-776 的扩展版本。VeRi-Wild 车辆数量超过4万图像超过40万场景更复杂光照、遮挡、视角变化的范围更大。在 VeRi 上学到的 pipeline 可以直接迁移只需要注意车辆ID映射表重新生成以及在更大的数据上梯度更新时要适当降低学习率。如果你最终目标是部署到园区、路口、商场这类场景还需要考虑数据分布差异。VeRi 是特定区域采集的换一个城市、换一套摄像头品牌图像风格差异会非常大。我的经验是在自家场景采集几百辆车的数据做微调再结合 VeRi 这种公开数据集做预训练效果比只用公开数据或只用自采数据都更好。5.2 给新入坑者的几点实操心得我最初被 VeRi 吸引是因为它的数据结构清爽规模适中能很快验证一个想法。后来在这个数据集上反复踩坑反而学到最多的是“数据协议”的问题哪些图片是 query、哪些是 gallery、特征怎么算相似度、mAP 怎么算。这些细节在论文里往往只是几行字真正上手跑一遍才知道坑有多深。如果让我给正要开始的人一个建议我会说先别急着上太复杂的模型把 ResNet50 这个 baseline 在 VeRi 上老老实实跑通再逐步加注意力机制、加重排序、加时空信息。一个能稳定复现 baseline 的代码库比一个调了一堆 tricks 但跑不出可解释结果的模型值钱得多。VeRi.zip 可能不是你见过最大的数据集但它绝对值得你花一个周末认真吃透。本文还有配套的精品资源点击获取