尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

基于YOLOv8的老鼠目标检测:5944张图像数据集训练与部署实战

基于YOLOv8的老鼠目标检测:5944张图像数据集训练与部署实战 简介目标检测是计算机视觉的核心任务之一高质量数据集与高效算法缺一不可。YOLO系列凭借端到端的单阶段检测原理在实时性与精度间取得平衡成为工程落地的首选。面对小目标、复杂背景等现实挑战数据集的规模与标注质量直接决定模型上限。从实验室动物行为分析到粮库鼠害监测老鼠检测需求广泛但类内差异与遮挡问题突出。本文基于一个包含5944张带标签图像的老鼠数据集系统讲解YOLOv8从环境配置、数据体检、训练调优到模型部署的完整流程并深入解析小目标检测、标注格式转换等实战技巧帮助开发者用有限数据训练出可用的检测模型。1. 5944张带标签老鼠图像这个数据集到底能干什么先别急着解压。拿到任何一个标题里写着“YOLO算法 老鼠数据集 5944张图像 带标签”的压缩包第一反应应该是问自己这个数据集我要用来做什么我见过不少人拿到数据集就一顿操作猛如虎解压、配环境、启动训练跑了一晚上出来一个mAP50只有0.3的模型然后就开始怀疑人生。其实问题往往不在模型而在数据本身——你根本没搞懂手里这批数据是什么、边界在哪、能覆盖什么场景。老鼠检测这个方向实际需求比想象中要多得多。实验室动物行为分析要跟踪老鼠的活动轨迹需要知道“老鼠在哪里”养殖场和粮库的鼠害监测需要在夜间红外画面里把老鼠框出来药物实验里要统计特定区域内老鼠的出现频次甚至有些宠物智能设备也需要识别“闯入者是不是老鼠”。这些场景的共同点是目标小、运动快、环境复杂、背景干扰大和通用目标检测里检测人、车、猫狗完全是两码事。5944张图像这个数量级在目标检测数据集里属于“中等偏上”的配置。COCO那种十几万张的规模你个人很难搞定也没必要但几千张图如果标注质量可靠、场景多样性足够完全能训练出一个在特定场景下可用的检测模型。关键问题从来不是“数量够不够”而是“这批数据和你实际要部署的环境像不像”。所以这个数据集的核心价值就在于它给你提供了一个已经标注好的起点省去了最痛苦的数据采集和人工标注环节。你要做的是在此基础上做场景适配、数据筛选、训练调优而不是从零开始攒数据。但我必须泼一盆冷水标题里的“老鼠”两个字和你实际要检测的“老鼠”很可能不是一回事。实验室的小白鼠、下水道的大褐鼠、粮仓里的黄毛鼠外观差异非常大。如果这个数据集拍的是一种老鼠你的部署场景是另一种那直接拿过来训练就是给自己挖坑。后面我会详细说怎么判断和处理这个问题。2. 解压之后第一件事别急着训练先给数据集做个体检数据集的坑绝大多数在训练之前就埋好了。我拿到这个数据集之后做的第一件事不是写训练脚本而是老老实实把文件结构、标注格式、图像内容全部过一遍。这个过程我称之为“数据集体检”做一遍能帮你省下后面几十个小时的试错时间。2.1 压缩包解压后的标准文件结构是什么样的一个好的YOLO格式数据集目录结构通常长这样rat_dataset/ ├── images/ │ ├── train/ │ │ ├── rat_0001.jpg │ │ ├── rat_0002.jpg │ │ └── ... │ └── val/ │ ├── rat_0501.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── rat_0001.txt │ │ ├── rat_0002.txt │ │ └── ... │ └── val/ │ ├── rat_0501.txt │ └── ... ├── data.yaml └── README.md (可选)这是YOLO系列包括YOLOv5、YOLOv8、YOLOv9、YOLOv11通用的组织方式。images和labels两个目录必须严格对应每张jpg图片对应一个同名txt文件。注意是同名连后缀前的名字都必须完全一致否则训练时会报“找不到标签”的错误。有一点要特别留意你可能看到的不是train/val划分而是一个大杂烩目录。有些数据包偷懒把所有图片和标签都放在一起让你自己划分。这不算致命问题但要记住自己划分数据集的时候一定要先打乱顺序再切分。否则如果你的图片是按拍摄时间顺序排列的比如前3000张是白天拍的后2944张是晚上拍的按顺序切成train和val就会导致验证集和训练集分布严重不一致训练出来的模型表现会非常不稳定。2.2 标签文件里的数字到底是什么意思如果数据集确实标注了YOLO格式那每个txt文件里的每一行应该长这样0 0.5234 0.4211 0.2310 0.1852这一行代表一个目标框五个数字的含义分别是0类别ID。因为只有一个类别老鼠所以ID是0。如果数据集里同时有“老鼠”和“老鼠洞”两个类别那就会分别用0和1表示。0.5234目标框中心点的X坐标归一化到0~1之间相对于图像宽度。0.4211目标框中心点的Y坐标归一化到0~1之间相对于图像高度。0.2310目标框的宽度归一化到0~1相对于图像宽度。0.1852目标框的高度归一化到0~1相对于图像高度。注意YOLO格式存的是归一化坐标不是像素坐标。这一点新手经常搞混。如果你打开标签文件发现坐标是像532 188 952 614这样的整数那说明这个数据集的标注是Pascal VOC格式xmin, ymin, xmax, ymax需要先转换成YOLO格式才能用。如果你拿到的数据集有图片却没有标签或者标签是XML/JSON格式那也不用慌。我后面会专门讲标签转换的事。但这里要明确一个原则先确认格式再决定下一步动作。格式错了训练跑得再漂亮都是垃圾进垃圾出。2.3 数据集的分布和场景多样性怎么评估体检的另一个重点是评估图像的多样性。这个步骤太容易被忽略了但恰恰决定了你模型的上限。我给的建议是解压后用脚本随机抽样出几十张图片人工快速扫一遍重点看几个维度背景多样性图片是不是都在同一个笼子里拍的背景是不是只有一种颜色如果背景单一模型会学一个非常强的背景偏置——在实验室白底笼子里可能mAP很高一换到粮库场景就彻底崩掉。老鼠的姿态和大小图片里的老鼠是大的、占画面一半那种还是远处小小的一个点YOLO模型对目标尺寸非常敏感训练集里如果都是大目标实测时遇到小目标会抓瞎。光照条件有没有夜间红外图有没有强光直射、背光、阴影光照变化是目标检测的大敌。如果你的实际部署场景是夜间的而数据集里全是白天的图那基本可以确定要出问题。遮挡情况老鼠一半身体被挡住、只露个头、被笼子栏杆遮住下半身——这类“难例”有多少如果数据集里全是干净完整的整只老鼠模型学到的特征就会过于理想化。有一句经验我反复强调数据集没有最好只有最合适。5944张图听起来不少但如果其中大量图片是高度相似的比如同一个摄像头每隔几秒拍一帧的连续帧那有效信息量其实很低。检测数据集的多样性比绝对数量更重要。3. 从零跑通YOLOv8训练写一份能直接用的配置体检做完确认数据没问题或者问题可控接下来就可以开始训练了。现在YOLO生态里最适合落地的两个版本是YOLOv8和YOLOv11Ultralytics出品我下面都用YOLOv8举例因为它的社区资料最多踩坑也好找答案。3.1 环境安装有哪几个容易被卡住的细节安装Ultralytics的YOLOv8理论上一条命令就够了pip install ultralytics但实际上你大概率会遇到几个和PyTorch版本、CUDA版本相关的问题。我的建议是如果机器上没有PyTorch不要直接装ultralytics先单独装PyTorch再装ultralytics。而且PyTorch的版本一定要和你的CUDA驱动匹配。命令行输入nvidia-smi看右上角的CUDA Version然后去PyTorch官网选择对应版本的安装命令。比如CUDA是12.x就装cu12对应的版本pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121CUDA是11.8的就换cu118的源。这一步要是偷懒后面训练时百分百报错CUDA error: no kernel image is available for execution on the device到时候还得回头折腾。另外Windows和Linux的行为差异很大。Windows上如果用了显卡路径里尽量不要有中文和空格否则读取数据时会出现莫名其妙的编码错误。Linux服务器上则要注意数据集目录的权限。这些都是小事但每一次都是血泪教训换来的。3.2 数据集配置文件data.yaml怎么写训练之前需要写一个data.yaml告诉YOLO你的数据在哪、有几类。对这个老鼠数据集配置如下# data.yaml train: /path/to/rat_dataset/images/train val: /path/to/rat_dataset/images/val # test: /path/to/rat_dataset/images/test # 可选 nc: 1 names: [rat]有几个点需要强调。train和val这里指向的是images目录不是labels目录Ultralytics会自动去找对应的labels目录。默认情况下它会把images字符串替换成labels来找标签文件所以目录命名规范真的很重要。如果你解压后发现目录名不是images和labels就用软链接或者重命名把它们规整成标准结构别指望框架自适应。类别的名字只影响日志显示不影响训练效果但最好写成和实际内容一致后面输出和部署时要看。nc是类别数这个数据集里只有老鼠所以是1。如果数据包里有多个类别而你不知道具体是什么用下面的脚本看标签里的第一列出现了哪些数字import os label_dir path/to/labels/train class_ids set() for f in os.listdir(label_dir): if not f.endswith(.txt): continue with open(os.path.join(label_dir, f)) as fh: for line in fh.readlines(): class_ids.add(int(line.split()[0])) print(sorted(class_ids))如果输出不是[0]而是[0, 1]说明这个数据集其实包含两个类别那你得检查一下第二类的目标到底是什么。千万别想当然。3.3 训练指令和关键超参数的取舍准备好之后训练命令非常简单yolo detect train datadata.yaml modelyolov8n.pt epochs100 batch16 imgsz640 device0这里我默认使用yolov8n预训练权重作为起点。为什么用nano版本而不是large版本原因很简单老鼠检测的目标通常比较小模型参数量大不一定效果好反而增加过拟合风险。而且对于自定义数据集迁移学习的关键不是模型容量而是预训练权重对通用特征的提取能力。nano版本速度快先跑通流程后面再根据结果升级模型复杂度。几个重要参数的选型逻辑epochs100不要少于50。小数据集训练100轮是常规操作。如果到50轮以后mAP还在明显上涨就加到150。batch16取决于显存。12G显存跑yolov8nbatch16绰绰有余。如果你的显卡只有6G降到8甚至4。显存溢出时不会第一时间报OOM而是训练死循环或者进程被kill日志看不出来只能通过排查发现。imgsz640标准尺寸。如果检测目标真的很小比如老鼠在监控画面里只占几十个像素可以提高到960或1280但显存消耗会翻倍。一个更合理的做法是先保持640训练后续用切片推理SAHI补足小目标检测能力。device0指定第一块GPU。没有GPU的用devicecpu先跑通流程但不要指望训练速度CPU训练这个数据集一个epoch可能要20分钟以上。3.4 训练过程的三个信号怎么读训练启动后终端会不停滚动输出每个epoch的loss值。很多人只会盯着看看不出门道。其实只需要关心三个信号第一个是box_loss和cls_loss是否单调下降。训练初期loss小幅震荡是正常的但如果50个epoch过去了loss还在高位震荡不下降说明学习率设置有问题或者数据本身有严重标注错误。第二个是验证集的结果是否和训练集同步提升。如果训练集loss降得很低但验证集mAP原地不动说明过拟合了。这时候可以加数据增强或者把epoch降下来或者用更强的预训练权重。第三个是训练结束后保存的best.pt和last.pt的差异。Ultralytics会每轮验证一次并保存最好的权重到best.pt同时每轮都会更新last.pt。如果两者相差巨大比如best是0.9的mAPlast只有0.6说明训练过程收敛不稳定可能是验证集太小导致评估波动大也可能是数据划分有问题。4. 训练结果出来了怎么看模型到底行不行训练结束后终端会输出一行性能指标一般长这样GFLOPs: 8.2 Speed: 0.8ms preprocess, 6.2ms inference, 1.5ms loss, 4.0ms postprocess per image mAP50: 0.921 mAP50-95: 0.684很多人的习惯是看一眼mAP50超过0.9就欢天喜地宣布大功告成。但实际上mAP50超过0.9在单一类别数据集上并不难难的是在真实场景下能不能稳定工作。mAP50表示IoU阈值在0.5时的平均精度这个0.5的IoU标准其实很宽容——框的位置偏了一些、尺寸大了不少只要重叠面积过半就算检测正确。所以mAP50很高不代表定位精度高。真正要重点看的是mAP50-95它把IoU从0.5到0.95每隔0.05取一个阈值共10个阈值然后取平均。mAP50-95的值通常比mAP50低20~30个点这个数字越接近mAP50说明定位越精准。对老鼠检测来说mAP50-95能到0.65以上基本可以认为模型定位能力合格。如果mAP50-95只有0.3、0.4那说明模型虽然能找到老鼠的大致位置但框得不准。这种情况在生物行为分析这种需要精确坐标的场景里是没法用的。除了看数字更重要的是实际跑几张图看效果。Ultralytics给了非常方便的可视化命令yolo detect predict modelruns/detect/train/weights/best.pt source/path/to/test_images saveTrue执行完去runs/detect/predict/目录下看标注好框的图片。人工看图这一步绝对不能省原因很简单指标是对整体数据集的统计但你真正关心的是个别极端情况的表现。比如某张图里老鼠藏在阴影里模型到底框住了没有框得准不准这类问题只有人眼才能判断。另外务必跑一段视频或连续帧看看。目标检测在单张图片上表现好不代表在视频序列里就不会抖动漏检。老鼠运动速度很快如果模型在连续帧之间频繁出现“检测到-消失-再检测到”的现象说明模型的鲁棒性不足。这时可以考虑加一些视频抽帧数据重新训练或者在推理阶段加入相邻帧的预测结果做平滑。还有一种很容易被忽视的评估方式是按图像分辨率分层看指标。老鼠检测数据里小目标占比很高你可以用脚本统计一下所有ground truth框中宽度小于32像素的占比。如果小目标超过20%但mAP50-95不高问题大概率就在小目标上。YOLOv8本身对小目标有优化但单阶段检测器的下采样倍数通常到20x20特征层决定了对极小目标的天然瓶颈。这种情况的解法一个是提升输入分辨率一个是使用P2层输出yolov8n-p2还有一个是SAHI切片推理我后面会详细聊。5. 老鼠检测特有的三个大坑小目标、类内差异和遮挡我在这个领域踩过的坑比训练过的模型还多挑三个影响最大的说清楚每一个都是实实在在花钱买来的教训。5.1 小目标老鼠在画面里只占几十个像素怎么办监控场景下的老鼠检测99%的痛点都是“目标太小”。你架一台摄像头在仓库角落老鼠出现在画面里可能只有30x20像素在640x640的输入里就是一个很小的框。目标检测的本质问题是特征提取后的特征图尺寸逐层缩小YOLOv8默认会输出80x80、40x40、20x20三个尺寸的特征图分别负责捕捉大、中、小目标。80x80的特征图理论上能检测小目标但实际上每个网格的感受野比较大小目标的有效特征在下采样过程中被稀释得很厉害。解决小目标最实用的三个手段按性价比排序第一是提高输入分辨率。把imgsz从640改成960或1280相当于把图像放大小目标的像素数成倍增加。这个方法简单粗暴但立竿见影。缺点是显存消耗直线上升推理速度下降。训练时可以imgsz960推理时也保持同样分辨率。如果部署端算力有限可以用更大的模型训练蒸馏到小模型上或者用TensorRT加速弥补推理变慢的损失。第二是SAHI切片推理。SAHISlicing Aided Hyper Inference的思路是把大图切成重叠的小块分别送进模型检测再合并结果。比如一张1920x1080的图切成640x640的块每块里的老鼠就会被放大很多倍。我实测过同样的模型用SAHI切片后小目标检测的mAP能提升10~20个点。这个方案唯一的坑是重叠区域会产生重复检测框要靠NMS过滤但SAHI已经内置了处理逻辑基本开箱即用。第三是专门扩样本。从原图上把小目标区域裁剪出来放大后再拼接到其他图片里做数据增强。这个方案叫Copy-Paste增强对提升小目标识别效果非常有效。不过要注意拼接时的尺度要合理别把小目标放得太大否则模型会学到不真实的上下文。5.2 类内差异小白鼠和褐鼠是同一个“老鼠”吗这是很多数据集的隐藏硬伤。老鼠不是一个视觉上均匀的类别实验室的ICR小鼠白色、SD大鼠白色但体型大、野生褐鼠棕色/灰色、黑鼠深灰色它们在颜色、纹理、体型上的差异比人和大猩猩的差异还大。现在你手里这个数据集5944张图的“老鼠”到底长什么样我需要你亲手确认。如果里面全是白色小鼠你在粮库场景里部署遇到褐鼠大概率识别不出来——因为模型学到的特征是“白色红眼睛粉尾巴”而不是更抽象的“老鼠形态”。反过来也一样用野生褐鼠训练的模型在实验室白鼠上表现也会打折扣。处理方式有几种。第一个方案是如果目标任务和数据集内容差异很大那这个数据集只能作为预训练你还需要自己额外采集目标场景的数据来微调。第二个方案是训练时就用带多种噪声的数据增强颜色扰动、亮度变化、灰度化让模型不那么依赖颜色特征而更依赖形态特征。第三个方案是把“老鼠”拆成多个类别比如white_rat和wild_rat两个类别分别标注让模型学习区分。但这需要重新标注成本和收益需要自己权衡。还有一个相关的坑是图像来源单一。很多数据集是从少数几段视频里抽帧生成的同一场景的相邻帧高度相似相当于有效样本只有几百张。判断方法也很简单抽样看图片的背景有没有明显变化。如果所有图的背景几乎一致一定要专门做背景增强或者混入你自己拍的背景图不需要标注作为负样本加入训练。5.3 遮挡和密集场景老鼠叠在一起怎么数得清老鼠经常成群出没而且喜欢钻在各种障碍物之间。这就带来两个问题一是大量遮挡导致目标框不完整模型很难从局部特征判断出“这里有一只老鼠”二是密集场景下目标框互相重叠NMS阈值不好调调低了漏检调高了误检。针对遮挡问题最有效的方法是训练时就用更强的数据增强。Ultralytics默认的马赛克增强mosaic可以把四张图片拼在一起相当于人为制造了很多遮挡和截断样本。我建议训练时开启更强的mixup增强让模型学会在噪声背景下提取老鼠特征。针对密集场景推理时的NMS参数是关键。Ultralytics默认的conf_thres0.25和iou_thres0.45对大多数场景适用但密集老鼠场景建议把iou_thres调低到0.3左右让重叠的框更容易被抑制——不对说反了密集场景恰恰应该把iou_thres调高到0.6~0.7避免互相重叠的两个真实目标框被NMS误杀。这个参数的调节依据是如果模型输出的框大量重叠但只是同一个目标被重复检测你看到的症状是同一个老鼠被框了两三次就把iou_thres调低如果两个挨得很近的老鼠只被框了一个漏检就把iou_thres调高。这类调参没有绝对公式需要结合你的实际结果做实验。但有一点是共性规律先调conf_thres再调iou_thres。conf_thres影响的是“信不信这个检测”iou_thres影响的是“两个框算不算同一个目标”逻辑上要先解决置信度问题再解决去重问题。6. 数据是死的人是活的标注修正和数据集扩展的实战经验数据集拿到手不等于能用标注质量不过关就得自己动手修。这个环节看起来枯燥但回报率极高——我常常说改一天标注比调一个月模型参数更管用。6.1 如何快速定位标注错误并批量修复标注错误的常见类型有四种目标漏标图片里明显有老鼠但没框、框过大或过小边界超出目标或者只框住一半、类别标错虽然只有一类但可能把别的东西标成了老鼠、坐标越界归一化坐标大于1或小于0。手动一张张检查不现实但可以用一个简单的思路快速定位问题训练一个快速模型用它的预测结果和ground truth对比。具体做法是先用全部数据训练一个过拟合程度很高的模型epochs50不加或少做数据增强然后对训练集本身做预测。如果模型预测出了某个框而ground truth里没有对应框说明那个区域很可能是一个漏标的真实目标如果ground truth里有个框但模型死活学不会那可能是标注框有问题太大了、太小了、位置偏了模型学不到稳定特征。除此之外写个脚本检查坐标越界是最基本的import os def check_labels(label_dir): for f in os.listdir(label_dir): if not f.endswith(.txt): continue path os.path.join(label_dir, f) with open(path) as fh: for line_num, line in enumerate(fh, 1): parts line.strip().split() if len(parts) ! 5: print(f{f}:{line_num} 字段数量异常: {line}) continue cls, x, y, w, h parts try: x, y, w, h map(float, (x, y, w, h)) except ValueError: print(f{f}:{line_num} 非数字坐标: {line}) continue if x 0 or x 1 or y 0 or y 1 or w 0 or w 1 or h 0 or h 1: print(f{f}:{line_num} 坐标越界: {line})这个脚本很有用但只能查出最明显的错误。真正影响模型效果的往往是那些不越界但框得不准的标注这种只能靠人工抽样检查。6.2 标注格式转换VOC、COCO和YOLO怎么互转你拿到的数据集不一定直接是YOLO格式。假设解压后发现是VOC格式的XML标注每张图对应一个xml文件第一反应不要慌转换脚本网上很多但最好自己写一遍理解背后的逻辑。VOC格式的XML里坐标是像素值角点方式——记录的是左上角(xmin, ymin)和右下角(xmax, ymax)。转换到YOLO格式需要做三步读图片宽高或从XML的size节点读算中心坐标和宽高cx (xmin xmax) / 2cy (ymin ymax) / 2w xmax - xminh ymax - ymin归一化所有值除以图片宽度或高度一个最精简的转换脚本是import os import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, out_path, class_names): tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) lines [] for obj in root.findall(object): cls_name obj.find(name).text if cls_name not in class_names: continue cls_id class_names.index(cls_name) box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) cx (xmin xmax) / 2 / img_w cy (ymin ymax) / 2 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) with open(out_path, w) as f: f.write(\n.join(lines)) class_names [rat] # 对每个xml文件执行 voc_to_yolo(...)这里特别强调一个细节xml里的xmin、ymin是整数像素但如果边界标注超出了图片范围xmin 0 或 xmax 图片宽转换后坐标可能为负或大于1前面那个越界检查脚本就能派上用场。COCO格式稍微复杂一点它是JSON文件通过images数组里的id关联annotations数组里的image_id坐标用bbox字段存的是[x, y, width, height]格式左上角宽高非中心。转换逻辑类似只是解析方式不同。6.3 怎么用公开数据扩充你的训练集如果确认手里的5944张图覆盖场景不够一个很划算的路径是补充公开数据。目前能找到的老鼠检测相关数据集主要分布在Roboflow Universe、Kaggle和个别学术项目页面上。Roboflow上一个叫“Rodent Detection”的数据集就可以下载格式支持直接导出YOLOv8格式非常省事。但公开数据一定要做一致性检查类别定义是否一致标注框风格是否一致比如有的数据集会把笼子也标进去图像分辨率差异有多大这些不一致会干扰训练。我的建议是公开数据不要一股脑全混进来先抽样检查再用前面说的快速模型验证数据是否一致最后小规模试训对比加数据前后的指标差异。还有一种扩展思路是用训练好的模型做伪标注。训练得到一个不错的模型后拿它去对你的未标注视频/图片做预测然后人工检查并修正预测结果把合格的框加入训练集。这是半监督学习的最简落地版成本低见效快。但务必注意伪标注的质量会直接决定扩展数据的质量人工检查这一关绝对不能省。省了这一步就等着模型在错误标注上越学越歪。7. 从测试到落地导出、部署和集成的一个完整路径训练收敛了测试指标满意了接下来才是真正的考验——把模型部署到实际环境里。7.1 导出ONNX和TensorRT要注意的坑Ultralytics提供了便捷的导出命令yolo export modelruns/detect/train/weights/best.pt formatonnx imgsz640导出ONNX后可以用ONNXRuntime在CPU/GPU上进行推理也可以继续导出TensorRT引擎通常后缀为.engine以获得更高的推理速度和更低的显存占用yolo export modelruns/detect/train/weights/best.pt formatengine device0这里有几个坑要注意。第一导出的imgsz必须和训练时保持一致。如果你训练时用了960的输入尺寸导出时却用640模型等于被强行缩水精度损失肉眼可见。第二TensorRT引擎的生成和GPU型号强相关在A卡上生成的engine基本没法在B卡上直接用需要重新导出。第三导出engine时最好指定halfTrue启用FP16推理如果你的GPU支持速度能翻倍精度损失通常可控。7.2 用ONNXRuntime写一个简洁的推理脚本ONNX的好处是部署环境依赖少不需要装完整的PyTorch。一个最小可用的推理脚本是这样import cv2 import numpy as np import onnxruntime as ort session ort.InferenceSession(best.onnx, providers[CUDAExecutionProvider, CPUExecutionProvider]) input_name session.get_inputs()[0].name input_shape session.get_inputs()[0].shape # [1, 3, 640, 640] def infer(image_path, conf_thres0.25, iou_thres0.45): img cv2.imread(image_path) img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) resized cv2.resize(img_rgb, (640, 640)) input_tensor resized.astype(np.float32) / 255.0 input_tensor np.transpose(input_tensor, (2, 0, 1))[None, ...] # [1,3,640,640] outputs session.run(None, {input_name: input_tensor})[0] # [1, 84, 8400] predictions outputs[0].T # [8400, 84] # 后面接NMS、坐标还原等逻辑 # 这里省略实际项目中建议直接用ultralytics的predict接口做原型 # 性能敏感再替换成ONNX/TensorRT的推理。很多人在这一步会纠结要不要手写NMS和后处理。我的建议很直接项目原型阶段直接用Ultralytics的推理API不要急着优化推理栈。先用它验证模型效果确认没有问题后再着手写C/TensorRT部署。不要一上来就搞工程化因为模型还没验证可靠之前工程化的每一分钟都是在给错误方案加固。7.3 摄像头实时检测的场景RTSP拉流和帧处理策略真正落地老鼠检测大概率要对摄像头视频流做实时检测。RTSP拉流用OpenCV的VideoCapture就能处理cap cv2.VideoCapture(rtsp://user:pass192.168.1.100:554/stream1) while True: ret, frame cap.read() if not ret: break # 关键不要在每次循环都跑全图检测 # 可以隔帧检测比如每3帧检测一次检测结果在有新结果前保持不变 results model(frame, verboseFalse) annotated results[0].plot() cv2.imshow(rat detection, annotated) if cv2.waitKey(1) 0xFF ord(q): break这里面最容易被忽略的是延时控制。老鼠动作快摄像头RTSP流的传输本身就有几百毫秒延迟你再用大模型做推理如果每帧要跑100ms那得到的结果几乎不可用。实操中几个调整方向换小模型用yolov8n而不是yolov8x、降低输入分辨率、跳帧检测、用TensorRT加速。具体选择取决于你的硬件平台和精度要求没有万能答案。还有一个很容易踩的坑老鼠检测的场景通常在夜间而很多摄像头的夜间模式是红外黑白画面。如果你训练数据里全是白天彩色图夜间红外图一张都没有那部署到现场后的表现会非常惨烈。条件允许的话务必在目标场景实地采集一些图像哪怕只有几百张加进去做微调效果提升都可能是决定性的。8. 最后讲一个容易被忽视但很有用的技巧训练时就把推断场景考虑进去这不算一个完整的章节更像是我个人的体会分享给看到这里的你。很多人训练数据集时只看训练集内容完全不考虑最终部署时的环境差异。但事实上训练时的数据增强策略完全可以针对部署环境做“预适配”。比如你知道部署场景是红外黑白画面训练时就在增强管线里加hsv_h0、hsv_s0把饱和度调成0强制模型看灰度特征。你知道白天有强逆光就加强亮度对比度扰动。这些在Ultralytics里都是现成的超参数不用改代码只需在训练命令里加yolo detect train datadata.yaml modelyolov8n.pt epochs100 imgsz640 hsv_h0.01 hsv_s0.2 hsv_v0.4 translate0.1 scale0.5 fliplr0.5这些参数的实际效果是让模型见过足够多“变形”后的老鼠从而在真实环境中不至于因为视角、光照、尺度变化就认不出来。数据增强不是锦上添花而是把训练集的有效多样性放大好几倍的关键手段。在我经手的项目里团队常常会忽略一个更基础的细节——图像的EXIF方向信息。很多手机或相机拍出来的照片在图像查看器里是正着的但读进OpenCV里却是旋转90度的EXIF Orientation信息没有应用。如果你的数据集来自不同设备采集运行训练前批量检查并修正所有图像的方向信息能避免一大批莫名其妙的问题。这个坑我在其他项目里踩过非常痛苦模型训练期间loss一直在降但验证集指标就是奇差无比最后发现是部分训练图像方向不对模型学了半天“旋转的老鼠”。数据集本身只是一个起点不是终点。5944张带标签的老鼠图像听着很完整但只有经过你自己的场景适配、质量筛查、训练调优和部署验证它才能真正变成可用的东西。数据是死的人的判断和经验才是让它活起来的那口气。希望你在训练老鼠检测模型时少走一些我走过的弯路。本文还有配套的精品资源点击获取
返回列表