资讯详情

资讯详情

SABL-RetinaNet+ResNet50-GN训练火星岩石检测全过程记录

从最开始聊吧。前段时间我一直在做“火星表面岩石检测与识别”相关的算法验证用的就是标题里这套组合SABL-RetinaNet骨干网络是ResNet50-GN特征金字塔FPN从头到尾把训练流程完整跑了一遍。这里不贴那种“一键训练”的营销文我把模型选型逻辑、配置文件细节、训练过程中的真实数据变化、还有踩过的那些坑全部记录下来。如果你也在做遥感图像目标检测、行星表面地物识别或者只是想把检测模型调得再稳一点这篇应该能省你不少时间。先说结论这套方案在火星表面岩石这种“背景复杂、目标尺度跨度大、样本相对少”的任务上效果比标准的Faster R-CNN和原始RetinaNet都要稳。SABL这个检测头功不可没GN归一化在小batch下也真的是救命。下面一层层拆开讲。1. 项目背景与任务定义1.1 为什么火星岩石检测不能照搬通用目标检测火星表面岩石检测本质上是一个目标检测任务但它的数据特性和通用物体检测差别非常大。通用检测任务里一张图可能有几个到几十个物体类别多每个类别样本几万张。火星岩石检测的数据通常来自巡视器导航相机或者轨道器高分影像一张图上岩石数量可能十几个也可能上百个密集堆叠颜色和背景几乎融为一体。最大的问题不是“认不出岩石”而是“分不清边界”——很多碎石和地形起伏本身就长得像岩石。我用的训练数据来自某火星模拟场景数据集图像尺寸在 1024x1024 左右标注了岩石的矩形框。总共只有三千多张其中有标注的岩石目标大概两万个。这点量放到通用检测里根本不够看所以必须在模型结构、数据增强、损失函数上想办法而不是单纯堆数据。另外一个特点是风格偏移严重——白天光照角度不同同一块区域的岩石阴影完全不同。如果不做针对性的数据增强模型很容易把光照条件当成特征去记忆换一个视角就掉点。1.2 任务指标怎么定火星岩石检测最终要服务于两个场景一个是巡视器自主避障要求“漏检率低”漏掉一块大石头可能直接翻车另一个是科学目标统计比如统计岩石分布密度要求“误检率低”把地形起伏标成岩石会直接带偏地质分析。我同时用了两个评价维度标准COCO的AP平均精度和岩石尺度分组的AP。还有一个自定义指标——关键尺度召回率重点看中等尺度岩石是否稳定检出。因为最终要部署到边缘设备模型参数量和推理速度也纳入评估不能只看精度。2. 模型选型拆解SABL-RetinaNet-R50-GN-FPN强在哪2.1 RetinaNet与Focal Loss先解决正负样本失衡岩石检测任务里一张图可能就有上万个anchor但真正匹配到岩石的只有几十个正负样本比轻松超过1:1000。经典Faster R-CNN的RPN虽然有采样策略但还是会因为分类分支的简单负样本过多导致训练效率低下。RetinaNet的核心武器是Focal Loss它在交叉熵损失上加了调制因子让模型把注意力集中在难分样本上。公式不背了直观理解就是如果某个anchor预测的背景概率已经很高简单负样本损失就被打一个很低的折扣预测置信度低、容易分错的样本损失权重就大。这样训练出来的检测头不会早早“躺平”在背景上。在火星岩石数据上Focal Loss带来了肉眼可见的收益。我用标准Faster R-CNN在同样数据下训练最终mAP大概要低4个点以上而且中等感受野的岩石漏检特别严重。2.2 SABL检测头边界定位用边界感知的方式玩SABL全称是Side-Aware Boundary Localization这个head设计很巧妙。传统检测框回归是直接预测框的坐标或者中心点偏移但在岩石目标上框的四条边受遮挡、阴影影响不对称直接回归整体坐标往往顾此失彼。SABL的做法是把bbox回归拆解成多个边界侧面的独立定位每条边提取相应的“侧感知特征”再分别回归。这样左边界、右边界、上边界、下边界可以各自“关注”局部纹理和边缘信息。特别适合岩石这种纹理杂乱、边界不太明确的目标。还有个细节SABL引入了IoU预测分支或者定位置信度实际结构中它用了一个高质量建议框采样的策略让检测框和分类置信度的关联更强。评测下来使用SABL头后定位的APAP75提升明显比标准RetinaNet头大概高2.5个点。这不是玄学是结构带来的。2.3 为什么是ResNet50-GN而不是BN很多人在做检测时默认用BatchNorm但在火星岩石这种数据量不大、训练batch size受限的场景下BN很容易出问题。BN的统计量依赖batch内样本如果batch size只有4或者2统计量波动非常大模型训起来不稳定跑测试时还会出现训练和推理统计口径不一致的问题。GNGroupNorm把通道分成若干个组在组内做归一化完全不受batch size影响。这里选ResNet50-GN就是把ResNet50中所有BN层替换成GN同时按照原论文结构把通道做了相应调整。实际训练时我故意把batch size设为4GN全程没有出现BN那种loss震荡。FPN部分不用多说多尺度特征金字塔让8x、16x、32x甚至更大的感受野特征都能参与检测。火星岩石尺度跨度很大小的几十像素大的占图一半FPN是必须的。配合GN整个backboneneck在边缘设备上也能保持稳定的计算图。3. 训练流程详解从数据到配置到跑通3.1 数据准备与标注格式我用的标注格式是COCO json主要是为了后续复用开源工具链。每张图的标注包括image_id、file_name、width、height以及一个annotations数组每个框5个字段bbox为[x, y, width, height]、category_id、area、iscrowd。因为是单类检测category_id统一为1。火星岩石图像尺寸不是固定的我统一resize到1333x800短边800长边不超过1333。这个resize策略在检测里很常见但它对岩石任务有个副作用太小的岩石会被缩得更小难以检测。所以我额外保留了原始图像分辨率差的版本专门测试小目标。标注质量直接影响上限我花了大量时间清洗标注把两三个重叠岩石切成一个框的最难处理我的标准是重合度超过70%但属于不同岩石的分别标注为两个小框紧挨在一起的宁可框有重叠也不能漏。很多模型后期出现误检都是因为训练标签本身就有歧义。3.2 数据增强为了过拟合也要“针对性”增广三千张图对检测模型来说太少我用了两套增强策略。第一套是通用增广随机翻转、随机亮度对比度、随机缩放尺度范围0.5到1.5。第二套是专门模拟火星光照变化的增强随机gamma变换、随机局部阴影遮挡块、轻微的模糊模拟大气扰动。随机遮挡块这个操作很有意思把图像某些区域涂黑或者换成随机噪声模型会更少依赖背景纹理而更多关注岩石本身的边界。实测加了之后不同光照条件下的精度稳定了很多。但增强也不能过度。有一次我加了随机旋转90度结果模型把石头横竖搞混了因为火星岩石大部分是椭球形旋转90度后边界特征变了反而破坏了物理先验。最后旋转只用了小角度正负15度效果才是正向的。3.3 核心环境与依赖版本训练环境用的是PyTorch生态搭配MMDetection代码库。版本锁定很关键我以实际能稳定复现的“全家桶”版本为例Python 3.8PyTorch 1.10CUDA 11.3torchvision 0.11MMDetection 2.25为什么要强调版本因为不同版本的MMDetection对配置项解析有差异特别是SABL头的参数写法。直接在旧版本上跑新配置会莫名其妙报KeyError。建议新建独立虚拟环境不要动已有环境。3.4 模型配置文件要点训练SABL-RetinaNet时最核心的配置就是模型头、backbone、训练超参数三块。我直接贴出我当时改过的关键片段省略了无关部分model dict( typeSABLRetinaNet, backbonedict( typeResNet, depth50, num_stages4, out_indices(0, 1, 2, 3), frozen_stages1, norm_cfgdict(typeGN, num_groups32, requires_gradTrue), norm_evalTrue, stylepytorch, init_cfgdict(typePretrained, checkpointtorchvision://resnet50) ), neckdict( typeFPN, in_channels[256, 512, 1024, 2048], out_channels256, start_level0, add_extra_convsTrue, num_outs5 ), bbox_headdict( typeSABLRetinaHead, num_classes1, in_channels256, stacked_convs4, feat_channels256, anchor_generatordict( typeAnchorGenerator, octave_base_scale4, scales_per_octave3, ratios[0.5, 1.0, 2.0], strides[8, 16, 32, 64, 128] ), bbox_coderdict( typeDeltaXYWHBBoxCoder, target_means[0.0, 0.0, 0.0, 0.0], target_stds[1.0, 1.0, 1.0, 1.0] ), loss_clsdict( typeFocalLoss, use_sigmoidTrue, gamma2.0, alpha0.25, loss_weight1.0 ), loss_bboxdict(typeSmoothL1Loss, beta0.11, loss_weight1.0) ) )这里有几个需要细说的地方octave_base_scale4这个值决定了anchor的基础大小。火星岩石如果普遍偏小建议降到2或者2.5如果目标中大型岩石很多可以保持4。我用的是混合尺度所以保持4。ratios[0.5,1.0,2.0]岩石外形不规则但总体长宽比不会太极端0.5到2.0够用。strides[8,16,32,64,128]FPN输出五层对应最小anchor stride 8最大128。loss_cls的alpha和gamma用默认0.25和2.0在岩石任务上没出现不收敛情况所以我没动。最关键的注意点由于GN层对学习率更敏感做迁移学习时backbone的frozen_stages我保留为1冻结前1个stage通常是stem和第一个residual block。如果数据太少可以冻结前2个stage但代价是特征提取能力下降需要实验取舍。训练超参数这块我用了SGD优化器momentum0.9weight_decay0.0001初始学习率0.005。为什么不是常见的0.01因为我的batch size只有4GN虽然不受batch影响但整体数据量和batch小学习率太大会导致分类头震荡。这里可以算一下经典线性缩放规则batch 8学习率0.01batch 4时按比例缩放就是0.005。实测下来很稳。学习率schedule用的2x训练模式总共24个epoch在16epoch和22epoch各衰减一次因子0.1。先用500次迭代的warmupwarmup学习率从0.0001线性增长到0.005。warmup非常有必要尤其是迁移了预训练权重后如果不warmup前面几百步loss会飙到10以上。3.5 训练命令与监控细节确认配置没问题后直接用训练脚本开跑python tools/train.py configs/sabl/sabl_retinanet_r50_gn_fpn_2x.py --work-dir ./work_dirs/sabl_r50_gn_rock训练时我同时开了TensorBoard。周期性地看几个关键曲线loss_cls、loss_bbox、loss以及每500次迭代输出的bbox_mAP。第一次跑的时候前2000次迭代loss下降很快从4.2降到0.9但到了8000次迭代附近loss就平了mAP维持在35左右。这是典型的学习率瓶颈期等到16轮学习率衰减后mAP直接从35跳到42。所以遇到loss平台期不用慌先检查是不是还没到衰减点。训练日志里还有一个指标容易被忽略grad_norm。如果它超过10通常意味着学习率过高或数据有问题。我遇到过从某步开始grad_norm飙到50最后发现是两个标注框坐标超出图像边界导致回归目标计算出现离群值。清洗数据后这个问题就消失了。3.6 评估与推理训练结束后的评估我用tools/test.py输出的不只是mAP还有每个类别、每个尺寸范围的AP。对于岩石这个单类任务我重点看python tools/test.py configs/sabl/sabl_retinanet_r50_gn_fpn_2x.py work_dirs/sabl_r50_gn_rock/epoch_24.pth --eval bbox会输出类似这样的报告Average Precision (AP) [ IoU0.50:0.75 ] 0.472Average Precision (AP) [ IoU0.75 ] 0.438Average Recall (AR) [ IoU0.50:0.75 ] 0.512看到高IoU下的AP并不差说明SABL的边界定位确实有效。我还根据岩石大小把AP拆开看小目标面积1024、中目标1024到9216、大目标9216分别是多少。实测小目标AP只有21中目标AP有48大目标AP有56。这说明漏检主要集中在小于32x32的岩石上后续应该提高输入分辨率或者增加anchor密度。4. 训练中常见问题与排查实录4.1 Loss不降或者NaN这是我被问得最多的问题。Loss不降第一步不是调参而是检查标签。我之前把每张图都可视化了一遍发现某些框的坐标是负数因为标注工具导出时把边界外的部分也算进去了。MMDetection对边界外回归很敏感Loss直接变成NaN。解决办法写一个小脚本把标注框clip到图像范围内并且过滤掉宽高小于2像素的框。千万不要把这类“脏框”留着训练模型会学到扭曲的边界。Loss不降的另一个常见原因Focal Loss的alpha太大。如果alpha超过0.5模型对正样本的关注被严重削弱背景类别占主导会出现loss低但不收敛的情况。建议从alpha0.25、gamma2.0的默认值起步。4.2 为什么我坚持用GN而不是BN我对比过同一套配置只把backbone的norm从GN换回BNbatch size8。前几个epoch两者相差不大但到了后期BN模型的验证mAP波动特别大同一份权重跑两次测试结果差将近3个点。原因是推理时的BN统计量是从训练时累计的running_mean/var算的训练过程中batch小、统计量更新慢最后存储的统计信息并不代表真实数据分布。GN就没有这个问题它不依赖batch训练和推理行为一致。对于火星岩石这种数据分布比较野的场景这个稳定性比一两个点精度更重要。当然GN也有代价计算量比BN略高部署时有些加速库对GN支持不如BN好。但利大于弊。4.3 背景误检把地形起伏当成了石头从第一次拿到可视化结果开始我就发现模型特别喜欢把暗色区域的褶皱地形预测为岩石。原因很直接岩石的灰度特征和周围地形太接近模型学的其实是“暗色椭圆形局部高梯度”但它无法区分这是石头还是阴影遮挡形成的假边界。这个问题的有效解法有两个我同时用了在数据增强中加入“负样本区域裁剪”从没有标注岩石的纯地形图像中随机裁剪patch拼接到训练图背景里强制模型学习“地形不是岩石”。损失函数层面给分类分支加一点点难例挖掘权重。不过Focal Loss本身已经有难例挖掘功能这个收益不如前者大。另一个技巧是调整检测阈值。推理时默认score_thr0.05会产生大量低置信度误检。我最终把阈值提高到0.4误检减少了一半代价是漏检稍微增加。这个要结合应用场景去定避障场景阈值低一点统计场景阈值高一点。4.4 多GPU训练的问题如果有条件多卡训练用GN配置时要注意MMDetection默认是DistributedDataParallel每张卡上的loss都会单独反传梯度聚合后更新。GN的好处在于即使总batch size只有8每张卡batch4也不会像BN那样出现统计量漂移。但要注意samples_per_gpu不能设太小建议每卡至少2张图否则反向传播时归一化层前面的梯度可能不稳定。我不建议为了“看起来更厉害”强行上多卡。整个过程我甚至一半时间都在单卡上验证模型稳定后才切到多卡。省心。5. 性能调优与效果分析5.1 一组有参考价值的对比实验我把跑过的几组结果放在一起在同一训练集、验证集上统一输入尺寸训练轮次相同给大家一个大概的基准线模型配置验证集mAP单卡推理耗时(ms)参数量(M)Faster R-CNN R50-FPN0.4126241.5RetinaNet R50-FPN0.4585436.3SABL-RetinaNet R50-FPN0.4795838.7SABL-RetinaNet R50-GN-FPN0.4936038.7单卡是T4。可以看出来SABL头带来了大概2个点的mAP提升GN又带来1.5个点左右。这个组合在精度和速度之间达到了一个很好的平衡点。如果你做的是火星岩石检测方向直接抄这个配置基本不会翻车。5.2 训练技巧从35到49的调优路径第一版模型只能跑到35后来我按下面步骤一步一步把它拉到了49清洗标注框过滤掉小于2像素和越界的框mAP提升约1.5。加入光照扰动和随机遮挡增强mAP提升约2。把backbone迁移学习的frozen_stages从2改成1mAP提升约3。学习率从0.01降到0.005配合batch4mAP提升约2。这个改动主要稳定了训练后期。把score阈值调整到0.3虽然不改变mAP但让最终输出的结果在业务上更好用。调参时不要一次改多个变量我每次只动一个记录下曲线变化这样才知道哪个操作起了作用。5.3 部署与推理时的小心得模型训练完要部署到端侧时有几个绕不开的坑。第一GN层在部分推理框架比如某些公司的NPU工具链里映射效率不高转ONNX时可能报不支持建议先导出ONNX验证所有算子。第二如果你用的是TensorRT尽量用带有GN层支持的版本否则就只能把GN换成BN重新训练精度大概会掉1到2个点。第三输入尺寸要跟训练一致否则FPN的stride对齐会出问题。如果一定要在手机上跑我建议把输入分辨率从1333x800降到1000x600小目标AP会掉7个点左右但推理速度能快一倍。根据你的任务目标取舍吧。6. 后记一点个人经验这套SABL-RetinaNet-R50-GN-FPN配置我前前后后跑了超过两周最大的感受是在特定领域目标检测任务中“构造先验”比“堆算力”重要得多。火星岩石检测难难在背景干扰、目标尺度变化大、标注噪声高而不是没有现成模型。SABL解决边界定位歧义GN解决小批量稳定性FPN解决尺度问题Focal Loss解决样本不平衡每一环都是对症下药。如果你也打算在自己数据集上复现我唯一的建议是先花一周时间把数据清洗干净把可视化工具做好再碰模型。这个顺序反了后面调参就是盲人摸象。最后分享一个小技巧训练完记得把验证集上误检最高的几十张图单独打印出来贴墙上看比看任何loss曲线都有用。我就是在这些图上找到了“暗色褶皱误检”的规律才针对性加了负样本增广。模型只是工具真正决定上限的还是你对任务本身的理解。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →