资讯动态

在mmdet3d下复现BEVFusion:从环境配置到训练评估的完整实战

发布时间:2026/10/22 4:13:10 来源:尧图企业网站定制
很多做三维目标检测的朋友应该都有过这种体验论文里BEVFusion的效果图看着很惊艳一到自己手上复现就各种卡壳。环境装不上、数据格式对不上、显存爆掉、训练几轮loss死活不下来……我去年花了两周时间断断续续把这个模型在mmdet3d框架下完整跑通了训练、评估和可视化。整个过程踩坑不少但捋清楚之后其实思路很清晰。这篇文章就把我的复现路径完整写出来包括版本选型、数据准备、原理梳理、配置修改和实际训练时遇到的坑给后面想动手的朋友省点时间。如果你正准备在mmdet3d下复现BEVFusion或者只是想弄明白它到底怎么把激光雷达和相机特征融合到一起这篇文章应该能帮你少走很多弯路。内容偏实操我会尽量按“我先做了什么、为什么这么做、出了什么问题、怎么解决的”这个顺序讲。1. 选型前的关键判断为什么用mmdet3d复现BEVFusion先说结论mmdet3d不是复现BEVFusion唯一的选择但对绝大多数人来说它是最省力的平台。BEVFusion这个模型的核心思想不算复杂——把多模态特征统一到鸟瞰视角BEV下做融合。但它的原始开源实现是基于特定版本的老框架写的直接拉下来跑经常遇到依赖冲突。而mmdet3d把很多三维检测的通用组件都封装好了从数据加载、数据增强到模型构建、训练评估链路很完整我们只需要把BEVFusion特有的模块用mmdet3d的接口方式重写或移植进去就好。我在选型时有这么几个考量点也分享给你参考版本生态成熟度mmdet3d对nuScenes数据集的支持比较完善像NuScenesDataset、NuScenesSegDataset这些类都是现成的省掉自己写数据解析的大量工作。自定义模型友好mmdet3d的注册机制DETECTORS、BACKBONES、FUSION_LAYERS等允许我们比较方便地插入自定义模块BEVFusion的融合模块就是这样加进去的。社区案例多如果你在复现过程中遇到问题不管是官方issue还是各种博客围绕mmdet3d的讨论覆盖率都远高于其他框架。当然mmdet3d也有它的脾气。最大的问题是版本兼容性非常敏感。PyTorch版本、mmcv版本、mmdet版本、mmdet3d版本、CUDA版本、GPU驱动版本任何一个不匹配都可能导致编译失败或者运行时报错。我在最开始就是在这里浪费了大量时间。我的建议很明确不要追新。选择一个经过验证的版本组合装好之后不要随便升级。下面是我稳定跑通的组合组件版本操作系统Ubuntu 18.04 / 20.04CUDA11.3PyTorch1.10.1mmcv-full1.5.0mmdet2.25.0mmdet3d1.0.0rc6spconv2.1.21自己编译安装这个组合是我反复尝试后确认相对稳定的方案实测多机多卡训练、验证、可视化都能正常跑。如果你用的不是这个组合请务必仔细阅读官方文档中对应的版本兼容表不要盲目混搭。版本选型还有一个小技巧装完mmdet3d之后第一件事不是跑训练而是跑一遍官方自带的demo和单卡快速训练确认整个链路是通的。我见过很多人装完环境就直接跑大模型结果最后发现是环境问题导致训练几个小时白费这个顺序问题很致命。2. BEVFusion的核心逻辑拆解先搞懂原理再动手很多人一上来就急着急模型、改配置但我觉得在动手指之前一定要把BEVFusion的核心逻辑理清楚。不然训练完你都说不清模型哪里在干什么后面想调优更是无从下手。BEVFusion这个名字里的“BEV”已经点出了核心把不同模态的特征都投射到鸟瞰视角这个统一空间里再做融合。这和早期一些方法在2D图像层面做融合或者只在3D框输出层面做融合的思路都不一样。2.1 两条特征提取支路一条支路是激光雷达支路另一条是图像支路。激光雷达支路通常使用稀疏卷积网络比如SECOND或VoxelNet结构把点云体素化之后用3D稀疏卷积提取特征最后得到一个BEV空间的特征图。这条支路的优点是几何信息准确距离精度高但缺点是点云稀疏、语义信息有限。图像支路使用传统的2D卷积网络比如ResNet系列提取多视角图像特征然后通过一个视角变换View Transformation模块把每个视角的2D特征“抬升”到3D空间再投影到BEV平面。这条支路的优点是语义信息丰富能看到颜色、纹理、路牌、车道线之类的细节缺点是深度估计不准、几何位置有偏差。BEVFusion的关键正是在这个“融合”上。早期的融合方法大多只是简单concat或者加权求和BEVFusion在这一点上做了更精细的设计在处理两类特征的置信度差异时做了类似于注意力机制的加权融合网络可以自己学会在哪个区域更信任哪种模态。2.2 为什么要把特征统一到BEV空间这个问题我一开始也困惑过图片有自己的视角点云有自己的坐标系为什么非要统一到BEV一个很朴素的原因下游任务需要。三维目标检测的输出是在俯视图上的3D框如果你不先把特征统一到一个空间后面的检测头就没法做。另外BEV空间是鸟瞰视角物体的尺寸、朝向、相对位置关系都一目了然对检测头的设计非常友好。还有一个现实原因多模态对齐更简单。图像和激光雷达本来就是两个不同坐标系下的信号硬要在像素级别对齐几乎不可能。但如果在BEV空间里每个位置都对应真实世界的一个坐标点比如图片上一个像素可能对应不了真实世界但BEV上的一个栅格一定能对应真实世界的某个区域不同模态之间就有了统一的“地址”对齐和融合就顺理成章了。2.3 mmdet3d里复现BEVFusion的基本框图用mmdet3d的配置思想来理解BEVFusion的模型结构大概可以拆成这么几块backbone图像用ResNet点云用VoxelNet的backbone部分。neck图像分支做FPN多尺度特征点云分支做SECOND的neck结构。fusion layer这是BEVFusion的核心负责把图像BEV特征和点云BEV特征做融合。bbox_head在融合后的BEV特征上做检测头的预测输出目标的类别、尺寸、朝向等。在mmdet3d里这几个部分都是可替换的模块我们可以通过修改配置文件自由组合。这也是我推荐用mmdet3d的另一个原因——它帮我们把这个结构整理得很清楚每一块都是一个独立的组件调参和debug都比较方便。下面我用一个简化版的注册关系来展示模型配置的结构逻辑方便你在配置文件中对照model dict( typeBEVFusion, img_backbonedict(...), # 2D图像backbone img_neckdict(...), # 2D特征多尺度融合 pts_voxel_layerdict(...), # 点云体素化 pts_voxel_encoderdict(...), # 体素特征编码 pts_backbonedict(...), # 3D稀疏卷积backbone pts_neckdict(...), # 点云neck fusion_layerdict(...), # BEV融合核心 bbox_headdict(...) # 3D检测头 )这个配置文件往深了说其实就是帮你把训练逻辑、前向过程的每一步都拆成了模块。理解了这个结构之后后面的所有操作——改数据路径、调参、加模块——都会变得顺理成章。3. 环境安装与数据准备最劝退的环节认认真真装一遍说实话不少人在第一步环境安装就放弃了。mmdet3d的编译安装确实比普通Python包要繁琐但只要我们按步骤来心态放稳其实是可以一次装好的。3.1 从零开始安装mmdet3d的完整流程我的建议是用conda创建独立环境所有依赖都装在这个环境里不要跟系统Python混在一起不然出问题很难回溯。下面是完整的命令流程我加了注释便于理解每个步骤是在干什么# 1. 创建并激活虚拟环境 conda create -n bevfusion python3.8 -y conda activate bevfusion # 2. 安装对应版本的PyTorch pip install torch1.10.1cu113 torchvision0.11.2cu113 -f https://download.pytorch.org/whl/torch_stable.html # 3. 安装mmcv-full注意要用源码编译方式保证版本完全匹配 git clone https://github.com/open-mmlab/mmcv.git -b v1.5.0 cd mmcv MMCV_WITH_OPS1 pip install -e . -v cd .. # 4. 安装mmdet pip install mmdet2.25.0 # 5. 安装mmdet3d git clone https://github.com/open-mmlab/mmdetection3d.git -b v1.0.0rc6 cd mmdetection3d pip install -e . -v cd .. # 6. 编译安装spconv用于稀疏卷积 git clone https://github.com/traveller59/spconv.git --recursive cd spconv python setup.py bdist_wheel pip install dist/*.whl cd ..这里特别要提一下spconv的编译。很多人在这一步卡住因为spconv和CUDA版本、PyTorch版本的对应关系非常严格。我建议先安装好PyTorch和mmcv之后再编译spconv确保它用的是当前环境里的CUDA版本。编译过程可能会持续十几分钟等待的时候耐心点不用频繁去看日志。3.2 最容易踩的坑版本兼容性我环境安装阶段遇到的最坑的一件事是mmcv-full编译时用的PyTorch版本和运行时用的不一致导致后面一跑训练就报错而且报错信息很抽象。查来查去才发现是编译环境变量里的CUDA路径指向了系统CUDA而不是conda环境里的CUDA。解决办法比较直接在编译前显式指定CUDA路径。export CUDA_HOME/usr/local/cuda-11.3还有一个坑是关于GCC版本的。过新的GCC在编译某些老版本mmcv的C扩展时会报错适当降低GCC版本或者使用更稳定的编译参数能避免很多麻烦。我用的GCC版本是7.5整个过程比较平稳。如果你不想用源码编译也可以直接安装官方发布的预编译wheel包但前提是你的PyTorch和CUDA版本跟它预编译的完全匹配。二选一即可我个人更推荐源码编译因为可控性更强。3.3 nuScenes数据集准备和格式转换BEVFusion在mmdet3d下的训练通常用nuScenes数据集需要依次处理visual、lidar、infos这几个组成部分。完整下载下来大概有300GB左右懒得全下的话可以先只下载mini版本跑通流程确认一切正常之后再下全量数据。下载之后最重要的环节是生成infos文件。mmdet3d的数据集类在读数据的时候依赖一个pkl文件这个pkl就是由官方脚本生成的。流程如下# 设置数据根目录 export NU_SCENES_ROOT/data/nuScenes # 生成infos文件full版本 python tools/create_data.py nuscenes \ --root-path $NU_SCENES_ROOT \ --out-dir $NU_SCENES_ROOT \ --extra-tag nuscenes \ --version v1.0-trainval \ --max-sweeps 10生成完之后你的nuScenes目录下会多出几个文件包括nuscenes_infos_train.pkl、nuscenes_infos_val.pkl等这些文件在训练和评估时都会被用到。我在生成infos的时候第一次就报错了报错原因是因为没有安装nuScenes官方的devkit。用pip安装一下就好pip install nuscenes-devkit另外如果你用的是镜像数据或者其他方式下载的数据一定要注意目录结构。mmdet3d的NuScenesDataset默认按{root}/samples/LIDAR_TOP这种方式寻找数据如果你把数据放在了别的路径下需要在配置文件里把data_root正确指到实际位置否则就是“file not found”满天飞。3.4 数据路径配置和软链技巧我习惯把数据统一放在一个目录下然后在mmdet3d工程目录里做一个软链接指向它这样配置文件写起来比较清爽也不会因为绝对路径出错ln -s /data/nuScenes ./data/nuscenes配置文件里的data_root我一般写成相对路的形式配合软链使用既方便迁移也方便多机训练时共享数据。这一点很多新手容易忽略但其实挺管用的。4. 配置文件详解从mmdet3d自带模型到BEVFusion环境装好、数据准备完毕之后就到了核心环节——配置模型。这一部分就是把BEVFusion的结构用mmdet3d的配置语言“翻译”出来。4.1 骨架文件从哪里来如果你用的mmdet3d版本比较新自带的模型库里已经收录了BEVFusion的实现可以直接在configs/bevfusion/目录下找到。我用的rc6版本没有收录所以需要从上游实现里手动移植工程量主要体现在编写融合模块的注册和配置上。无论你从哪个渠道获得配置都不要直接拿默认配置就去训练。至少要修改这几个地方数据路径data_root、ann_file类别数量和类别名称训练和测试时的batch size、学习率是否使用预训练权重非常重要BEVFusion的两条分支最好都要有预训练初始化4.2 逐步拆解一个BEVFusion配置主体结构下面我展示一个精简后的配置文件结构并把关键部分的含义标注出来。这个不是全文但包含了模型、数据、训练策略这几大块的核心要素model dict( typeBEVFusion, img_backbonedict( typeResNet, depth50, num_stages4, out_indices(0, 1, 2, 3), frozen_stages1, norm_cfgdict(typeBN, requires_gradFalse), norm_evalTrue, init_cfgdict(typePretrained, checkpointtorchvision://resnet50) ), img_neckdict( typeFPN, in_channels[256, 512, 1024, 2048], out_channels256, num_outs4 ), pts_voxel_layerdict( point_cloud_range[-51.2, -51.2, -5.0, 51.2, 51.2, 3.0], voxel_size[0.1, 0.1, 0.2], max_num_points10, max_voxels60000 ), pts_voxel_encoderdict( typePillarFeatureNet, in_channels5, feat_channels[64], with_distanceFalse, voxel_size[0.1, 0.1, 0.2], point_cloud_range[-51.2, -51.2, -5.0, 51.2, 51.2, 3.0] ), pts_backbonedict( typeSECOND, in_channels64, out_channels[64, 128, 256], layer_nums[3, 5, 5], layer_strides[1, 2, 2], norm_cfgdict(typeBN, eps1e-3, momentum0.01), conv_cfgdict(typeConv2d, biasFalse) ), pts_neckdict( typeSECONDFPN, in_channels[64, 128, 256], upsample_strides[1, 2, 4], out_channels[128, 128, 128] ), fusion_layerdict(...), # 这是BEVFusion核心负责BEV特征融合 bbox_headdict( typeTransFusionHead, num_classes10, in_channels128, ... ) )这份配置里值得单独拿出来说的是两件事一是voxel_size的选择。配的体素大小是0.1米和0.2米这是在精度和显存之间折中的结果。体素越小越精细但计算量越大。我试过把体素改成0.05米显存直接翻了一倍还多训练速度明显变慢但精度提升其实有限。如果是第一遍复现不建议追求极致的体素精度。二是图像分支和点云分支的预训练权重。图像的ResNet直接用torchvision://resnet50的预训练权重这个比较方便。点云部分的SECOND最好也使用在Waymo或nuScenes上预训练过的权重虽然mmdet3d模型库里有现成的但需要另外下载对应的pth文件。4.3 训练和测试阶段的数据流水线差异训练和测试时数据流水线最大的区别在于数据增强。训练阶段我使用的增强包括随机翻转、全局旋转、全局缩放和真值采样GlobalRotScaleTrans、RandomFlip3D、ObjectSample。其中真值采样对三维检测效果提升很大——从真值框里随机复制一些物体样本放入当前场景相当于人为增加目标数量对点云稀疏的类别特别有效。测试阶段则只保留最基础的筛选和加载操作不做任何增强保证评估结果的可比性。4.4 训练策略参数的确定我训练时用的关键参数如下表参数训练配置备注优化器AdamW权重衰减设0.01初始学习率2e-4图像分支和点云分支可以分别设置学习率调度CosineAnnealing10个epochbatch size4单卡/ 8双卡与显存直接相关训练轮数20 epochs迭代步数约2.4万步实际训练中有一个很实用的技巧把图像分支和点云分支的学习率分开设置。图像分支用较小的学习率因为它的预训练比较充分点云分支用较大的学习率让它在当前数据集上快速适应。这样设置比统一学习率收敛要快不少这个经验是在我多跑了几组对比之后得出的不是拍脑袋想的。5. 训练环节的实操记录从启动到收敛的完整过程训练是整个复现过程中时间成本最高的环节也是出现意外最多的环节。我详细记录一下我实际跑训练时经过的几个阶段以及遇到的问题。5.1 启动训练前的完整性检查清单在我真正敲下训练命令之前我养成了一个习惯——先跑一个“两轮快速调试”来验证整个流程是通的再放大规模训练。调试命令如下# 快速调试模式加载少量样本验证前向和反向传播是否正常 python tools/train.py 配置文件 \ --work-dir work_dirs/bevfusion_debug \ --cfg-options data.samples_per_gpu2 \ runner.max_epochs2如果这个调试跑通了说明模型结构、数据加载、损失计算、反向传播这一整个链路都没问题。接下来再跑正式训练心里就比较有底。正式训练我用的命令大致是这样export CUDA_VISIBLE_DEVICES4,5 # 多卡分布式训练 bash tools/dist_train.sh \ 配置文件 \ 2 \ --work-dir work_dirs/bevfusion \ --cfg-options \ data.samples_per_gpu4 \ optimizer.lr2e-4 \ runner.max_epochs20训练启动后一定要观察前十几个迭代的输出日志确认loss在正常波动范围。如果loss是NaN或者从一开始就异常大说明前面某些环节参数设置出了问题这时候别顾着跑应该先停下来排查。5.2 loss曲线观察与问题诊断我刚开始训练时遇到过一个典型问题前500步loss下降比较正常后面突然开始上下剧烈振荡而且模型输出的3D框出现了大量异常尺寸比如几十米长的“幽灵框”。我当时的第一反应是学习率太大但降了学习率之后振荡并没有缓解。后来排查发现真正的原因是训练类别不平衡。nuScenes数据集里行人、自行车这类小目标的标注框本来就多但点云稀疏检测头很难学到有效特征。解决方法是给loss函数里的不同类别加上不同的权重让小目标类别的loss贡献更大一些。这个调整加上之后振荡明显缓解小类别的召回率也有所提升。5.3 显存优化技巧训练时我用的GPU是24G显存的卡单卡batch size只能开到4再多就显存溢出。试过几个优化方法效果比较明显的是这几个梯度累积把每2个batch的梯度累积一起更新一次相当于变相扩大batch size对收敛稳定性有帮助。混合精度训练mmdet3d里可以用fp16True开启混合精度实测显存能省30%左右速度也有提升。但要注意混合精度模式下loss容易出现NaN需要设置合适的loss scale策略。关闭部分图像特征的梯度图像backbone在预训练之后可以实现frozen降低反向传播的内存开销。如果是第一遍复现我不建议一上来就把所有优化手段都加上那样出了问题很难排查。先用单精度、小batch size跑通再逐步加上混合精度和梯度累积每一步都确认效果和稳定性之后再继续。5.4 训练中断和续训我训练的第三天遇到过GPU被同事任务占用的中断事件。好在mmdet3d的trainer默认会定期保存checkpoint我用--resume-from参数直接从断点恢复python tools/train.py 配置文件 \ --work-dir work_dirs/bevfusion \ --resume-from work_dirs/bevfusion/epoch_10.pth续训时要注意一个问题如果你同时在跑多个实验不要直接重载模型权重文件而不带优化器状态。--resume-from和--load-from的区别在于前者会恢复优化器状态、学习率调度器状态后者只加载模型权重。续训应该用--resume-from这一点很多人容易忽略。6. 评估和可视化看结果怎么量化也看结果怎么“眼见为实”模型训练完之后评估和可视化是验证效果的重要环节。这部分也是复现过程中的高频需求。6.1 标准评估指标解读nuScenes数据集上的官方评估指标比较全主要看这几个指标含义参考值mAP多类别平均精度BEVFusion复现通常能做到0.4左右NDSnuScenes综合分数融合了mAP和多种属性误差0.5以上算不错mATE平均平移误差越小越好mASE平均尺度误差越小越好评估命令如下# 单卡评估 python tools/test.py 配置文件 \ 训练好的权重.pth \ --eval mAP \ --out results.pkl跑完评估会输出一份比较完整的指标报告每个类别的AP都会有单独数值。我重点看的一个类别是行人因为行人在nuScenes里点云稀疏属于难检类别BEVFusion在这类目标上的表现能直观体现图像分支带来的语义增益。6.2 可视化推理结果三维检测的可视化强烈推荐用mmdet3d自带的tools/test.py里的--show或者--show-dir参数它可以直接在点云场景里画出预测框和真值框python tools/test.py \ 配置文件 \ 训练好的权重.pth \ --show \ --show-dir work_dirs/bevfusion/vis_results输出结果是一组.jpg或.png格式的鸟瞰图和透视图可以直观看到模型在不同场景下的预测效果。另外mmdet3d还支持调用Open3D和Mayavi做交互式三维可视化直接把点云和预测框在三维空间里转着看。我调试模型的时候很喜欢用这个功能能精确定位到某些误检框到底是在什么位置、可能由什么因素造成的。6.3 定量分析和误检模式总结可视化看的是单个样本定量分析要换一种思路。我一般会把测试集的结果全部存成pkl文件然后写脚本做进一步分析核心关注这几个维度距离分布按目标距离划分区间统计各区间内的检测精度。一般来说近距离0-20米表现好远距离50米以上衰减严重。目标尺寸分布小目标行人、摩托车和大目标卡车、公交车的AP往往差别很大。误检模式观察哪些位置容易出现假阳框比如城市道路边缘、遮挡严重的区域往往误检率高。我实际分析下来发现BEVFusion复现结果中远距离行人的漏检率明显高于其他类别。这个现象的原因在点云支路——远距离行人的点云只有几个点稀疏卷积很难提取有效特征而图像支路的深度估计误差又比较大导致BEV投影位置偏移。明白了原因之后后面做优化就有了明确的方向比如可以考虑给图像分支加更深的深度监督或者提升远距离体素分辨率。7. 复现过程中的常见问题和解决方案汇总最后这部分是我从环境搭建到训练、评估全过程遇到的各类问题的汇总按问题现象、原因分析、解决方式来写供你对照排查。这些都是真实的“踩坑记录”不是从文档里抄来的。7.1 环境安装过程中的问题问题1mmcv编译报错提示找不到libcuda.so原因CUDA路径没有指向正确位置编译时找不到链接库。解决设置CUDA_HOME环境变量指向实际CUDA安装目录再重新编译。问题2spconv编译成功但import时报错原因spconv的编译版和当前虚拟环境中的PyTorch版本不一致。解决确保在同一个conda环境里依次安装完PyTorch后再编译spconv顺序很重要。问题3点云数据加载报错“could not open file”原因配置文件里的data_root指向了错误路径。解决检查配置文件中data_root和ann_file的路径或者用软链接把数据链到预期位置。7.2 训练过程中的问题问题1loss为NaN训练无法继续原因排查按优先级排列学习率过大 → 混合精度下loss scale设置不当 → 数据中有异常值 → 模型参数初始化为无穷大。我的处理顺序是先降到小学习率不行就关掉fp16再看数据预处理里是否有除零或log0操作。问题2训练前期loss下降很慢宛如“不学习”这通常和初始化相关。BEVFusion的两个分支对初始化都比较敏感如果点云分支不是从预训练权重启动初期收敛会非常慢。另外要检查学习率的绝对值多卡训练时学习率要相应放大比如单卡2e-4双卡可以尝试3e-4左右。问题3显存不足OOM一般出现在图像分支的BEV特征图上。处理手段包括降低输入分辨率、减小体素分辨率、开启梯度累积、关闭图像backbone的BN层梯度等。不建议一上来就强行降低batch size到1那样BN统计量的更新会很不稳定模型性能会明显下降。7.3 评估阶段的问题问题1评估结果里预测框全是空的这通常是评估时使用了训练时的配置文件但遗忘关闭测试时的数据增强。某些增强比如全局旋转在测试时会把真值框和点云一起变换导致坐标错乱。检查测试流水线里是否还残留着训练时的增强。我在第一次评估时也遇到过这个坑原因就是测试时依然加载了包含GlobalRotScaleTrans的流水线配置。问题2mAP正常但NDS偏低NDS还包含了方向、速度、尺寸等属性误差。如果mAP正常但NDS偏低说明模型在定位或朝向估计上还有短板。可以先单独看看mATE定位误差和mAOE朝向误差判断具体是哪个属性拖了后腿。这种情况通常可以通过调整检测头里的方向损失权重、细化anchor设置来改善。8. 我的几点实际体会和后续改进建议复现BEVFusion这件事说难也难说简单也简单。难在环境兼容、数据准备这种“脏活累活”上简单在模型结构本身并不像一些纯Transformer-based方法那么绕只要你把流程拆对了逐块去调基本上都能跑通。我自己的最大体会是不要小看环境配置阶段的每一分钟消耗后面所有的时间和算力成本都建立在环境稳定之上。我为了图快一开始装的是最新版mmcv结果和mmdet3d的接口对不上光排错就花了两天。后来老老实实按版本兼容表一字不差地装反而半小时就搞定。这个教训非常直接。如果跑通之后你还想做进一步的优化我会建议从这几个方向尝试数据增强层面加入更多针对远距离小目标的采样策略比如在真值采样时按类别控制采样比例尽量多让难例参与训练。模型结构层面可以试试在融合层里做更细致的模态置信度建模而不是直接用concat也可以把图像分支的FPN换成BiFPN多尺度特征的融合效果大概率会有提升。损失函数层面给深度估计分支加一个显式的监督信号让视角变换的深度预测更准确这能从根上缓解远距离目标特征错位的问题。推理优化层面尝试TensorRT做半精度推理或者将图像backbone替换为更轻量的网络比如MobileNet系列在边缘平台上跑实时推理是可行的方向。另外复现的意义不只是跑出一个和论文差不多的分数。我建议跑通之后把训练好的模型在没有图像输入只用点云和没有点云输入只用图像两种极端情况下各测一次。这能非常直观地告诉你这个融合模型到底从跨模态融合里获得了多少增益。我实测下来跨模态融合对行人和自行车这两个稀疏目标的AP提升能达到8~12个百分点这个数据比论文图表更有说服力。最后再分享一个小技巧。如果你需要调参但算力有限可以先锁住图像分支和点云backbone的参数只训练融合层和检测头。这样训练速度快很多而且往往能达到全参数训练七八成的效果。等主要参数调优差不多之后再解冻全部参数做完整微调。这个策略不管是时间成本还是显存需求上都划算不少。我在复现BEVFusion的过程中踩过的坑基本都写在上面了每一个都对应一次真实的debug经历。希望这篇文章能让你在动手之前心里有个底如果真的遇到问题也知道大概率问题出在哪个环节。祝跑通顺利。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑