简介:电池目标检测数据集专为小型电池分类与定位任务打造,面向需要训练YOLOv7等主流检测模型的开发者与研究人员,可有效解决9伏电池、纽扣电池、干电池三类对象的自动识别问题。包内共2000个文件,绝大部分为txt格式的标注文件,另含1个yaml配置文件,整体压缩包约65.72MB,标注格式与YOLO系列模型直接兼容,省去格式转换环节。该数据集基于约2030张640×640分辨率的原始图片构建,在实验中模型正确识别率达到97.7%,说明数据质量和标注一致性较高。目前已有48人学习使用,适合作为小型工业检测、智能回收分类等场景的起步数据集,可直接用于模型训练、精度验证与迁移学习。
1. 电池数据集到底值不值得用:2030张图把9伏、纽扣、干电池分到97.7%
想象一个场景:电池分拣线上,传送带不停走,工人要在一秒内分辨9伏电池、纽扣电池和干电池,还要挑出混料。这种重复劳动最适合交给视觉检测,但第一步就被数据卡住了。网上下到一个电池数据集,2030张原始图、640×640分辨率、YOLOv7标注格式,宣称正确识别率97.7%。这个数字听起来不错,但靠不靠谱?数据能不能直接用?训练时有哪些坑?这篇文章我就按自己做电池检测项目的经验,把这个数据集从头拆到尾:先讲它包含什么、标注怎么读,再讲怎么用YOLOv7训练和调参,最后把部署和迭代的思路一起说清楚。适合刚接触目标检测的算法工程师,也适合做非标自动化又绕不开视觉的机电工程师。
2. 拆解电池数据集:三类电池的样本构成与YOLOv7标注格式
2.1 三类电池的样本分布与分辨率校验
先说视觉上的硬区别。9伏电池是方形块体,顶部有两个金属扣,侧面有塑料外壳;纽扣电池是扁圆形,银白色,直径从几毫米到两厘米不等,最大的特征是反光;干电池是圆柱形,5号、7号最常见,有正极帽和PVC封套。这三类外形差异大,理论上比区分猫狗简单,但真做起来,纽扣电池反光带来的高光、干电池正极帽和9伏电池金属扣的相似性,都会让模型学到不该学的特征。
拿到数据集第一件事,不是打开图片看,而是先统计类别分布和分辨率。标题写了640×640,但实际下载的数据集经常混入不同尺寸的图,或者标注框类别ID和说明对不上。我会先跑一段脚本,把每类的框数量和所有图片的尺寸统计出来。
from pathlib import Path from PIL import Image label_dir = Path("labels") image_dir = Path("images") class_counter = {} size_counter = {} for txt in label_dir.glob("*.txt"): for line in txt.read_text().splitlines(): parts = line.split() if len(parts) != 5: print(f"格式错误: {txt.name}: {line}") continue cls_id = int(parts[0]) class_counter[cls_id] = class_counter.get(cls_id, 0) + 1 for img in image_dir.glob("*.jpg"): w, h = Image.open(img).size size_counter[(w, h)] = size_counter.get((w, h), 0) + 1 print("类别统计:", class_counter) print("尺寸统计:", size_counter)逻辑说明:这里做了两件事。第一,遍历所有txt标注文件,统计每行第一个数字也就是类别ID的出现次数;同时检查每行是不是正好5个字段,多一个少一个都会导致训练时解析失败。第二,打开每张图片读取宽高,统计分辨率分布。参数说明:如果你的图片是png或bmp,把glob("*.jpg")改成对应后缀;如果txt里出现len(parts)不等于5的行,不要直接跳过,先停下来确认是不是标注工具导出时用了逗号分隔。
类别统计结果能直接看出数据是否平衡。如果三类各占600多框,训练起来比较稳;如果纽扣电池只有200框,9伏电池有1000框,模型天然会偏向多的类别,训练时得靠数据增强或重采样来拉平。尺寸统计也很关键,如果混入一批1920×1080的图,训练时统一缩放到640会损失小目标细节,后面mAP虚高,到了现场又打折扣。
还有一个经常被忽略的点:拍摄场景。从缩略图里能判断这些图是传送带上拍的、桌面静态拍的,还是在托盘里无序摆放拍的。桌面静态图背景单一,模型很容易通过背景色来判断电池类别,而不是通过电池本身。这样的模型拿到产线上,背景一变,准确率立刻掉十个点。我一般会抽样100张图,把标注框加载出来,先人工扫一遍,确认背景多样性够不够。
2.2 读懂YOLOv7标注:归一化坐标到像素坐标的换算
标题里的“yolov7标注”,指的不是用YOLOv7模型来做自动标注,而是标注文件按YOLO格式组织。YOLOv7、YOLOv5、YOLOv8用的都是同一套格式:每张图片对应一个同名txt,图片里的每个目标占一行,内容依次是“类别ID、归一化中心点x、归一化中心点y、归一化宽度、归一化高度”。这里“归一化”的意思是坐标除以图片宽高,所以值都在0到1之间,和图片分辨率无关。
举个例子:一张640×640的图,9伏电池检测框的像素坐标是左上角(240, 150)、右下角(400, 350),那么框宽160、高200、中心点(320, 250)。转换成YOLO格式就是“0 0.5 0.390625 0.25 0.3125”。数字看起来抽象,但正因为只存比例,同样一份标注可以喂给任意输入尺寸的模型。检查标注最直接的办法是把归一化坐标还原成像素坐标,再画回图片上。
def yolo_to_boxes(txt_path, img_w, img_h): boxes = [] with open(txt_path, "r") as f: for line in f.read().splitlines(): cls, x_c, y_c, w, h = map(float, line.split()) x1 = (x_c - w / 2) * img_w y1 = (y_c - h / 2) * img_h x2 = (x_c + w / 2) * img_w y2 = (y_c + h / 2) * img_h boxes.append((int(cls), x1, y1, x2, y2)) return boxes逻辑说明:把归一化坐标还原成像素坐标,方便用OpenCV的rectangle画框检查。参数说明:img_w和img_h必须传实际图片尺寸。这里有个细节,如果原图不是640×640,比如是960×1280,拿着640的假设去还原,所有框都会画错位置。正规做法是先从图片读宽高,再传入。
画框检查的时候,重点看三类问题。第一,框是不是贴着电池外沿,而不是把背景阴影大片包进来;第二,两个目标离得很近时,框有没有互相交叠超过20%;第三,纽扣电池这种小目标,框是不是明显比实际区域大一倍。这些问题一旦带到训练里,模型学到的边界就是错的,表现出来就是验证集mAP很高,但抓细节的位置始终差一点。
2.3 用LabelImg或CVAT复现一套相同标注
如果你要在原始数据集上补充自己的图片,或者想把产线新拍的照片加进训练集,就必须自己动手标注。数据量小、只有一个人干活,用LabelImg最顺手;数据量大、多人协作或者要远程分配任务,用CVAT更靠谱。两者都支持导出YOLO格式,也就是生成和图片同名的txt文件。
LabelImg按YOLO格式保存的配置很容易踩坑。打开LabelImg后,先点击工具栏上的格式切换,把存放格式从PascalVOC改成YOLO,然后设置保存目录到labels文件夹。画框时按W键进入画框模式,松开鼠标后选择类别。这里有一个我翻过车的地方:类别的顺序完全取决于你第一次输入类别的顺序,LabelImg会把这个顺序写进classes.txt。如果你先用“9伏”后用“纽扣电池”,那classes.txt里第0行是“9伏”,第1行是“纽扣电池”。之后训练用的battery.yaml里names列表必须和这个顺序一致,否则类ID就错位了。
CVAT导出的步骤是:在Task里标注完成后,选择Export dataset,格式选YOLO 1.1,会下载一个zip包。解压后里面有obj.names和obj_train_data文件夹,obj.names每一行对应一个类别标签,顺序就是数据集yaml里names的顺序。很多工程师习惯自己写names,结果和obj.names不一致,训练出来的模型看着loss正常,实际推理全错。直接用obj.names生成battery.yaml的names字段,不要手敲。
标注阶段还有一个省时间的经验:电池目标有大量重复结构,尤其同一批次的干电池,外观几乎一样。用LabelImg自带的“自动保存”和“下一张”快捷键,把操作流做成点击键盘就能完成,比来回挪鼠标快一倍以上。标注工具本身不挑,挑的是工作流顺不顺。
3. 用YOLOv7训练电池识别模型:从文件夹到mAP的完整流程
3.1 环境准备:显卡、依赖和仓库
训练YOLOv7不需要特别新的硬件。以2030张图的规模,一张6GB显存的GTX 1660 Super到RTX 3060都能跑,batch size设16,训练100轮大约需要两三个小时。如果只有CPU,也能跑通,但100轮可能要跑一整天,而且BN层在CPU上更新慢,效果未必好。内存16GB起步,训练时磁盘IO也很关键,数据集放在机械硬盘上会拖慢每个epoch。
环境上我习惯用一个干净的conda环境,Python版本3.9,PyTorch按CUDA版本安装。YOLOv7的requirements.txt里包含opencv-python、matplotlib、numpy等常用包,但不会帮你装PyTorch,因为那要配合CUDA手动装。
git clone https://github.com/WongKinYiu/yolov7.git cd yolov7 pip install -r requirements.txt逻辑说明:克隆YOLOv7官方仓库到本地,然后安装训练需要的依赖。参数说明:如果机器上已有PyTorch,担心requirements.txt里的numpy版本把环境搞乱,就加--no-deps参数只装当前缺失的包,torch、torchvision保持你原来的版本。YOLOv7对PyTorch版本不挑,1.10到2.x都能跑,重点是CUDA和torch要匹配。
装完依赖后,跑一句python train.py --help,能打印参数说明就说明环境OK。这里提醒一句,网上很多教程让人把batch size设成64、图片缩到320来加速,但对电池检测来说,纽扣电池本身小,输入尺寸一旦降到320,一个小目标可能只占4×4像素,特征全丢了。所以我在这个项目里坚持用640。
3.2 数据组织:train/val划分与标签校验
YOLOv7官方推荐的目录结构是images和labels两个大目录,下面再按train和val分。很多数据集下载下来是图片和txt混在一个文件夹里,或者train和val已经分好,但val里的标注txt缺失。不管原始结构什么样,统一转换成下面的形式:
dataset ├── images │ ├── train │ └── val └── labels ├── train └── val如果原数据集的图片和txt都在同一个目录,我一般先复制图片,再把对应的txt按同名规则复制过去。这里不要手动改,用脚本。
import random, shutil from pathlib import Path src = Path("raw_data") train_dir = Path("dataset/images/train") val_dir = Path("dataset/images/val") train_lbl = Path("dataset/labels/train") val_lbl = Path("dataset/labels/val") for d in [train_dir, val_dir, train_lbl, val_lbl]: d.mkdir(parents=True, exist_ok=True) all_imgs = list(src.glob("*.jpg")) random.seed(42) random.shuffle(all_imgs) split = int(len(all_imgs) * 0.8) for img in all_imgs[:split]: txt = src / (img.stem + ".txt") if txt.exists(): shutil.copy(img, train_dir / img.name) shutil.copy(txt, train_lbl / txt.name) for img in all_imgs[split:]: txt = src / (img.stem + ".txt") if txt.exists(): shutil.copy(img, val_dir / img.name) shutil.copy(txt, val_lbl / txt.name)逻辑说明:先把所有jpg图片读进来,固定随机种子后按8:2划分为训练集和验证集,然后把图片和对应的txt复制到新目录。参数说明:random.seed(42)保证每次执行划分结果一样,方便复现训练效果。注意这里只处理了jpg,如果原图里有png和bmp,需要把glob("*.jpg")改成匹配所有图片格式的写法,比如直接列出所有非txt文件。
划分之后,还有一道关键检查:train和val的图片名不能有交集,否则相当于验证集泄漏。另外,如果原始数据集已经提供了train.txt和val.txt,那就直接用,不要自己再分,因为作者可能已经按场景分好了。
最后把train.txt和val.txt里每行的路径写成绝对路径,或者直接利用YOLOv7的相对路径逻辑,在数据yaml里指到images根目录,YOLOv7会自动找同名的labels目录。如果训练时报“image not found”,多半就是路径格式问题。
3.3 训练启动:battery.yaml与train.py参数解读
数据目录准备好后,在YOLOv7的根目录写battery.yaml。注意yaml里的names顺序必须与标注txt里的类别ID一一对应。
train: /home/your_name/dataset/images/train val: /home/your_name/dataset/images/val nc: 3 names: ['9v', 'button_cell', 'dry_cell']参数说明:train和val指向图片目录即可,YOLOv7会自动去相邻的labels目录找同名txt;nc是类别数,和names列表长度一致;names里的顺序就是类别ID的顺序,0对应'9v',1对应'button_cell',2对应'dry_cell'。如果你的标注里0是纽扣电池,这里names第一行就必须写'button_cell'。
训练命令我会这样写:
python train.py \ --data battery.yaml \ --cfg cfg/training/yolov7.yaml \ --weights yolov7.pt \ --epochs 100 \ --batch-size 16 \ --img 640 \ --workers 4 \ --device 0逻辑说明:train.py是YOLOv7训练入口。--data指定数据yaml,--cfg指定模型结构,--weights指定预训练权重,--epochs指定训练轮数,--batch-size指定批量大小,--img指定输入分辨率。参数说明:--weights用yolov7.pt预训练权重可以让收敛更快,但如果想从头训练也可以去掉这个参数;--workers表示数据加载的进程数,Windows上设置4以上偶尔会报DataLoader worker错误,改成0最稳,但会慢一些;--device 0是第一块GPU。
关于batch size,显存6GB的卡用16比较稳妥,如果报CUDA out of memory,依次往下调到8或4,同时把--workers降到2。但我不建议用batch size 4,因为BN层在batch size小于8时统计量不稳定,训练出来的模型验证集指标波动大。如果只能调到8,训练时考虑开启同步BN,降低不稳定的影响。
这里提到了YOLOv7和YOLOv8的代码组织不同,但训练流程大同小异。如果团队里已经有了YOLOv8的部署链路,也可以按YOLOv8的数据格式复用这套数据。标题既然锁定了YOLOv7,下面都按YOLOv7的命令来。
3.4 训练日志怎么看:loss、mAP和权重选择
训练过程会实时打印loss,每轮结束后还会在验证集上跑一次mAP。第一次训练电池数据集时,不用急着盯准确率,先看loss曲线形状。正常情况是:前10轮loss快速下降,中间30轮缓慢下降,后面趋于平缓并带一点波动。如果loss一直在降但验证集mAP始终上不去,典型原因是过拟合,看是否数据增强没开,或者训练集图片太少。
YOLOv7训练完一轮,日志里会输出Box、Obj、Cls三部分loss。Box是边界框回归损失,Obj是置信度损失,Cls是分类损失。对电池检测来说,Obj如果偏高,说明模型经常不知道该不该输出框——通常是背景太复杂或小目标太多。Cls偏高,说明容易把纽扣电池和干电池正极帽搞混,这时要去查混淆矩阵。
训练完成后,runs/train/exp/weights目录下会有best.pt和last.pt。best.pt是按验证集mAP挑选的权重,last.pt是最后一轮的权重。默认用best.pt部署,但有时候直接看验证集指标会过拟合验证集,我会把best.pt和last.pt都跑一遍test.py,选择实测更稳定的那个。
python test.py --data battery.yaml --weights runs/train/exp/weights/best.pt --img 640 --conf-thres 0.25 --iou-thres 0.45逻辑说明:test.py会在验证集上评估模型的mAP和召回率。参数说明:--conf-thres 0.25表示置信度低于0.25的预测框会被过滤,--iou-thres 0.45是NMS的IOU阈值。这几个阈值后面部署时还要微调,现在评估用默认值即可。
4. 把正确率从“纸上”做到“现场”:验证、调参与数据增强
4.1 混淆矩阵:找到误判的薄弱环节
训练日志里看到mAP@0.5为0.977,并不代表现场也能到97.7%,那只是在验证集上的表现。你想知道模型真正的短板,要看混淆矩阵。YOLOv7训练完会在runs/train/exp/目录下生成confusion_matrix.png,横轴是真实类别,纵轴是预测类别,对角线是正确率。
以电池场景为例,最常见的混淆出现在“纽扣电池”和“干电池”之间。原因有两个:一是纽扣电池的反光面和干电池正极帽在灰度图上长得像;二是标注时如果把纽扣电池的框画大了,把银色托盘边缘包了进来,模型就学到了“银色圆形区域”这个错误特征。另一个容易混淆的是“9伏电池”和“干电池”,9伏顶部两个金属扣在特定角度下看起来像两个圆形目标,如果框没包住整个电池,模型可能只看到金属扣。
处理混淆的第一手段是检查训练集标注质量,而不是急着换模型。我做过一次实验,把纽扣电池的框全部收紧20%,重新训练后混淆率下降了一半,mAP反而没变。所以说,mAP是一个平均值,它会把多数的准确掩盖少数的错误。你用混淆矩阵找到错误集中的类别,再回头修数据,比在训练参数上做文章更有效。
如果确认标注没问题,再考虑类别不平衡。严格说YOLOv7没有直接暴露按类别加权的参数,常见做法是在损失函数里对Cls loss加权。这个改动对新手不友好,我建议优先用数据增强解决类别不平衡,而不是动损失函数。
4.2 锚框、输入尺寸与batch size的取舍
YOLOv7的锚框是在COCO数据集上用聚类算出来的,默认值偏向中等大小目标。电池检测里三类目标尺寸差异很大:9伏电池可能占整张图50%,纽扣电池只占5%。直接沿用默认锚框,小目标的召回率会偏低。YOLOv7仓库里提供了重新聚类锚框的工具,跑一下:
python tools/kmeans_anchors.py --data battery.yaml --img_size 640 --num_clusters 9 --gen_csv逻辑说明:这个脚本会读取数据yaml里的训练集路径,把所有标注框的宽高聚成9个簇,输出一组更适合电池尺寸分布的锚框。参数说明:--num_clusters 9对应YOLOv7的9组锚框,不要改成其他数字;--gen_csv会生成一个CSV文件,里面是聚类结果,把里面的9行数值替换到cfg/training/yolov7.yaml的anchors参数中。
改锚框这步不是每次都有用。如果你的数据里目标尺寸分布和COCO本来就接近,改了反而会让前几十轮收敛变慢。我的判断标准是:先跑一遍默认配置,用test.py看各类别的AP,如果小目标那一类AP明显低于其他类,再去做锚框聚类。
输入尺寸和batch size是一对矛盾。输入640,batch size就上不去;想加大batch size,就得降分辨率。我的建议是优先保输入尺寸,因为纽扣电池小,分辨率是模型理解细节的基础。6GB显存卡用640+16这个组合在个别情况还是会爆显存,那就在yaml里把模型宽度乘系数,比如用yolov7-tiny或者把yolov7.yaml的width_multiple从1.0改成0.75。这个改动对精度影响不大,对显存占用影响很明显。
4.3 现场光照与背景干扰:数据增强和采图策略
电池这类反光物体,最大的敌人是现场灯光。纽扣电池在射灯下会出现镜面高光,整块区域白成一片,模型如果没见过这种样本,就会漏检。数据增强是第一步。YOLOv7的hyp.scratch.yaml里,hsv_h、hsv_s、hsv_v控制色调、饱和度、亮度的随机扰动,默认值分别是0.015、0.7、0.4。我会把hsv_v调到0.6,模拟现场灯的明暗波动,把hsv_s调到0.9,模拟不同批次电池封套的颜色差异。
但数据增强只能扩充已有像素,弥补不了拍摄角度和光源结构的差异。更可靠的办法是去现场补一批图。操作流程是:先用现有模型跑现场视频,把置信度低于0.8的帧截下来,打上时间戳;然后从中挑出不同光照条件、不同角度的各50张,用LabelImg补标注。把这100张加进训练集,重新用best.pt微调30轮,比在家调一星期参数都管用。
如果现场光源完全固定,还可以在硬件上做文章。常见做法是加一块偏振片消除镜面反射,或者改用红外背光让电池变成剪影。硬件能解决的问题就不要交给模型硬扛,这个道理很多项目到最后才明白。
5. 电池数据集训练避坑指南:5个常见问题与排查
这一章整理的是我在类似电池检测项目里真正踩过的坑,每一条都按“现象→原因→解决”的顺序写。数据集不同,但这些问题几乎都会遇到,尤其是从网上下载的二手数据集,脏数据比想象中多。
5.1 现象:loss降了但mAP不动
原因:数据划分不合理。很多网上下载的数据集,train和val的图片是同一个时段连续拍的,背景几乎一样,模型在验证集上“背答案”成功,loss在降,mAP却卡在某个值上不去。这里要区分两类情况:loss在降但mAP不变,和loss在降但mAP缓慢波动。前者通常是数据泄漏,后者一般是模型容量不够。解决:用场景维度重新划分,比如按拍摄批次、背景、光照条件分组,保证验证集是模型没见过的新场景。没有场景标注的话,可以用图片的直方图做聚类,再按聚类结果划分。补一条检查方法:训练完成后看结果目录里的val_batch图片,如果验证集上的预测框和真实框高度重合,且背景单一,就要怀疑划分太保守了。
5.2 现象:纽扣电池和干电池总是混在一起
原因:类间特征重叠。纽扣电池的反光面、干电池的正极帽在视觉上都是银色圆形。干电池正极帽在暗光下看起来就是一个小圆点,和缩小版的纽扣电池几乎一样。如果标注框又都包了一圈背景,模型根本没机会学到两者的区别。解决:先检查标注框是否紧贴电池本体,把框收紧后重训;再检查数据里是否混入硬币、垫片等干扰物,如果无标注,模型会强行把它们归到纽扣电池。收集干扰物图片单独加一个背景类,或者直接把这些图从训练集里去掉。
5.3 现象:验证集精度高,现场一测就翻车
原因:现场相机色彩、白平衡和数据集图片差异太大。数据集图片多半是手机或普通RGB相机拍的,现场用的是工业相机,如果加了红外滤光片,电池封套颜色完全变样。解决:拿到现场相机后,先拍50张电池图片,和数据集图片放在一起对比色域。色差明显就先做白平衡校正或颜色映射,再进模型。有一个有效办法是让现场相机和数据集拍摄相机的色温、增益尽量一致,如果现场用自动白平衡,模型每次看到的颜色都会变,误检率会升高。不要把现场图直接扔进YOLOv7推理,先保证输入分布一致。
5.4 现象:640×640输入把9伏电池裁没了
原因:原图不是正方形,预处理直接拉伸到640,长宽比被压缩,或者letterbox逻辑不一致。9伏电池长宽比接近1.5,如果被压成正方形,金属扣特征会发生畸变。解决:统一用YOLOv7仓库里的letterbox函数做缩放,不要自己写resize。训练和推理阶段用同一套预处理参数,确保模型的输入分布一致。如果原图有1920×1080,letterbox会保留长边并填充两侧黑边,这是正常的。不要为了省计算量把黑边再裁掉,那会让目标的位置信息发生偏移。检查方法:从训练集里抽几张图,跑一次模型可视化输出,如果9伏电池的检测框明显比标注框小一圈,说明预处理可能出了问题。
5.5 现象:标注文件里出现空框或越界坐标
原因:标注工具导出异常,或者人工框选时误操作,生成width或height接近0的框,坐标归一化后跑出[0,1]范围。这些脏数据训练时不报错,但会让某个类别的loss出现NaN,或者让AP变成0。解决:写一个清洗脚本,过滤所有w或h小于0.005的框,把小于0的坐标裁剪到0、大于1的裁剪到1。清洗完检查每一类的框数量是否和清洗前对得上,对不上的说明有整行被误删,回头检查原始txt。
from pathlib import Path def clean_label(txt_path, min_size=0.005): lines = [] for line in txt_path.read_text().splitlines(): parts = line.split() if len(parts) != 5: continue cls, x_c, y_c, w, h = map(float, parts) if w < min_size or h < min_size: continue x_c = min(max(x_c, 0.0), 1.0) y_c = min(max(y_c, 0.0), 1.0) w = min(max(w, 0.0), 1.0) h = min(max(h, 0.0), 1.0) lines.append(f"{int(cls)} {x_c:.6f} {y_c:.6f} {w:.6f} {h:.6f}") txt_path.write_text("\n".join(lines) + "\n") for txt in Path("labels").glob("*.txt"): clean_label(txt)逻辑说明:逐行解析标注,过滤掉字段数不足5行、宽高小于阈值、坐标越界的框,处理完写回原文件。参数说明:min_size=0.005在640分辨率下对应3像素宽或高,小于这个值的框即使保留也没有训练价值。注意清理前先备份整个labels目录,因为这个脚本是直接覆写。
6. 从数据集到部署:电池分拣模型上现场还要做的三件事
6.1 用TensorRT把YOLOv7压到现场算力
训练完的best.pt是PyTorch权重,现场设备不一定装PyTorch,更常见的部署方式是用TensorRT把它转成engine文件。YOLOv7的export.py支持直接导出带NMS的ONNX,命令如下。
python export.py --weights best.pt --grid --end2end --simplify --img-size 640逻辑说明:--grid让模型输出带网格结构的原始结果,--end2end把NMS算子写进ONNX图里,--simplify用onnx-simplifier做图优化。参数说明:转换完的ONNX用trtexec转成engine,固定输入尺寸640×640。转换后要在同一批测试集上对比TensorRT和PyTorch的mAP,误差一般在0.5%以内,超过就要检查是否有算子精度丢失。
6.2 数据闭环:把误检图加回去
部署不是终点,而是数据迭代的起点。我的习惯是现场跑两周,每天把漏检、误检的截图存到独立目录,一周挑100张,补标注后加入训练集,用best.pt做预训练权重微调30轮。这个闭环跑上两个月,模型对现场光线、角度、摆放方式的适应能力才会真正稳定。迭代时要注意类别平衡,哪类误检多就补哪类的样本,但也要控制每类总量不要太偏。
6.3 投入判断:这个数据集适合什么样的项目
2030张图、三类电池、97.7%正确识别率,这个组合适合做产线分拣的可行性验证、适合做小型工位机的辅助质检,但不适合直接扛高节拍全自动分拣。如果现场电池是随机角度、互相遮挡,图像种类和姿态远超数据集的覆盖范围,就得先补数据再谈部署。拿到数据集后也别急着训练,先用自己的脚本复现一遍标注统计和图片尺寸检查,确认97.7%这个数字能复现,再考虑投入多少时间。我做了几年视觉检测,最大的教训就是:数据整理花的时间永远是训练的好几倍,把标注格式、划分逻辑、清洗脚本固定成一套流程,下次换电池型号,半天就能出一版新模型。这个数据集作为第一个练手项目,正好帮你把这条路走通。希望帮到你。
本文还有配套的精品资源,点击获取