简介《计算机视觉与深度学习实战》中基于深度学习的汽车目标检测章节以PDF形式单独整理面向计算机视觉、深度学习方向的开发者与科研人员尤其适合需要借助MATLAB和Python实现目标检测的读者。该章节从CNN的发展历程切入简述从早期手写数字识别到AlexNet掀起深度结构浪潮的背景随后系统讲解特征抽取器与分类器构成的基本架构、卷积层的深度与步长概念以及局部感知、参数共享、多核卷积、池化降维等关键设计。案例部分以已标记的小汽车样本训练RCNN检测器并采用测试样本计算准确率完整呈现数据加载、模型训练与评测的流程。资源为单份PDF文件大小仅1.2MB便于快速查阅与移动学习。目前已有853人学习。读者可从中获得CNN理论要点、RCNN汽车检测实现思路及MATLAB程序示例为后续在自动驾驶、智能交通等场景中开展目标检测实践打下基础。1. 汽车目标检测的MATLABPython双轨路线先定工具链再动手做汽车目标检测这个方向最常被低估的环节不是模型选型而是工具链的规划。计算机视觉里的深度学习项目一旦落到汽车目标检测这种需要反复调参、快速验证、再上线部署的任务上MATLAB和Python其实是各占一半戏份MATLAB胜在标注可视化、训练接口和调试速度Python胜在迁移学习生态和部署链条。下面按数据集准备、MATLAB训练、Python复现、评测验收这条路线把每一步的参数和坑摆出来这也是《计算机视觉与深度学习实战-以MATLAB和Python为工具-基于深度学习的汽车目标检测》这类案例教程最常见的推进方式。适合正在做计算机视觉大作业、想进入深度学习落地开发、或者为交通场景做检测预研的开发者照着走一遍能省下至少两周试错时间。2. 数据集与标注决定模型上限的第一道工序2.1 公开数据集怎么选KITTI、VOC还是自己标汽车目标检测不像人脸检测有那么多现成的高质量数据集常见可选项其实就是三个方向KITTI、PASCAL VOC、自建数据。KITTI的优势是真实驾驶场景图像里车辆占比大、遮挡和截断频繁、光线变化剧烈标注信息里连遮挡等级和截断比例都有适合做自动驾驶方向的算法验证但它的标注是自成一派的txt格式转换脚本要自己写初学阶段容易被这一层额外负担劝退。PASCAL VOC的价值在于生态几乎所有检测框架都默认支持VOC的XML标注格式配套的预训练权重和评测代码也最齐全car类别在VOC里的样本量足够撑起一次迁移学习实验。自建数据的常态做法是用MATLAB的Ground Truth Labeler或者Python侧的labelImg逐帧标注矩形框缺点是人力成本高一个1000张图的车辆数据集认真标完至少两天而且标注质量直接决定模型上限。我的选型经验是固定的第一步用VOC的car类建立baseline检验训练和评测链路是否通畅第二步叠加KITTI做泛化测试看模型在真实道路场景上的掉点幅度第三步才按业务需要决定要不要自建数据。不要一上来就标自己的数据因为没有baseline的情况下模型效果差你根本分不清是数据问题、标注问题还是训练参数问题排查成本反而翻倍。2.2 MATLAB标注导出从groundTruth对象到CSV用MATLAB做标注的工具叫Ground Truth LabelerApp菜单里直接打开支持视频逐帧标注、矩形框自动插值标完自动生成groundTruth对象。这个对象内部结构有点绕LabelData属性是一张表行名是图片文件名每一列对应一个标注层每个格子里的box坐标是Mx4的double矩阵格式是[x y w h]。很多人第一次在这步翻车把w和h当成右下角坐标直接喂训练接口框全体偏移推理结果自然没法看。把标注导出成统一CSV的常见做法是这样% 从groundTruth对象导出检测框坐标到CSV load(vehicleGT.mat); % 假设变量名是gTruth data gTruth.LabelData; fid fopen(vehicle_boxes.csv, w); fprintf(fid, image,x1,y1,x2,y2,class\n); for i 1:height(data) imgName data.Properties.RowNames{i}; boxes data.Vehicle{i}; % Vehicle是标注层名按实际改 if isempty(boxes), continue; end for j 1:size(boxes, 1) x boxes(j,1); y boxes(j,2); w boxes(j,3); h boxes(j,4); % 关键MATLAB框是[x y w h]这里转成[x1 y1 x2 y2] fprintf(fid, %s,%d,%d,%d,%d,vehicle\n, ... imgName, x, y, xw, yh); end end fclose(fid);这段代码做的事情只有一个把MATLAB内部的[x y w h]框格式转成更通用的[x1 y1 x2 y2]并连同类别写进CSV。转出去之后无论后面用MATLAB训练还是切到Python都从这一个CSV读取避免两套代码各读各的原始标注、格式冲突。这里有个容易忽略的细节LabelData的RowNames默认排序可能和图片文件夹里的实际顺序不一致写CSV前把图片路径和RowNames逐条对齐一遍否则训练时图片与标注错位模型会学到一种固定偏移推理时框总差了那么几个像素。注意MATLAB导出的[x y w h]和VOC风格的[x1 y1 x2 y2]经常被混用转换脚本里务必统一成一种并在训练前做一次可视化抽查这一步能拦下九成的低级错误。2.3 Python侧格式转换CSV到YOLO的txt附坐标裁剪如果后续计划用Python侧的YOLO系列做对比训练标签格式还得再转一层。YOLO系列的要求是每张图片对应一个同名txt每行一个目标内容是“类别id 中心x 中心y 宽 高”且全部归一化到0到1。这个转换脚本我每次做检测项目都要写直接贴出来import os import csv import cv2 def csv_to_yolo(csv_path, img_dir, out_dir, class_map): os.makedirs(out_dir, exist_okTrue) rows {} with open(csv_path, r) as f: for r in csv.DictReader(f): rows.setdefault(r[image], []).append(r) for img_name, objs in rows.items(): img cv2.imread(os.path.join(img_dir, img_name)) if img is None: print(f图片缺失: {img_name}) continue h, w img.shape[:2] lines [] for obj in objs: cls obj[class] if cls not in class_map: continue x1 float(obj[x1]); y1 float(obj[y1]) x2 float(obj[x2]); y2 float(obj[y2]) # 统一转成YOLO的归一化中心点宽高 cx ((x1 x2) / 2.0) / w cy ((y1 y2) / 2.0) / h bw (x2 - x1) / w bh (y2 - y1) / h # 越界坐标裁剪YOLO训练遇到负值或大于1会直接报错 cx max(0.0, min(1.0, cx)) cy max(0.0, min(1.0, cy)) lines.append(f{class_map[cls]} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}) base os.path.splitext(img_name)[0] with open(os.path.join(out_dir, base .txt), w) as f: f.write(\n.join(lines))参数说明class_map传一个字典比如{vehicle: 0}决定类别如何映射到数字idout_dir下生成的txt和图片同名YOLO训练时按图片路径自动去找同名标签。代码里有两处常被抄错的地方一是读图片尺寸必须用cv2.imread之后的shape不要偷懒用标注CSV里的字段因为部分数据集的宽高字段经过缩放后和原始图不一致二是越界坐标必须裁剪标注时手滑把框画出图像边界是家常便饭YOLO的损失函数里出现负宽度会直接崩训练。补充一个数据增强的提醒车辆检测里水平翻转是安全的垂直翻转会生成车在天上、倒立行驶这类假样本不建议开亮度、对比度扰动对夜间场景有效但幅度控制在0.5到1.5倍之间过头了白天车会变成阴间滤镜反而增大误检。这些都属于数据层面看不见的坑模型mAP低了先检查数据再怀疑网络别一上来就换结构。3. 用MATLAB先跑通Faster R-CNN深度学习工具箱的正确打开方式3.1 为什么先在MATLAB里验证优势与边界同样重要说句实话MATLAB在计算机视觉深度学习这件事上的定位很微妙。Deep Learning Toolbox将训练接口封装得很完整好处是几十行代码就能跑通一个Faster R-CNN或者YOLOv2坏处是网络结构想改就得自己拼层自由度远不如PyTorch。我的习惯是一类新任务做可行性验证时MATLAB确实快课程项目和预研阶段特别合适但如果模型要投到生产环境MATLAB导出的模型无论是转ONNX还是做C部署都要经过一番折腾早晚得回Python侧重训一版。对汽车目标检测来说MATLAB更强的其实是另一件事数据检查。训练之前用Computer Vision Toolbox把标注框以透明度覆盖的形式叠到原图上逐张查看能发现大量标错框位、漏标目标、类别标反的问题。这个习惯看起来笨但对检测模型非常值——目标检测对标签噪声的敏感度比图像分类高得多一个框错位0.2个IoU模型就会在对应位置学到错误的特征响应推理时反复出现半框、偏移框。另外MATLAB工具箱里Faster R-CNN的训练链路最成熟训练日志和可视化都比YOLOv2分支完善单类检测任务里两阶段精度也够用所以作为第一轮验证是最稳的选择。3.2 trainFasterRCNNObjectDetector最小可运行训练脚本下面这份脚本是Faster R-CNN在车辆检测任务上的最小可运行配置% 读取第二章导出的CSV组装成训练接口要求的table data readtable(vehicle_boxes.csv); imgDir images/; trainingData table(); trainingData.imageFilename fullfile(imgDir, data.image); % 每个图一个Mx4矩阵注意是[x1 y1 x2 y2]形式 boxes cell(height(data), 1); for i 1:height(data) mask strcmp(data.image, data.image(i)); boxes{i} [data.x1(mask), data.y1(mask), ... data.x2(mask), data.y2(mask)]; end trainingData.vehicle boxes; % 训练选项MiniBatchSize和InitialLearnRate是最常调的两个 options trainingOptions(sgdm, ... MiniBatchSize, 8, ... InitialLearnRate, 1e-3, ... MaxEpochs, 20, ... VerboseFrequency, 20, ... CheckpointPath, ./ckpt, ... Plots, training-progress); % resnet50做骨干网络迁移学习 detector trainFasterRCNNObjectDetector(trainingData, ... vehicle, resnet50, options, ... NegativeOverlapRange, [0 0.3], ... PositiveOverlapRange, [0.6 1]);逻辑说明trainFasterRCNNObjectDetector的第二个参数是类别名第三个是特征提取网络。这里用resnet50而不是自己从零搭网络道理和Python侧用预训练权重一样——骨干网络的特征提取能力是迁移过来的省掉的训练时间通常在一半以上。NegativeOverlapRange和PositiveOverlapRange是RPN阶段锚框的正负样本划分阈值锚框和真值IoU大于0.6才算正样本小于0.3算负样本中间地带忽略。车辆密集遮挡的场景下0.6的门槛会导致正样本数量严重不足常见做法是降到0.5给RPN多一点候选。3.3 训练选项拆解调参顺序比参数数值更重要几个必调参数的含义要说透。MiniBatchSize是每次迭代喂入的图片张数默认值往往超出单卡显存报错就调到4或2但它调小之后梯度震荡加剧初始学习率也要跟着降不然损失曲线会像心电图。InitialLearnRate是整个训练里最重要的旋钮从预训练模型起步1e-3通常安全超过5e-3就可能把骨干网络的原始特征冲掉训练后期想收都收不回来。MaxEpochs别贪多20轮足够观察收敛趋势先跑通再追加。CheckpointPath是后悔药每隔若干轮自动存一份检查点训练崩了直接load最近的权重不用从头开始烧时间。训练选项常用值适用场景MiniBatchSize8单卡8G显存不足降4/2并同步降学习率InitialLearnRate1e-3迁移学习安全起点震荡则减半MaxEpochs20第一轮验证用确认收敛后再加VerboseFrequency20每20轮打印一次loss便于盯训练状态CheckpointPath./ckpt训练中途存档防意外中断我的调参顺序基本固定第一轮全部默认只看两个东西——loss曲线是否稳定下降、训练日志里有没有NaN确定链路通了之后第二步只调学习率损失震荡就降一半下降太慢就翻倍第三步针对数据分布调IoU阈值比如车辆遮挡密集就降PositiveOverlapRange最后才轮到网络结构。很多项目死在第二步之前学习率没调明白就急着换骨干网络等于换了发动机还以为是轮胎的问题。3.4 训练完先做一轮推理扫描训练结束后不要急着算mAP先拿十几张训练集和验证集之外的真实图片做一次可视化推理这一步能暴露大部分低级问题% 加载训练好的检测器跑单张图片 detector load(./ckpt/checkpoint_epoch_20.mat).detector; img imread(test_01.jpg); [bboxes, scores, labels] detect(detector, img, Threshold, 0.35); out insertObjectAnnotation(img, rectangle, ... bboxes, cellstr(labels), FontSize, 18, LineWidth, 3); imshow(out);detect函数的Threshold是置信度门槛可视化阶段我习惯放到0.35宁可多看几个误检框也别漏掉真实目标正式评测时再拉回0.5否则误检会把precision拖下来。看到框位整体偏移、某些尺寸的车完全检测不到这类问题优先检查标注转换而不是调网络——标注错位的概率远大于模型出问题的概率。这一步在MATLAB里做最舒服因为图像可视化工具链不用额外装OpenCVimshow加上insertObjectAnnotation就够盯完一轮。4. 用Python复现同一套检测任务从环境配置到YOLO训练4.1 切到Python的真实理由生态、调试与部署深度学习目标检测切到Python侧不是因为更流行所以选它而是有几个具体刚需绕不开。第一是技巧跟进速度Mosaic增强、自动锚框、余弦退火、早停这些实用技巧Python框架里论文出来没几个月就能用上MATLAB工具箱要等版本更新。第二是调试自由度想在骨干网络上加一个注意力模块PyTorch里改一层forward就行MATLAB得拆网络图拼层。第三是部署链路PyTorch训练完转ONNX再走TensorRT或者直接导出TorchScriptPython侧全程无断点。入门路线方面我的建议是先把cs231n的官方笔记过一遍把卷积网络、反向传播、目标检测的基础概念补扎实再动手跟这个项目。环境上我一般用Miniconda建独立环境IDE用VSCode调试断点功能够用且启动快PyCharm在大型项目里更舒服但吃内存检测任务迭代频繁VSCode的轻量优势更明显。Python安装直接用Miniconda官方安装包装完一句conda create -n det python3.10把torch和ultralytics装进去不要用系统自带的Python版本混乱问题会缠你一个月。4.2 数据配置与YOLO最小训练脚本假设第二章的转换脚本已经生成好训练和验证两个文件夹接下来用ultralytics的YOLOv8跑通这个任务。先写数据配置文件# vehicle.yaml path: ./vehicle_data # 数据集根目录 train: images/train # 训练图片目录 val: images/val # 验证图片目录 names: 0: vehicle # 只有一类id必须从0开始然后是训练脚本from ultralytics import YOLO # 加载COCO预训练权重类别数不同会自动替换检测头 model YOLO(yolov8n.pt) results model.train( datavehicle.yaml, epochs60, # 单类检测收敛快60轮够用 imgsz640, # 输入分辨率见下文说明 batch16, # 显存不够就减半同时lr0也减半 lr01e-3, # 迁移学习的起始学习率 lrf0.01, # 余弦退火末期衰减到1% momentum0.937, weight_decay0.0005, patience15, # 验证mAP连续15轮不涨就早停 augmentTrue, # 默认开Mosaic等数据增强 devicecuda:0 )逻辑说明yolov8n.pt是一个在COCO 80类上训练过的轻量权重车辆这类目标在COCO里样本充足骨干网络的特征迁移价值很高框架加载时检测头会自动按新类别数重建不用手动改网络。epochs设60而不是照搬COCO的300轮原因是单类目标分布集中、收敛快多出来的轮次只是让模型在训练集上钻牛角尖。注意train和val目录下图片与标签要严格同名YOLO按basename匹配差一个后缀都不认目录列表排序不同也不会影响匹配唯独名字必须一致。4.3 关键参数怎么调imgsz、batch、早停与迁移学习imgsz是车辆检测里性价比最敏感的输入分辨率。640是个临界点低于640画面中远距离的小车会被缩到几个像素特征直接消失召回率明显下滑高于640显存占用和推理耗时接近线性上涨而单个车辆框的精度增益迅速饱和。做高速公路场景车辆普遍在画面下方且尺寸大512就能用做路口监控远处大量小车直接上640或960别省这点算力。Batch从16起调显存不够先减半到8同时把lr0从1e-3降到5e-4保持每个样本实际收到的梯度量级大致不变这是迁移学习一个容易忽略的匹配关系。参数建议值说明epochs60单类检测收敛快后期靠早停兜底imgsz640远距离小车多则上960显存约翻倍lr01e-3预训练权重起步别超过5e-3lrf0.01末期学习率为初始的1%别设0patience15验证mAP连续不涨就停省时间Patience是早停参数我习惯设15到20。单类检测的验证mAP往往在最后十几轮就不再上涨早停能省下大量训练时间还能避免模型在训练集上继续过拟合。lrf设0.01表示学习率在训练末期衰减到初始值的1%这是多个检测框架验证过的稳妥区间设成0会让末期梯度完全停住模型容易停在局部极值边缘得不偿失。如果你用的是YOLOv5或更老版本注意autoanchor自动锚框会反复扫描训练集统计锚框分布如果数据规模小这个环节可能反复触发浪费不少训练时间。训练完先跑一次验证集评测# 验证集评测conf设低是为了画完整PR曲线 model YOLO(runs/detect/train/weights/best.pt) metrics model.val(datavehicle.yaml, conf0.001, iou0.6) print(fmAP50-95: {metrics.box.map:.4f}) print(fmAP50: {metrics.box.map50:.4f})metrics对象在不同版本里字段名略有变化第一次跑先print(metrics)或dir(metrics)确认字段再引用map和map50避免版本差异把脚本搞崩。这一步跑通之后MATLAB侧和Python侧就有了可对比的数字接下来进入避坑环节。5. 汽车检测训练避坑五条血泪经验5.1 远距离小车检不到现象训练完模型近处的大巴、货车都能稳稳框住但画面远处的小车频繁漏检而且置信度诚实地给得很低不是那种框住了但不自信的状态。原因小目标在骨干网络逐级下采样的过程中特征被压缩得几乎不剩什么。以YOLO系列为例640输入下特征图最小的格子对应原图约8x8像素区域一辆在画面里只有30x20像素的车经过几次stride之后留下的只是几个弱响应点检测头很难从中恢复可靠分类。这是目标检测的经典尺度困境模型本身没有错是输入分辨率配不上目标尺寸。解决最直接的办法是把imgsz从640提到960或1280显存占用大概翻倍另一个思路是原图切片检测把大图切块放大后再推理在监控场景效果尤其明显数据层面可以有意识地提高远处小车样本的占比让网络在训练期见过足够多的小目标。一个路口监控项目里imgsz从640提到960后100米外车辆的召回从0.62涨到0.78显存从6G涨到11G这个代价是值得的。5.2 car、truck、bus类别边界模糊现象轿车被框成卡车卡车被框成轿车两者的置信度还都挺高看不出网络在犹豫。原因三类目标的外形边界本身模糊。皮卡、SUV、面包车到底算car还是truck不同标注员的标准不一致同样的车换个角度、换个距离人类自己都容易分错。标签噪声就这样被模型完整地学进去了这不是模型蠢是答案本身不唯一。解决第一标准化标注规则定死一条判断依据比如轴距明显长于普通轿车的算truck标注前给标注员看示例图再开标第二如果业务不区分车型直接合并成单一的vehicle类单类检测的mAP通常比细分类高2到4个点。除非下游任务明确需要区分车型否则别为了演示效果硬分细类细分只会给自己添堵。5.3 训练loss持续下降但验证mAP不动现象train loss从2.1一路降到0.3训练曲线漂亮得很但验证集上的mAP从第30轮开始就没再动过甚至轻微回落。原因模型过拟合到了训练集特有的标注噪声和场景分布上泛化能力停滞。单类车辆检测里过拟合的典型信号不是loss反弹而是loss继续降、mAP不涨——网络在记住训练集而不是学会检测。这时候停训练、缩模型都比加大epochs更合理。解决先检查训练集和验证集的划分方式如果它们出自同一段视频的连续帧属于典型数据泄漏必须改成按场景切分比如按不同拍摄时段或不同路段切分否则验证mAP虚高上线即翻车。然后增强数据多样性把HSV颜色扰动和随机遮挡相关增强打开车辆这种颜色丰富、纹理分明的目标对颜色增强很敏感。最后再考虑给模型加Dropout或者换更小容量的网络。5.4 MATLAB和Python推理结果对不上现象同一个权重文件通过ONNX分别导出到MATLAB和Python两侧同一张测试图推理出来的框和置信度存在肉眼可见的差异置信度经常差0.1。原因两个运行时对BatchNorm合并、图像归一化的顺序、甚至插值算法的处理细节不同。MATLAB的imresize默认双三次插值OpenCV的resize默认双线性输入图像差几个像素值神经网络推理结果就会漂。这不是模型坏了是预处理链路不一致权重本身完全没问题。解决在导出ONNX之前把预处理逻辑显式固定下来——是先归一化再resize还是先resize再归一化导出侧和推理侧必须逐位一致确定不了的话写一段逐像素对比脚本把两边的预处理结果输出成数组比差值。这类问题九成是预处理顺序不一致只有一成是模型转换真的出错。别急着怀疑转换工具先把输入数据对齐。5.5 正样本锚框不足导致RPN不收敛现象用Faster R-CNN训练时报No positive anchors或者RPN分支的loss几乎不走训练日志里每个epoch都是同一个数模型等于白训。原因车辆宽高比集中在1.5到2.5之间但默认锚框是按COCO 80类的分布调出来的大量锚框落在车辆样本的IoU阈值之外RPN找不到足够正样本梯度信号接近于零。解决MATLAB侧用estimateAnchorBoxes从训练集标注框重新统计锚框分布% 统计训练集真实框的尺寸分布生成适配锚框 anchors estimateAnchorBoxes(trainingData.vehicle, 9); disp(anchors); % 把结果传给训练函数 detector trainFasterRCNNObjectDetector(trainingData, ... vehicle, resnet50, options, AnchorBoxes, anchors);YOLOv8自带自动锚框训练时会自己统计基本不用管但如果用YOLOv5或更老版本autoanchor可能会反复搜索锚框浪费训练时间数据分布稳定的话直接指定一组先验把这个环节关掉。锚框这件事记住一个判断标准训练日志里出现anchor相关的警告先解决它再谈调参否则后面所有实验都是无效数据。6. 用mAP和PR曲线验收模型评测口径定生死6.1 评测口径先对齐IoU阈值与置信度下限做评测之前先把口径对齐否则数字没意义。mAP50要求预测框和真值框IoU超过0.5就算命中对车辆这种矩形目标偏宽松定位偏差半米也可能混过去mAP50-95从0.5到0.95每0.05取一个阈值算平均对框的贴合精度敏感得多。同一个模型两个指标能差出20个点汇报时必须两个都报只报mAP50会让定位误差蒙混过关。置信度下限同理评测时conf设0.001是为了画出完整的PR曲线但部署时你会提到0.4以上压制误检所以部署实际表现和评测数字不一致是正常的不是模型变了。6.2 手工计算PR曲线和mAP如果用的是YOLOv8val接口已经算好全套指标如果是MATLAB训练后拿Python评测或者自写检测器用下面这个标准过程import numpy as np def compute_ap(detections, ground_truths, iou_thr0.5): detections: [(img_id, box, score), ...] ground_truths: {img_id: [box, ...], ...} dets sorted(detections, keylambda d: d[2], reverseTrue) n_gt sum(len(v) for v in ground_truths.values()) matched set() tp np.zeros(len(dets)); fp np.zeros(len(dets)) for i, (img_id, box, score) in enumerate(dets): best_iou 0; best_gt None for gt_box in ground_truths[img_id]: iou calc_iou(box, gt_box) if iou best_iou: best_iou iou; best_gt gt_box key (img_id, tuple(best_gt)) if best_iou iou_thr and key not in matched: tp[i] 1; matched.add(key) else: fp[i] 1 cum_tp np.cumsum(tp); cum_fp np.cumsum(fp) recall cum_tp / max(n_gt, 1) precision cum_tp / np.maximum(cum_tp cum_fp, 1) ap np.trapz(precision, recall) return ap, precision, recall逻辑说明按照置信度从高到低逐个判断预测框找到当前图片里IoU最高且未被匹配的真值框超过阈值就算TP否则FP。matched去重是关键——同一个真值框被两个预测框同时命中第一个算TP第二个必须算FP这是检测任务和分类任务评测最大的区别漏了这步AP会虚高到没有参考价值。calc_iou实现两个矩形框的交并比注意坐标系的四值表示要一致混用[x y w h]和[x1 y1 x2 y2]算出来的IoU一定是错的。6.3 一个收尾习惯最后说一个我长期保留的固定流程任何检测模型提交前跑一套三件套——验证集mAP50和mAP50-95两个数、PR曲线图、十张典型失败样本的人工检查。前两个指标负责说服别人第三个负责发现指标没暴露的问题。指标好看但失败样本全是远处小车漏检说明评测集里小车占比过低先补数据再谈完成PR曲线尾部骤降说明高置信度区间存在系统性误检先查类别混淆再调阈值。这套流程替我省下了不止一次返工希望帮到你。本文还有配套的精品资源点击获取