种地的都知道,棉田虫害发现晚一周,产量损失就补不回来。我前两年跟着某农业示范基地的植保团队做课题,天天蹲在田里拍虫子、数虫子、被棉铃虫折磨到头秃,最后落地了一套基于深度学习的棉田虫害轻量化检测系统。说它"轻量化",是因为真正跑到一线的设备根本不是什么高端GPU服务器,而是树荫下、田垄边一个巴掌大的边缘计算盒子,供电靠太阳能板,算力紧张到得精打细算每一兆的模型内存。这篇文章就把我从数据采集、模型选型、训练调参,到部署实测、解决现场问题的全过程完整捋一遍。核心围绕"虫害目标检测怎么做""轻量化到底轻到什么程度""从实验室到棉田还差哪几步"展开。适合正在做农业视觉项目、或者手里有一个边缘部署需求但没想清楚技术路线的同学参考,踩过的坑我会直接标出来。1. 先想清楚一件事:棉田虫害检测和普通目标检测根本不是一回事1.1 虫害场景的“难”和你想得不一样很多人第一次接触这个课题,脑子里想的还是经典目标检测任务:识别图片里有没有猫、有没有车、有没有人。但棉田虫害检测的难点是另一套逻辑。首先是目标尺寸小,早龄期的蚜虫可能只有几个像素到十几个像素,普通检测器对这种小目标天然不友好。其次是密集,叶片背面密密麻麻的虫卵、若虫挤在一起,标注框经常互相重叠甚至一个框里套好几只。第三是遮挡,虫子藏在叶背、蜷在花蕊里,可见特征非常有限。最后是背景干扰,棉田里阳光、泥土、水滴、枯叶、滴灌带这些东西颜色纹理和昆虫高度相似,模型很容易把环境噪声当虫子。还有一个很实际的问题:田间数据本身就不是高质量数据。你可能凌晨背着设备去拍,光线昏暗;中午太阳直射,叶片反光;风一吹叶片晃动,画面模糊。手机拍的、植保无人机拍的、固定摄像头拍的,角度、距离、分辨率完全不一样。这种情况下,如果一个模型在实验室公开数据集上表现很好,到棉田里大概率折戟。所以课题的第一课不是选什么模型,而是理解生产环境对模型提出的真实约束:既要盯得住微小的目标,又要在廉价设备上实时响应,还要能扛住复杂光照和背景变化。这个"既要又要"就决定了后面所有技术决策的方向。1.2 为什么必须做轻量化一开始我也纳闷,既然已有的大模型在通用检测上效果不错,直接用不就行了?后来算了一笔账就老实了。真实田间监测设备是什么水平?市面上常见的边缘计算盒子,CPU算力有限,GPU单元比手机AP略强,内存一般4到8GB,功耗要求往往压在5W到15W。一个ResNet50级别的Backbone配合FPN检测头的模型,参数量动辄几十兆甚至上百兆,浮点运算量上百GFLOPs,在桌面上能跑到30帧,一旦部署到边缘设备,单帧推理立刻变成一两秒甚至更慢。棉田监测不是单张图片处理,而是连续视频流分析,一秒处理一两帧,漏检的风险会大幅上升。更重要的是功耗和成本。农业场景对设备成本非常敏感,一个几万元的推理服务器不可能摆在每块田边,但一个几百元的嵌入式盒子可以。轻量化模型的价值就在这里:更少的参数、更低的浮点运算量、更小的内存占用,换来能够在低功耗设备上连续运行的能力。同时模型小,下载更新快,田间的弱网环境也能顺利升级。我最终把模型大小控制在10MB以内,单帧推理时间控制在毫秒级,在边缘设备上稳定跑20帧以上,同时保持了可用的检测精度。这个"甜点区间"是反复试出来的,后面我会讲具体怎么调。2. 数据才是硬骨头:采集、清洗、标注、增强全是细节2.1 棉田数据采集方案与坑位数据采集是整个项目里最耗时、最容易被低估的一环。我前后分了三个阶段来做:第一阶段是借用植保站的固定摄像头,连续记录不同时段、不同天气、不同光照条件下的视频流;第二阶段是带着手持设备去田里补拍特写,尤其针对低龄若虫、卵块这类小目标;第三阶段是把无人机航拍数据加进来,增加多视角样本。每个阶段都有教训。固定摄像头的分辨率如果低于1080P,想看清蚜虫几乎不可能,所以采集设备必须保证最低清晰度。无人机高度一旦超过3米,地面目标就缩成几个像素,很多样本只能含泪丢弃。手持拍摄看似灵活,但人的影子、设备反光都会引入噪声。我后来定了一条操作约束:所有采集动作都尽量在自然光下完成,不补光、不逆光,镜头与叶面保持45度到90度夹角,避免把阴影当成目标特征。数据清洗也极其重要。田间数据里经常出现空帧、剧烈运动模糊、叶片完全遮挡这类"废图"。如果不过滤,模型会花大量容量去拟合噪声。我当时的做法是先用一个简单的清晰度指标批量筛选,把这些废图直接剔除;然后再人工快速浏览一遍剩余图片,把带严重偏色和反光的也去掉。清洗完的数据集干净不少,模型收敛速度明显变快。2.2 标注规范与增强策略要匹配检测目标标注工具我用的开源标注平台CVAT,支持多人协作,也方便导出COCO格式和YOLO格式。关于标注,我踩过最大一个坑是"标得太实"。有经验的人都知道,目标检测框需要留一点点边缘,不能贴得太紧,也不能包太多背景。棉田虫害经常是密集分布,如果框太贴合,框与框之间大量重叠,后处理里NMS会误杀很多正确检测;如果框太松,背景噪声又会混进特征学习。我最后统一了一套规则:框边距目标轮廓约2到3像素,重叠面积过大时允许微调。数据增强方面,我尝试的顺序值得参考。先上通用几何增强:旋转、平移、缩放、翻转。这里注意,棉田场景里90度旋转可能让图像语义发生变化,所以旋转范围我锁在正负15度。接下来是颜色扰动:亮度、对比度、饱和度、色调随机变化,模仿不同天气光照。然后是大杀器Mosaic增强。四张图拼接成一张,让模型看到更多尺度变化,对小目标检测特别有用。最后是专门针对密集小目标的Copy-Paste增强:从一张图里把虫子的区域裁出来,随机粘贴到另一张图上。这个操作直接把小目标样本密度拉上来,效果立竿见影。还有一个容易被忽略的操作:加入负样本。我放了一批完全没有虫子的棉叶图像进训练集,让模型学会"这里没有东西,不要输出框"。加上负样本之后,误报率下降非常明显。注意:数据增强不是越多越好。增强太猛,具体表现为训练损失死活不降,验证集效果反而差。要盯着验证集的mAP做决策,而不是凭感觉堆增强策略。3. 模型选型与轻量化改造:精度、速度、体积的三角博弈3.1 主流轻量模型横向对比我先后测试了好几类轻量模型,简单做个对比供参考。模型参数量计算量端侧实测FPS原始mAP备注YOLOv5s7.2M16.5G28中综合平衡,易训练YOLOv5n4.3M7.2G38中偏低体积小,速度极快YOLOX-Nano2.3M5.0G40中偏低无锚框结构,部署时略麻烦MobileNetV3-SSD5.6M8.6G22低小目标表现一般EfficientDet-Lite04.3M2.5G25低计算量最低,但精度天花板低这里面的数字是我的实测值,原论文里的mAP通常是在COCO这种数据集上的结果,直接硬搬到棉田数据上没有任何意义。我自己的结论是:YOLOv5s作为基线最合适。它训练稳定、资料多、部署工具链成熟,YOLOv5n更小但精度下降明显,MobileNetSSD的速度和精度在密集小目标场景下都不占优,EfficientDet-Lite系列计算量虽低但精度上限实在太紧。3.2 轻量化改进:从替换Backbone到注意力模块的克制使用选定YOLOv5s之后,我做了三处轻量化改造。第一处是替换Backbone。我试验过把主干换成MobileNetV3和ShuffleNetV2。MobileNetV3在公开图像上分类精度很不错,但测下来在密集小目标场景下并没有展现出优势,特征提取对小目标的响应偏弱。ShuffleNetV2倒是让整体计算量降低了不少,但代价是精度掉得有点多。权衡下来,我保留原版的CSPDarknet结构,但把通道数和深度都做了缩减,把最重的几个卷积模块换成深度可分离卷积。这一通操作下来,计算量砍了差不多三分之一,精度损失控制在可接受范围内。第二处是引入轻量注意力模块。我试过SE模块和ECA模块。ECA效果好一点,因为它避免了全连接降维带来的信息损失,只通过一维卷积做局部跨通道交互,计算开销几乎可以忽略。我把它插在Backbone后面两个Stage以及Neck部分,确实能看到mAP小幅回升。这里必须强调一个经验:注意力模块不是哪里都插,插多了会直接拖慢推理速度,而且收益会递减。我最后全模型只插了5个ECA模块,多一点都不要。第三处是Neck结构微调。针对小目标,我增加了一个浅层特征图输出,也就是在原本的P3、P4、P5之外,再把P2层引入检测头。P2层分辨率更高,能保留更多空间细节,小目标的检测召回率因此提升。代价是计算量稍有增长,但轻量化省下的预算足够覆盖这一点,整体依然在可接受范围内。整套方案跑下来,最终模型参数量控制在7MB左右,单帧推理在边缘设备上从最初的1.2秒缩短到45毫秒,mAP比原始YOLOv5s只低了不到两个点。这个结果让我比较满意,也是后面所有部署工作的基础。4. 训练实现全流程:参数细节与调优心得4.1 环境、数据划分与训练配置训练环境就是常规的深度学习环境,PyTorch框架,GPU用了一台中端训练卡,CUDA环境版本和PyTorch版本对齐。数据集按照8:1:1划分成训练集、验证集、测试集。划分的时候有个细节:同一个摄像头连续时间段拍出来的图片高度相似,如果随机划分,验证集和训练集容易混入内容相近的样本,导致mAP虚高。我按"来源批次"分组划分,也就是同一批采集的图片要么全进训练集,要么全进验证集,这样评估结果才可信。训练配置方面,我直接给出一组经过实测的参考参数:参数取值输入分辨率640x640Batch Size32初始学习率0.01优化器SGD + Momentum 0.937训练轮次100Warmup5轮Weight Decay0.0005EMA开启,衰减系数0.999这组参数是常规配置,效果稳定。如果显存紧张,Batch Size可以降一半,也可以同时启用梯度累积,保证等效Batch Size不变。学习率通常也要相应调低,从0.01降到0.005,否则前期loss容易震荡。4.2 损失函数、学习率策略与小目标专项处理损失函数方面,常规YOLOv5使用CIoU损失,我在小目标检测上做了微调。CIoU对微小目标的位置偏差非常敏感,几个像素的偏移就会导致损失剧烈波动。我改用Alpha-IoU,它的非单调聚焦机制能够增强对高IoU样本的权重,小目标回归更稳。实测在棉田数据集上,Alpha-IoU让小目标的召回率明显改善,代价是收敛速度略慢,需要配合稍长的训练轮次。学习率策略我推荐使用余弦退火。前期用5个轮次的Warmup让训练稳定起步,之后学习率按余弦曲线衰减到接近0。相比固定步长下降,余弦退火在训练末端能更细腻地收敛到局部最优点,最后的mAP一般会高出一点几个点。还有一个被我验证过多次的"笨办法":多尺度训练。我在训练中每隔一个Batch就从640、672、704、736这几个分辨率里随机挑一个作为输入尺寸。这个策略让模型对目标尺寸变化更鲁棒。代价是训练时间会增加约20%,但换来的是在田里面对不同高度摄像头时表现稳定,这笔投入很值。EMA也要开。简单说,EMA就是对模型参数做滑动平均,相当于在训练过程中累积出一个更平滑的模型。开启EMA之后,验证集精度通常能提升0.5到1个点,而且几乎不增加训练成本。动手训练之前,这几项最好一次性在配置里打开,别等训练到一半再回头补救。5. 部署落地:从PyTorch模型到田间边缘设备的最后一公里5.1 模型转换、量化与精度损失控制训练完的PyTorch模型不可能直接扔到边缘设备上跑。标准流程是先导出ONNX中间格式,再做设备端的推理引擎转换。ONNX导出这块经常出问题的一个点是动态尺寸。为了让模型灵活应对不同输入尺寸,有些同学会把动态轴全部放开,结果转换后的模型在设备上推理时出现不规则卡顿甚至内存越界。我的做法是固定输入尺寸为640x640,把动态轴全部关闭。虽然灵活性牺牲了,但稳定性和执行效率是最重要的。接下来是模型量化。边缘设备通常支持FP16和INT8推理。FP16最简单,转换后精度损失几乎可以忽略,体积减半。INT8则需要准备校准数据集,我用的是验证集里采样的500张图片,在转换工具里跑完校准后,模型大小从7MB压缩到2.8MB,单帧推理时间进一步缩短。INT8带来的精度损失主要集中在小目标上,实测mAP掉约1.5到2个点,在可接受范围。提示:如果目标场景里小目标占比很高,不建议直接上INT8。可以先跑FP16版本,把精度和速度基线都测出来,再评估有没有必要进一步量化。分阶段做,排查问题时思路会清晰很多。5.2 实测定点与现场性能数据我把编译好的模型部署到了一个边缘计算盒子上,用USB摄像头接入视频流,计算输出检测结果。现场实测环境是棉田边缘的固定支架,摄像头距地面约1.5米,斜向下45度拍摄,视野里同时包含叶片、地面和滴灌带,背景复杂度比较高。性能数据给大家参考:FP16模型单帧推理耗时48毫秒,加上前后处理大约55毫秒,换算下来大概18帧每秒;INT8模型单帧推理耗时32毫秒,加前后处理约38毫秒,能跑到26帧每秒。这个帧率对于虫害监测完全够用——虫子的移动速度不快,连续视频流里每秒十几帧足以捕捉大多数情况。如果还想进一步提升帧率,可以在接入端设置抽帧策略,比如每两帧处理一次,再配合输入缩放,速度还能再翻一倍。现场还发现一个问题:棉田里气温高,边缘盒子如果被太阳直射,表面温度能到60度以上,推理速度会明显下降,严重时直接死机。后来我加了一个简易遮阳罩并调整了支架角度,温度控制在45度以内,设备才稳定。这种细节,实验室环境里根本不会暴露。6. 常见问题与排查方法实录6.1 小目标漏检严重怎么调漏检永远是虫害检测的头号痛点。如果是密集的小目标类型,排查顺序建议是:先看数据层面,检查训练集里小目标的标注框数量是否充足。如果小目标占比过低,优先做Copy-Paste增强,把小目标样本数量补上来。再看模型层面,确认有没有针对小目标增加高分辨率特征层。最后看推理层面,把输入分辨率从640提高到768或832,小目标在更高分辨率下像素更多,检测难度会明显降低。用这招,很多情况下漏水率能降一半。6.2 训练Loss不降或震荡Loss不降最常见的原因是学习率设置过高或过低。可以打印出前10个Batch的Loss变化曲线看一眼,如果刚开始就暴涨,多半是学习率太高;如果纹丝不动,可能是学习率太小或者模型完全没有收敛。还有一个隐蔽原因是数据增强过猛,特别是Mosaic加Copy-Paste同时拉满,样本分布过于随机,模型反而学不到稳定特征。我遇到过一次loss震荡一整轮的情况,最后就是降低增强强度并尝试增大Batch Size解决的。6.3 模型过拟合采集数据有限时基本躲不过过拟合。典型表现是训练loss一直降、验证mAP却不再上升甚至下降。我的处理办法按优先级排序:优先给数据增强"加码",这是低成本且收益高的;其次是使用更大的Weight Decay;再次是引入随机失活。如果这些都试过还是过拟合,那就老老实实回田里补拍数据,尤其是不同天气条件下的样本。6.4 部署后推理速度不达标模型在本地FPS爆表,部署到边缘设备却卡成PPT,通常问题出在前处理和输入输出部分。比如OpenCV读取视频流的方式、缩放算法的选择、NMS的后处理实现,都会吃掉大量时间。我最后把NMS部分替换成快速实现,并把图像缩放从双线性插值换成了更高效的插值方式,单帧总耗时立刻降低了15毫秒。另外,确认推理引擎是否真正启用了硬件加速也很关键,排除下来,有时候单纯是工程实现没写对。我个人在反复打磨这套系统的过程中最大的体会是:农业AI项目拼的根本不只是模型结构多花哨,而是整个数据-模型-部署闭环里能不能把每个环节的不确定性都压下去。模型轻量化只是其中一块拼图,前期的数据规范和后期的现场处置同样决定项目成败。如果你正准备做类似的轻量化检测课题,建议把采集和标注的时间预留充足,那部分花的时间,最终都会在训练和部署阶段加倍还回来。
种地的都知道,棉田虫害发现晚一周,产量损失就补不回来。我前两年跟着某农业示范基地的植保团队做课题,天天蹲在田里拍虫子、数虫子、被棉铃虫折磨到头秃,最后落地了一套基于深度学习的棉田虫害轻量化检测系统。说它"轻量化",是因为真正跑到一线的设备根本不是什么高端GPU服务器,而是树荫下、田垄边一个巴掌大的边缘计算盒子,供电靠太阳能板,算力紧张到得精打细算每一兆的模型内存。这篇文章就把我从数据采集、模型选型、训练调参,到部署实测、解决现场问题的全过程完整捋一遍。核心围绕"虫害目标检测怎么做""轻量化到底轻到什么程度""从实验室到棉田还差哪几步"展开。适合正在做农业视觉项目、或者手里有一个边缘部署需求但没想清楚技术路线的同学参考,踩过的坑我会直接标出来。1. 先想清楚一件事:棉田虫害检测和普通目标检测根本不是一回事1.1 虫害场景的“难”和你想得不一样很多人第一次接触这个课题,脑子里想的还是经典目标检测任务:识别图片里有没有猫、有没有车、有没有人。但棉田虫害检测的难点是另一套逻辑。首先是目标尺寸小,早龄期的蚜虫可能只有几个像素到十几个像素,普通检测器对这种小目标天然不友好。其次是密集,叶片背面密密麻麻的虫卵、若虫挤在一起,标注框经常互相重叠甚至一个框里套好几只。第三是遮挡,虫子藏在叶背、蜷在花蕊里,可见特征非常有限。最后是背景干扰,棉田里阳光、泥土、水滴、枯叶、滴灌带这些东西颜色纹理和昆虫高度相似,模型很容易把环境噪声当虫子。还有一个很实际的问题:田间数据本身就不是高质量数据。你可能凌晨背着设备去拍,光线昏暗;中午太阳直射,叶片反光;风一吹叶片晃动,画面模糊。手机拍的、植保无人机拍的、固定摄像头拍的,角度、距离、分辨率完全不一样。这种情况下,如果一个模型在实验室公开数据集上表现很好,到棉田里大概率折戟。所以课题的第一课不是选什么模型,而是理解生产环境对模型提出的真实约束:既要盯得住微小的目标,又要在廉价设备上实时响应,还要能扛住复杂光照和背景变化。这个"既要又要"就决定了后面所有技术决策的方向。1.2 为什么必须做轻量化一开始我也纳闷,既然已有的大模型在通用检测上效果不错,直接用不就行了?后来算了一笔账就老实了。真实田间监测设备是什么水平?市面上常见的边缘计算盒子,CPU算力有限,GPU单元比手机AP略强,内存一般4到8GB,功耗要求往往压在5W到15W。一个ResNet50级别的Backbone配合FPN检测头的模型,参数量动辄几十兆甚至上百兆,浮点运算量上百GFLOPs,在桌面上能跑到30帧,一旦部署到边缘设备,单帧推理立刻变成一两秒甚至更慢。棉田监测不是单张图片处理,而是连续视频流分析,一秒处理一两帧,漏检的风险会大幅上升。更重要的是功耗和成本。农业场景对设备成本非常敏感,一个几万元的推理服务器不可能摆在每块田边,但一个几百元的嵌入式盒子可以。轻量化模型的价值就在这里:更少的参数、更低的浮点运算量、更小的内存占用,换来能够在低功耗设备上连续运行的能力。同时模型小,下载更新快,田间的弱网环境也能顺利升级。我最终把模型大小控制在10MB以内,单帧推理时间控制在毫秒级,在边缘设备上稳定跑20帧以上,同时保持了可用的检测精度。这个"甜点区间"是反复试出来的,后面我会讲具体怎么调。2. 数据才是硬骨头:采集、清洗、标注、增强全是细节2.1 棉田数据采集方案与坑位数据采集是整个项目里最耗时、最容易被低估的一环。我前后分了三个阶段来做:第一阶段是借用植保站的固定摄像头,连续记录不同时段、不同天气、不同光照条件下的视频流;第二阶段是带着手持设备去田里补拍特写,尤其针对低龄若虫、卵块这类小目标;第三阶段是把无人机航拍数据加进来,增加多视角样本。每个阶段都有教训。固定摄像头的分辨率如果低于1080P,想看清蚜虫几乎不可能,所以采集设备必须保证最低清晰度。无人机高度一旦超过3米,地面目标就缩成几个像素,很多样本只能含泪丢弃。手持拍摄看似灵活,但人的影子、设备反光都会引入噪声。我后来定了一条操作约束:所有采集动作都尽量在自然光下完成,不补光、不逆光,镜头与叶面保持45度到90度夹角,避免把阴影当成目标特征。数据清洗也极其重要。田间数据里经常出现空帧、剧烈运动模糊、叶片完全遮挡这类"废图"。如果不过滤,模型会花大量容量去拟合噪声。我当时的做法是先用一个简单的清晰度指标批量筛选,把这些废图直接剔除;然后再人工快速浏览一遍剩余图片,把带严重偏色和反光的也去掉。清洗完的数据集干净不少,模型收敛速度明显变快。2.2 标注规范与增强策略要匹配检测目标标注工具我用的开源标注平台CVAT,支持多人协作,也方便导出COCO格式和YOLO格式。关于标注,我踩过最大一个坑是"标得太实"。有经验的人都知道,目标检测框需要留一点点边缘,不能贴得太紧,也不能包太多背景。棉田虫害经常是密集分布,如果框太贴合,框与框之间大量重叠,后处理里NMS会误杀很多正确检测;如果框太松,背景噪声又会混进特征学习。我最后统一了一套规则:框边距目标轮廓约2到3像素,重叠面积过大时允许微调。数据增强方面,我尝试的顺序值得参考。先上通用几何增强:旋转、平移、缩放、翻转。这里注意,棉田场景里90度旋转可能让图像语义发生变化,所以旋转范围我锁在正负15度。接下来是颜色扰动:亮度、对比度、饱和度、色调随机变化,模仿不同天气光照。然后是大杀器Mosaic增强。四张图拼接成一张,让模型看到更多尺度变化,对小目标检测特别有用。最后是专门针对密集小目标的Copy-Paste增强:从一张图里把虫子的区域裁出来,随机粘贴到另一张图上。这个操作直接把小目标样本密度拉上来,效果立竿见影。还有一个容易被忽略的操作:加入负样本。我放了一批完全没有虫子的棉叶图像进训练集,让模型学会"这里没有东西,不要输出框"。加上负样本之后,误报率下降非常明显。注意:数据增强不是越多越好。增强太猛,具体表现为训练损失死活不降,验证集效果反而差。要盯着验证集的mAP做决策,而不是凭感觉堆增强策略。3. 模型选型与轻量化改造:精度、速度、体积的三角博弈3.1 主流轻量模型横向对比我先后测试了好几类轻量模型,简单做个对比供参考。模型参数量计算量端侧实测FPS原始mAP备注YOLOv5s7.2M16.5G28中综合平衡,易训练YOLOv5n4.3M7.2G38中偏低体积小,速度极快YOLOX-Nano2.3M5.0G40中偏低无锚框结构,部署时略麻烦MobileNetV3-SSD5.6M8.6G22低小目标表现一般EfficientDet-Lite04.3M2.5G25低计算量最低,但精度天花板低这里面的数字是我的实测值,原论文里的mAP通常是在COCO这种数据集上的结果,直接硬搬到棉田数据上没有任何意义。我自己的结论是:YOLOv5s作为基线最合适。它训练稳定、资料多、部署工具链成熟,YOLOv5n更小但精度下降明显,MobileNetSSD的速度和精度在密集小目标场景下都不占优,EfficientDet-Lite系列计算量虽低但精度上限实在太紧。3.2 轻量化改进:从替换Backbone到注意力模块的克制使用选定YOLOv5s之后,我做了三处轻量化改造。第一处是替换Backbone。我试验过把主干换成MobileNetV3和ShuffleNetV2。MobileNetV3在公开图像上分类精度很不错,但测下来在密集小目标场景下并没有展现出优势,特征提取对小目标的响应偏弱。ShuffleNetV2倒是让整体计算量降低了不少,但代价是精度掉得有点多。权衡下来,我保留原版的CSPDarknet结构,但把通道数和深度都做了缩减,把最重的几个卷积模块换成深度可分离卷积。这一通操作下来,计算量砍了差不多三分之一,精度损失控制在可接受范围内。第二处是引入轻量注意力模块。我试过SE模块和ECA模块。ECA效果好一点,因为它避免了全连接降维带来的信息损失,只通过一维卷积做局部跨通道交互,计算开销几乎可以忽略。我把它插在Backbone后面两个Stage以及Neck部分,确实能看到mAP小幅回升。这里必须强调一个经验:注意力模块不是哪里都插,插多了会直接拖慢推理速度,而且收益会递减。我最后全模型只插了5个ECA模块,多一点都不要。第三处是Neck结构微调。针对小目标,我增加了一个浅层特征图输出,也就是在原本的P3、P4、P5之外,再把P2层引入检测头。P2层分辨率更高,能保留更多空间细节,小目标的检测召回率因此提升。代价是计算量稍有增长,但轻量化省下的预算足够覆盖这一点,整体依然在可接受范围内。整套方案跑下来,最终模型参数量控制在7MB左右,单帧推理在边缘设备上从最初的1.2秒缩短到45毫秒,mAP比原始YOLOv5s只低了不到两个点。这个结果让我比较满意,也是后面所有部署工作的基础。4. 训练实现全流程:参数细节与调优心得4.1 环境、数据划分与训练配置训练环境就是常规的深度学习环境,PyTorch框架,GPU用了一台中端训练卡,CUDA环境版本和PyTorch版本对齐。数据集按照8:1:1划分成训练集、验证集、测试集。划分的时候有个细节:同一个摄像头连续时间段拍出来的图片高度相似,如果随机划分,验证集和训练集容易混入内容相近的样本,导致mAP虚高。我按"来源批次"分组划分,也就是同一批采集的图片要么全进训练集,要么全进验证集,这样评估结果才可信。训练配置方面,我直接给出一组经过实测的参考参数:参数取值输入分辨率640x640Batch Size32初始学习率0.01优化器SGD + Momentum 0.937训练轮次100Warmup5轮Weight Decay0.0005EMA开启,衰减系数0.999这组参数是常规配置,效果稳定。如果显存紧张,Batch Size可以降一半,也可以同时启用梯度累积,保证等效Batch Size不变。学习率通常也要相应调低,从0.01降到0.005,否则前期loss容易震荡。4.2 损失函数、学习率策略与小目标专项处理损失函数方面,常规YOLOv5使用CIoU损失,我在小目标检测上做了微调。CIoU对微小目标的位置偏差非常敏感,几个像素的偏移就会导致损失剧烈波动。我改用Alpha-IoU,它的非单调聚焦机制能够增强对高IoU样本的权重,小目标回归更稳。实测在棉田数据集上,Alpha-IoU让小目标的召回率明显改善,代价是收敛速度略慢,需要配合稍长的训练轮次。学习率策略我推荐使用余弦退火。前期用5个轮次的Warmup让训练稳定起步,之后学习率按余弦曲线衰减到接近0。相比固定步长下降,余弦退火在训练末端能更细腻地收敛到局部最优点,最后的mAP一般会高出一点几个点。还有一个被我验证过多次的"笨办法":多尺度训练。我在训练中每隔一个Batch就从640、672、704、736这几个分辨率里随机挑一个作为输入尺寸。这个策略让模型对目标尺寸变化更鲁棒。代价是训练时间会增加约20%,但换来的是在田里面对不同高度摄像头时表现稳定,这笔投入很值。EMA也要开。简单说,EMA就是对模型参数做滑动平均,相当于在训练过程中累积出一个更平滑的模型。开启EMA之后,验证集精度通常能提升0.5到1个点,而且几乎不增加训练成本。动手训练之前,这几项最好一次性在配置里打开,别等训练到一半再回头补救。5. 部署落地:从PyTorch模型到田间边缘设备的最后一公里5.1 模型转换、量化与精度损失控制训练完的PyTorch模型不可能直接扔到边缘设备上跑。标准流程是先导出ONNX中间格式,再做设备端的推理引擎转换。ONNX导出这块经常出问题的一个点是动态尺寸。为了让模型灵活应对不同输入尺寸,有些同学会把动态轴全部放开,结果转换后的模型在设备上推理时出现不规则卡顿甚至内存越界。我的做法是固定输入尺寸为640x640,把动态轴全部关闭。虽然灵活性牺牲了,但稳定性和执行效率是最重要的。接下来是模型量化。边缘设备通常支持FP16和INT8推理。FP16最简单,转换后精度损失几乎可以忽略,体积减半。INT8则需要准备校准数据集,我用的是验证集里采样的500张图片,在转换工具里跑完校准后,模型大小从7MB压缩到2.8MB,单帧推理时间进一步缩短。INT8带来的精度损失主要集中在小目标上,实测mAP掉约1.5到2个点,在可接受范围。提示:如果目标场景里小目标占比很高,不建议直接上INT8。可以先跑FP16版本,把精度和速度基线都测出来,再评估有没有必要进一步量化。分阶段做,排查问题时思路会清晰很多。5.2 实测定点与现场性能数据我把编译好的模型部署到了一个边缘计算盒子上,用USB摄像头接入视频流,计算输出检测结果。现场实测环境是棉田边缘的固定支架,摄像头距地面约1.5米,斜向下45度拍摄,视野里同时包含叶片、地面和滴灌带,背景复杂度比较高。性能数据给大家参考:FP16模型单帧推理耗时48毫秒,加上前后处理大约55毫秒,换算下来大概18帧每秒;INT8模型单帧推理耗时32毫秒,加前后处理约38毫秒,能跑到26帧每秒。这个帧率对于虫害监测完全够用——虫子的移动速度不快,连续视频流里每秒十几帧足以捕捉大多数情况。如果还想进一步提升帧率,可以在接入端设置抽帧策略,比如每两帧处理一次,再配合输入缩放,速度还能再翻一倍。现场还发现一个问题:棉田里气温高,边缘盒子如果被太阳直射,表面温度能到60度以上,推理速度会明显下降,严重时直接死机。后来我加了一个简易遮阳罩并调整了支架角度,温度控制在45度以内,设备才稳定。这种细节,实验室环境里根本不会暴露。6. 常见问题与排查方法实录6.1 小目标漏检严重怎么调漏检永远是虫害检测的头号痛点。如果是密集的小目标类型,排查顺序建议是:先看数据层面,检查训练集里小目标的标注框数量是否充足。如果小目标占比过低,优先做Copy-Paste增强,把小目标样本数量补上来。再看模型层面,确认有没有针对小目标增加高分辨率特征层。最后看推理层面,把输入分辨率从640提高到768或832,小目标在更高分辨率下像素更多,检测难度会明显降低。用这招,很多情况下漏水率能降一半。6.2 训练Loss不降或震荡Loss不降最常见的原因是学习率设置过高或过低。可以打印出前10个Batch的Loss变化曲线看一眼,如果刚开始就暴涨,多半是学习率太高;如果纹丝不动,可能是学习率太小或者模型完全没有收敛。还有一个隐蔽原因是数据增强过猛,特别是Mosaic加Copy-Paste同时拉满,样本分布过于随机,模型反而学不到稳定特征。我遇到过一次loss震荡一整轮的情况,最后就是降低增强强度并尝试增大Batch Size解决的。6.3 模型过拟合采集数据有限时基本躲不过过拟合。典型表现是训练loss一直降、验证mAP却不再上升甚至下降。我的处理办法按优先级排序:优先给数据增强"加码",这是低成本且收益高的;其次是使用更大的Weight Decay;再次是引入随机失活。如果这些都试过还是过拟合,那就老老实实回田里补拍数据,尤其是不同天气条件下的样本。6.4 部署后推理速度不达标模型在本地FPS爆表,部署到边缘设备却卡成PPT,通常问题出在前处理和输入输出部分。比如OpenCV读取视频流的方式、缩放算法的选择、NMS的后处理实现,都会吃掉大量时间。我最后把NMS部分替换成快速实现,并把图像缩放从双线性插值换成了更高效的插值方式,单帧总耗时立刻降低了15毫秒。另外,确认推理引擎是否真正启用了硬件加速也很关键,排除下来,有时候单纯是工程实现没写对。我个人在反复打磨这套系统的过程中最大的体会是:农业AI项目拼的根本不只是模型结构多花哨,而是整个数据-模型-部署闭环里能不能把每个环节的不确定性都压下去。模型轻量化只是其中一块拼图,前期的数据规范和后期的现场处置同样决定项目成败。如果你正准备做类似的轻量化检测课题,建议把采集和标注的时间预留充足,那部分花的时间,最终都会在训练和部署阶段加倍还回来。