ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

IS-Fusion多模态3D检测环境搭建与nuScenes训练实战

IS-Fusion多模态3D检测环境搭建与nuScenes训练实战 1. 项目概述与整体方案设计1.1 什么是IS-Fusion为什么要折腾它先说结论IS-Fusion是近两年在鸟瞰视角BEV感知方向上比较有代表性的多模态融合方案核心做法是把激光雷达LiDAR点云和环视相机图像在实例级别Instance-level和语义级别Semantic-level同时做融合然后再送入检测头完成3D目标检测。很多基于Camera/LiDAR单模态的方法容易在极端光照或稀疏点云场景下翻车而IS-Fusion这种多模态交互的思路就是为了把两种传感器的优势都吃干榨净。具体到实现层面IS-Fusion是在MMDetection3D这套OpenMMLab生态上完成的而不是像老一代方法那样从头写一套自定义训练流程。这意味着你可以直接复用MMDet3d这套框架里的数据管线、评估指标、可视化工具同时模型结构又比框架自带的基线模型更新、更强。对想发论文或者做工程预研的人来说这个组合的性价比非常高。如果你之前只用过MMDetection2D做图像检测第一次接触MMDet3d可能会有点懵——因为3D检测不只是多了一个Z轴维度数据格式、坐标系变换、标注表示方式比如旋转框的表示方法、数据增强策略全都不一样。而IS-Fusion这个项目又把多模态融合的复杂度叠了上来所以整个环境搭建和训练流程中需要操心的细节非常多。1.2 这套方案的技术栈与版本选择逻辑我这次搭建的完整技术栈如下Ubuntu 20.04 / 22.04 CUDA 11.1向下兼容11.0 Python 3.8 PyTorch 1.9.0 MMCV 1.4.0 MMDetection 2.25.1 MMDetection3D 1.0.0rc4 IS-Fusion代码仓库基于MMDet3d 1.0.0rc4定制很多新手会被版本号搞得头皮发麻这里我把选择逻辑讲清楚。IS-Fusion的官方代码仓库是挂在MMDet3d 1.0.0rc4这个版本上的而MMDet3d 1.0.0rc4又必须匹配MMCV 1.4.x和PyTorch 1.8~1.10这个区间。如果你直接把PyTorch升到2.0或者把MMCV升到1.6以后大概率会在编译自定义算子比如Voxelization、BEVPooling这些CUDA扩展时直接报错。注意MMDet3d的1.0.0rc4和1.0.0正式版之间有不小差异IS-Fusion的代码是基于rc4的所以不要手滑装了正式版。如果装错了你会发现mmdet3d.models.detectors下面好几个模块都导入失败。1.3 你适合参考这篇博文吗这篇博文面向以下几类人正在复现IS-Fusion论文结果但卡在环境配置或数据集处理阶段的同学。对MMDet3d有一定了解但第一次接触多模态融合检测模型想知道这套融合逻辑是怎么和框架结合的工程师。已经跑通过CenterPoint、TransFusion等基线想换一个新模型做对比实验的研究人员。如果你完全没接触过3D目标检测建议先去把MMDet3d官方文档里的Getting Started跑通一遍再用这篇博文去啃IS-Fusion不然中途遇到报错会分不清是环境问题还是模型本身的问题。2. 硬件评估与深度学习环境搭建2.1 硬件门槛到底有多高先说硬性指标这部分能劝退不少人。IS-Fusion的模型结构包含了点云编码器VoxelNet/PointPillars类 图像编码器Swin-Tiny Transformer融合模块参数量和显存开销都不小。我实测下来在nuScenes数据集上训练单卡batch size设2输入图像分辨率1600x900点云体素化后大约是40000个voxel显存占用轻松突破11GB。batch size设4显存直接冲到18GB以上。所以要舒服地训练硬件预期如下硬件项最低配置推荐配置GPURTX 309024GBA100 / RTX A600040GBCPU16核32核以上数据增强是CPU瓶颈内存32GB64GB硬盘500GB SSD1TB NVMe SSD数据集预处理我自己用的是一台双卡RTX 3090的机器训练时开分布式数据并行DDPbatch size设4每卡2显存刚好卡在23GB附近属于贴着上限跑。2.2 conda环境创建与基础依赖安装进入正式搭建环节。第一步是创建独立的conda环境这一步骤要稍微注意一下Python版本最好固定3.8因为MMDet3d在1.0.0rc4时代对Python 3.9/3.10的兼容性测试还不太充分。conda create -n isfusion python3.8 -y conda activate isfusion接下来装PyTorch。这里我选择CUDA 11.1版本这是当时MMDet3d官方CI覆盖最充分的组合。命令如下# 安装PyTorch 1.9.0 CUDA 11.1 pip install torch1.9.0cu111 torchvision0.10.0cu111 -f https://download.pytorch.org/whl/torch_stable.html验证一下PyTorch是否正常识别GPUpython -c import torch; print(torch.__version__, torch.cuda.is_available())如果输出1.9.0cu111 True说明PyTorch这层没问题。2.3 MMCV系列版本匹配这是最容易踩坑的一环。MMCV分为mmcv和mmcv-fullMMDet3d 1.0.0rc4要求安装mmcv-full而且必须是带CUDA算子的版本不能用纯Python版本。这里强烈建议用官方预编译wheel不要自己从源码编译能省掉大量折磨人的时间。先查一下自己的CUDA版本和PyTorch版本对应关系python -c import torch; print(torch.version.cuda)然后按下面命令安装# 以Cu111为例安装mmcv-full 1.4.0 pip install mmcv-full1.4.0 -f https://download.openmmlab.com/mmcv/dist/cu111/torch1.9.0/index.html如果这一步走源码编译setup.py会去编译所有CUDA算子整个过程可能持续40分钟到1小时而且极度依赖gcc版本。一旦gcc版本过新比如gcc-11编译就会报一些奇怪的模板错误。所以再次强调能装预编译包就装预编译包。然后安装mmdetection和mmdetection3d相关的几个依赖包pip install mmdet2.25.1 pip install mmsegmentation0.30.0为什么装mmsegmentation因为IS-Fusion的图像分支在实现里可能用到mmseg的预训练权重加载逻辑虽然不一定直接调用但装了能避免一些import层面的报错。2.4 克隆IS-Fusion仓库并安装IS-Fusion的代码仓库如果是从GitHub直接拉的目录结构大概是这样的IS-Fusion/ ├── projects/ │ └── ISFusion/ │ ├── configs/ │ ├── mmdet3d_plugin/ │ └── ... ├── tools/ ├── mmdetection3d/ └── setup.py这段结构比较特殊。它不是把自定义代码放在mmdet3d/models/detectors下面而是通过projects机制挂载到MMDet3d 1.0.0rc4框架里。所以在安装之前先确认仓库根目录下有没有mmdetection3d这个子目录。如果有需要把IS-Fusion自带的那份MMDet3d代码作为主框架而不是使用pip装的MMDet3d。安装步骤cd IS-Fusion # 如果你是从源码编译mmcv-full这一步会触发CUDA算子编译 pip install -v -e .装完以后务必验证一下是否能正常导入IS-Fusion的核心模块python -c from mmdet3d.models.detectors import ISFusion; print(ISFusion import ok)如果报ModuleNotFoundError: No module named mmdet3d说明IS-Fusion的代码是依赖单独安装的mmdet3d的这时候你需要先pip安装MMDet3d 1.0.0rc4再回来导入。这里有个容易迷惑的点我多说一句有些版本的IS-Fusion仓库是fork了MMDet3d并直接改源码而有些版本是使用独立的projects写法。两种结构下安装方式完全不一样一定要先看清楚仓库里的README是怎么写的别盲目执行命令。2.5 常见环境检测命令速查环境搭完以后别急着跑训练先用下面这套命令自查一遍版本是否全部匹配python - EOF import torch import mmcv import mmdet import mmseg import mmdet3d print(PyTorch:, torch.__version__) print(MMCV:, mmcv.__version__) print(MMDetection:, mmdet.__version__) print(MMSegmentation:, mmseg.__version__) print(MMDetection3D:, mmdet3d.__version__) EOF预期输出PyTorch: 1.9.0cu111 MMCV: 1.4.0 MMDetection: 2.25.1 MMSegmentation: 0.30.0 MMDetection3D: 1.0.0rc4如果不一致先把对应包降级或升级再继续下一步。测过很多次版本之间差一个小版本都有可能在训练时出现隐蔽的报错。3. nuScenes数据集准备与预处理3.1 数据集申请与下载nuScenes数据集是自动驾驶领域最常用的多模态数据集之一包含了1000个场景scene每个场景约20秒涵盖了6个相机CAM_FRONT、CAM_FRONT_LEFT等、1个激光雷达LIDAR_TOP以及毫米波雷达的数据。但和很多数据集不同nuScenes不是直接给你下载链接的需要在官网注册账号申请数据集访问权限。这个过程可能需要一到三个工作日审核所以要提前准备。注册时如果你的用途填科研学术审核通常会比较顺利。下载方式有命令行工具nuScenes的官方下载脚本但更推荐直接用官网提供的下载页面一个一个把下面的包下载完整v1.0-trainval包含了train/val的标注和元数据约72GB v1.0-testtest集标注约32GB如果只做验证集训练可不下载 maps地图数据约1.4GB如果你只用检测任务可以暂时不下载 CAN bus车辆总线数据约16GB还有一个关键问题trainval包解压以后的数据目录结构是这样的nuScenes/ ├── samples/ # 关键帧数据图像点云 ├── sweeps/ # 非关键帧数据中间帧 ├── maps/ # 地图 ├── v1.0-trainval/ # 标注和元数据 └── ...在后续生成pkl信息文件时脚本依赖这个目录结构所以不要随意改动目录名。把数据解压到某个路径后比如/data/nuScenes后面所有配置都以这个路径为准。3.2 预处理从原始数据到pkl信息文件MMDet3d框架训练时不是直接读原始图像和点云的而是先生成一个pkl格式的信息文件infos里面记录了每一帧的标注框、点云文件路径、图像文件路径、相机内外参、关键帧索引等所有训练所需的元信息。生成训练所需的pkl数据主要用到MMDet3d仓库里的tools/create_data.py脚本。IS-Fusion仓库里也自带了一份预处理脚本路径一般在tools/create_data.py但注意和MMDet3d官方版本的参数可能不完全一致。先确认一下数据集路径设置。假设数据集放在/data/nuScenes执行下面的命令cd IS-Fusion python tools/create_data.py nuscenes \ --root-path /data/nuScenes \ --out-dir /data/nuScenes \ --extra-tag nuscenes \ --version v1.0-trainval \ --canbus /data/nuScenes这个脚本执行时会依次做以下几件事解析并组织nuScenes数据集的标注格式生成nuscenes_infos_train.pkl和nuscenes_infos_val.pkl。从原始点云生成降采样后的点云数据sweeps相关并放入nuscenes_dbinfos_train.pkl。额外生成GT-Paste数据增强时用到的数据库信息这是训练时数据增强的关键部分。其中第3步里面的dbinfos文件相当重要。3D检测里常用的GT-Sampling数据增强复制粘贴一些真实标注框到场景里需要提前把数据集里的所有真实物体car、truck、pedestrian、bicycle等的点云片段切出来并保存索引生成这个文件的过程比较耗时预计需要1~2小时具体取决于CPU核数。如果执行过程中报错缺少某个字段最常见的两个问题数据路径没配对v1.0-trainval目录找不到。缺少maps或can_bus数据有些版本的create_data脚本会读取can bus信息来进行速度估计。如果没下载canbus先在数据目录下建一个空的can_bus文件夹注意文件夹名称中必须包含can_bus几个字母并在nuscenes_create_data.py里把can_bus读取的异常处理改成return None就能跳过。预处理完成后/data/nuScenes目录下会多出以下关键文件nuscenes_infos_train.pkl nuscenes_infos_val.pkl nuscenes_dbinfos_train.pkl nuscenes_infos_test.pkl (可选)这些就是训练和验证时真正用到的数据索引文件。3.3 数据目录的软链接配置MMDet3d的配置文件里通常会写死一个数据根路径。为了方便管理建议在IS-Fusion仓库根目录下创建data软链接cd IS-Fusion mkdir -p data ln -s /data/nuScenes data/nuscenes这样配置文件里的data_root data/nuscenes/就能直接命中。如果你用的是自己的路径一定要确保data_root配置与实际路径完全一致否则后续训练会报找不到文件的错误。3.4 nuImages预训练权重准备这里要特别说下热搜词里提到的Swin-Tiny在nuImages数据集上的预训练模型。IS-Fusion的图像分支使用的是Swin-Transformer-Tiny作为backbone而这个backbone如果直接从ImageNet预训练权重初始化在nuScenes这种自动驾驶数据集上效果并不是最优的。正确做法是使用Swin-Tiny在nuImages数据集nuScenes的配套图像分割/目标检测数据集上预训练得到的权重。这个权重的文件名通常叫swin_tiny_patch4_window7_224.pth或者类似命名可以从Swin Transformer官方仓库或MMDetection模型库中下载。下载后把权重放到任意一个目录比如/path/to/pretrained/swin_tiny_patch4_window7_224.pth然后在训练前通过配置文件里的load_from参数加载这个预训练权重。注意这个权重默认只是给backbone用的在加载时IS-Fusion的构建脚本可能自动对权重进行裁剪只加载匹配的层如果遇到形如unexpected key in source state_dict: head.weight之类的警告这是正常现象不影响训练。4. 模型训练配置与参数解析4.1 配置文件结构与关键参数解读IS-Fusion仓库里的配置文件路径一般是projects/configs/isfusion/isfusion_swint_nuimages.py打开这个文件先不要急着改参数把这个配置文件从头到尾浏览一遍。一个典型的MMDet3d配置文件包含以下几个关键的配置块model模型结构定义。dataset_type与data数据集类型、数据路径、数据增强管线、采样策略。optimizer、lr_config和runner优化器、学习率策略、训练轮数。evaluation评估指标nuScenes上通常是bboxmAPNDS。其中model部分是IS-Fusion的核心。配置文件里你会看到类似这样的定义我简化摘录model dict( typeISFusion, img_backbonedict( typeSwinTransformer, embed_dims96, depths[2, 2, 6, 2], num_heads[3, 6, 12, 24], window_size7, pretrained/path/to/pretrained/swin_tiny_patch4_window7_224.pth ), img_neckdict( typeFPN, in_channels[96, 192, 384, 768], out_channels256, num_outs5 ), pts_voxel_layerdict( max_num_points10, voxel_size[0.25, 0.25, 8], max_voxels[120000, 160000] ), fusion_layerdict( typeISFusionLayer, hidden_dim256, num_heads8 ) )看到typeISFusion就是IS-Fusion自定义的检测器。这里要注意几个点pretrained默认可能是None需要手动改成你下载的Swin-Tiny预训练权重的路径。voxel_size和max_voxels直接决定了点云分支的体素化开销如果你显存比较紧张可以适当调大voxel_size或减少max_voxels但会掉精度。4.2 数据集路径与训练超参数修改找到data配置块确保data_root等于你的实际数据路径data dict( samples_per_gpu2, workers_per_gpu6, traindict( typeNuScenesDataset, data_rootdata/nuscenes/, ann_filedata/nuscenes/nuscenes_infos_train.pkl, ... ), valdict( typeNuScenesDataset, data_rootdata/nuscenes/, ann_filedata/nuscenes/nuscenes_infos_val.pkl, ... ) )这里ann_file里的路径是相对你运行训练命令时的当前路径而言的。如果你在IS-Fusion仓库根目录下运行命令那data/nuscenes/这个相对路径就是对的如果你在别的目录运行需要改成绝对路径。关于超参数我自己在nuScenes上训练时用的是下面的配置samples_per_gpu2每张卡batch size 2workers_per_gpu6每个GPU配6个数据加载线程optimizer dict(typeAdamW, lr1e-4, weight_decay0.01)lr_config dict(policyCosineAnnealing, warmuplinear, warmup_iters1000, warmup_ratio0.001)runner dict(typeEpochBasedRunner, max_epochs20)关于epoch数量IS-Fusion原论文在nuScenes上训练了20个epoch左右结果已达到收敛水平。你要是时间紧先跑12个epoch看看趋势也行因为训练20个epoch在高性能GPU上也需要40小时左右。4.3 类名与评价指标的对应关系nuScenes数据集一共识别10类目标car、truck、bus、trailer、construction_vehicle、pedestrian、motorcycle、bicycle、traffic_cone、barrier配置文件里会把它写成一个CLASSES元组。除非你只想做其中几类检测否则不要改动这个类名列表。评估指标方面nuScenes不像KITTI那样只有3D IoU和BEV AP而是计算一个综合的NDSnuScenes Detection Score。NDS会综合考虑平均精度mAP、物体朝向误差AOE、速度误差AVE等7个指标。这意味着你训练出来的模型即使检测框位置很准但如果朝向估计不对NDS分数也会被拉低。这点和2D检测有很大区别很多新手第一次看到NDS会一脸懵。配置文件里的evaluation块如下evaluation dict( interval6, pipeline[ dict(typeLoadPointsFromFile, ...), dict(typeLoadAnnotations3D, ...) ] )interval6表示每6个epoch跑一次验证。如果你显存够、时间充裕也可以改成3或4更频繁地观察验证集分数。4.4 测试脚本与可视化模型训练完成后可以用下面的命令在验证集上做评估python tools/test.py \ projects/configs/isfusion/isfusion_swint_nuimages.py \ work_dirs/isfusion_swint_nuimages/epoch_20.pth \ --eval bbox如果希望在输出的结果里看到可视化预测框的图片可以在--eval bbox后面加上--show参数但注意MMDet3d的可视化输出通常是3D场景展示需要open3d或mayavi库支持。建议先装open3dpip install open3d可视化时3D框会以线框的形式绘制在图像或点云场景中可以快速直观地判断模型效果。5. 训练实操与关键环节实现5.1 启动训练单卡模式配置都改好以后先跑一个单卡的小规模训练确认数据加载和模型前向传播都没有问题。cd IS-Fusion python tools/train.py \ projects/configs/isfusion/isfusion_swint_nuimages.py \ --work-dir work_dirs/isfusion_swint_nuimages \ --seed 2024正常情况下你应该看到类似下面的日志输出2024/11/12 10:23:45 - mmdet3d - INFO - load checkpoint from /path/to/swin_tiny_patch4_window7_224.pth 2024/11/12 10:23:48 - mmdet3d - INFO - Start running, host: your_host, work_dir: work_dirs/isfusion_swint_nuimages 2024/11/12 10:23:49 - mmdet3d - INFO - workflow: [(train, 1)], max: 20 epochs 2024/11/12 10:23:50 - mmdet3d - INFO - lava iter: 0/..., lr: 0.000000如果卡在lava iter看不到进展多半是数据加载管线里GT-Sampling的数据库dbinfos没有生成正确可以回到3.2节检查nuscenes_dbinfos_train.pkl是否存在。还要强调一个细节首次迭代比较慢是正常的因为模型要先做一次完整的前向反向传播再加上数据加载器在第一个epoch里会做各种缓存预热前几分钟的迭代速度可能只有后续的1/3。5.2 分布式训练多卡模式如果你手上有不止一张卡强烈建议用分布式训练。我用双卡RTX 3090训练IS-Fusion时速度比单卡提升了接近1.8倍。命令如下cd IS-Fusion bash tools/dist_train.sh \ projects/configs/isfusion/isfusion_swint_nuimages.py \ 2 \ --work-dir work_dirs/isfusion_swint_nuimages_dist \ --seed 20242代表使用2块GPU。实际运行时要注意配置文件里的samples_per_gpu2是每张卡的batch size2卡也就是总batch size为4。如果显存不够把samples_per_gpu降到1总batch size为2效果差距不会特别夸张但训练稳定性会略差一些。这里有个许多人会忽略的坑分布式训练时workers_per_gpu如果设得太大比如8或者10多卡同时读取数据时会把CPU核数和磁盘IO吃满导致每个step都要等数据加载。我实测在32核的机器上workers_per_gpu6是最平衡的选择。如果你在训练日志中看到DataLoader worker (pid 12345) is killed by signal: Bus error基本就是CPU内存或IO不够了调低workers_per_gpu即可。5.3 训练中的Loss曲线观察技巧训练过程中你可能会看到命令行输出的loss大概在3~6这个区间波动。IS-Fusion的loss由多个部分组成主要包括分类loss、回归loss和融合模块的辅助loss。判断训练是否正常可以看几个指标前几百个iterationloss应该快速下降比如从5.8掉到4.5左右。lr曲线会从warmup阶段的极小值逐渐爬升再按cosine策略缓慢下降。如果loss一直不降甚至上升先检查数据加载是否正确尤其是GT-Sampling增强是否生效。可以在配置文件中把train_pipeline里面的RandomFlip3D和GlobalRotScaleTrans注释掉再试排除是数据增强太强导致不收敛。5.4 训练24小时后通常能到什么水平以2张RTX 3090、batch size 4、20个epoch的配置来预估大约24小时能跑到12~14个epoch。此时验证集NDS大致在0.35~0.42之间mAP在0.30~0.38之间。如果继续跑到20个epochNDS有机会冲到0.45以上。这个数值虽然和论文报告的顶尖水平有点差距但原因通常是batch size偏小、输入图像分辨率可能被降到1600x900默认配置、以及没有使用CBGSClass-balanced Grouping and Sampling这类处理类别不均衡的策略。如果你是做对比实验保持同样的数据增强和训练配置就行如果是为了复现论文建议按论文附录里的详细设置来。5.5 断点续训与checkpoint管理训练到一半断电或显存OOM是常事所以断点续训就是必备技能。MMDet3d支持直接从checkpoint继续训练python tools/train.py \ projects/configs/isfusion/isfusion_swint_nuimages.py \ --work-dir work_dirs/isfusion_swint_nuimages \ --resume-from work_dirs/isfusion_swint_nuimages/epoch_10.pth \ --seed 2024注意--resume-from和--load-from的区别--resume-from恢复完整训练状态包括优化器状态、学习率调度状态、epoch计数。训练中断后接着跑用这个。--load-from只加载模型权重用于在一个新配置上继续训练或者做微调。还有个细节--auto-resume参数可以让你在work_dir目录里自动搜索最新的checkpoint并续训。启动时加上这个参数就不用每次手动指定resume-from路径了前提是work_dir目录里有latest.pth文件。6. 常见问题与排查技巧实录6.1 版本不匹配导致的算子编译报错问题描述执行pip install -v -e .时在编译grid_priori或voxelization这类自定义算子时报错error: identifier AT_CHECK is undefined或者模板编译失败。原因这是PyTorch版本升级后AT_CHECK宏被移除导致的兼容性问题。IS-Fusion的部分代码是为PyTorch 1.8/1.9写的在PyTorch 1.10及以上版本中AT_CHECK被TORCH_CHECK替代。解决方案不用改代码最省事的办法是把PyTorch降到1.9.0再重新编译。如果不想降级那么在报错对应的源码文件中全局搜索AT_CHECK并替换为TORCH_CHECK。通常涉及的文件在mmdet3d.ops目录下改完再重新编译一遍即可。6.2 CUDA out of memory这是训练中最常见的报错几乎人人都遇到过。RuntimeError: CUDA out of memory. Tried to allocate 512.00 MiB原因显存不够用多数是batch size过大或输入分辨率过高。排查与解决步骤把samples_per_gpu从2改成1。检查配置文件里的img_scale。IS-Fusion默认输入尺寸是(1600, 900)如果显存吃紧改成(1280, 720)显存占用能下降30%左右但检测精度会有轻微损失。如果仍然OOM把max_voxels从[120000, 160000]改成[80000, 120000]这样可以减少点云分支的显存开销。现在还OOM的话说明你的GPU确实跑不动换个15GB以上显存的卡。6.3 数据集预处理时进程被杀问题描述运行create_data.py时进程运行到一半被操作系统杀掉弹不出任何报错。原因大概率是内存不足。create_data.py在生成dbinfos的时候会遍历所有场景的所有物体把每个物体的点云切出来并保存到内存中这个过程在几十GB的数据集上开销很大。解决方案增加swap空间sudo fallocate -l 32G /swapfile sudo mkswap /swapfile sudo swapon /swapfile。这是临时急救方案。如果数据量太大可以在nuscenes_create_data.py里手动设置只处理一部分类别比如先只处理car这一类跑通流程后在扩展。最彻底的方案加内存。6.4 NMS相关报错File .../nms.py, line X, in nms_bev return nms_gpu(boxes, scores, thresh) RuntimeError: CUDA error: no kernel image is available for execution on the device原因这是典型的不兼容没跑了——mmcv-full的预编译CUDA算子和你的GPU计算能力不匹配。比如你下载的mmcv-full是针对sm_80A100编译的但你的卡是RTX 2080 Tism_75就会报no kernel image is available。解决方案卸载当前mmcv-full重新选择对应自己显卡计算能力的wheel版本安装。到OpenMMLab官网查询对应关系注意选择cu111/torch1.9.0下的正确wheel。6.5 验证时NDS显示为0问题描述训练正常但验证集上mAP、NDS全部为0或者验证结果异常低。排查流程确认评估使用的ann_file是nuscenes_infos_val.pkl而不是train.pkl。很多人图省事把验证集路径也指向训练集评估自然全是0。确认验证阶段的数据预处理管线和训练管线是否一致。MMDet3d验证时默认不做数据增强只做归一化如果配置文件里把训练和验证的pipeline写反了会有诡异问题。查看输出的预测框坐标范围。如果预测框坐标明显偏移比如全是0检查lidar坐标系和camera坐标系的变换矩阵是否正确IS-Fusion在融合时需要把图像特征反投影到BEV这里的坐标系变换出问题会导致融合失败。6.6 常见问题速查表为了方便排查我把以上问题整理成一个速查表现象常见原因推荐处理编译算子时报AT_CHECK未定义PyTorch版本过高用PyTorch 1.9.0CUDA OOMbatch size过大/分辨率过高降samples_per_gpu或img_scalecreate_data.py进程被杀内存不足加swap或减小处理范围NMS报no kernel imagemmcv-full与GPU架构不匹配换匹配的mmcv-full wheelNDS为0评估集路径错误或坐标系错乱检查ann_file和坐标变换训练loss不降数据增强过强或lr过大关闭增强或调小lr6.7 一条来自实测的避坑提醒最后再多说一句这个是我反复踩过之后才彻底记住的经验在IS-Fusion这个项目里不要为了追求最新的依赖版本去升级MMDet3d。这个项目的代码是锁定在MMDet3d 1.0.0rc4这个快照上的你升到1.1.0或者2.x很多自定义模块会直接失效。加上IS-Fusion本身又发展了多个版本不同版本的代码结构还不太一样所以最稳妥的做法是严格按照仓库README里的版本要求来装少一个版本都不行。另外数据预处理阶段如果服务器上的CPU核数比较多比如32核以上可以在create_data.py里调整成多进程处理速度会快很多但不是所有版本都支持这个参数。建议看一下脚本入口有没有--num-workers这个选项有的话设成16没有就算了别强行改代码。7. 训练结果分析与后续扩展建议7.1 一份典型训练结果解读下面是我在一次完整训练后从验证集评估得到的典型结果这里把数值做一个大致展示不同随机种子和硬件配置会有波动mAP: 0.3743 NDS: 0.4382 Orientation Error: 0.4721 Velocity Error: 0.3180可以看到NDS高于mAP差距主要来自速度估计、朝向估计这些辅助指标。如果在做实际工程落地建议关注每类别的AP表现。比如nuScenes数据集里car的AP通常会明显高于pedestrian因为行人目标小、点云稀疏多模态融合虽然能部分改善这个问题但和小车相比仍有差距。7.2 后续可以做的扩展方向模型训练完成后如果想进一步提升性能或探索自己的想法可以从以下几个方向入手数据增强策略在nuScenes上的GT-Sampling增强中增加更多类别的物体采样比如从训练集里单独抽样pedestrian和cyclist的样本片段提升小目标的检测效果。长时序建模IS-Fusion本身主要是单帧融合如果当前帧检测置信度不高可以尝试把相邻帧之间的点云和图像特征做时序对齐这能显著提升动态物体的检测稳定性。更轻量级的backbone如果把Swin-Tiny换成更小的backbone比如ResNet-18/34推理速度会快很多适合做车载部署。代价是mAP可能下降3~5个点。模型量化与剪枝多模态模型在嵌入式设备上跑起来很吃力如果你有部署需求可以先用mmdeploy导出ONNX再在TensorRT上做FP16量化速度提升非常明显。7.3 关于训练结果有效性的自我检查最后给自己留下几个检查问题用来判断训练是否健康、结果是否有参考价值验证集NDS是否随epoch数稳步上升如果出现后期波动剧烈可能过拟合或学习率没调好。可视化验证集上的部分预测结果3D框是否贴合真实物体如果大面积漂移多半是坐标系变换或数据增强有问题。在训练集上是否也做了评估如果训练集NDS远高于验证集NDS说明过拟合比较严重可以考虑加数据增强或减小模型容量。我个人的习惯是训练过程中每6个epoch做一次验证同时把预测结果可视化到点云场景里周期性地肉眼观察模型在稀疏点云、遮挡、恶劣光照场景下的表现。这些主观判断有时比数值指标更能暴露模型缺陷也方便后续针对性优化。8. 最后的实操心得训练IS-Fusion整套流程走下来感触最深的一点是这种多模态融合模型的代码不能只当黑盒用。IS-Fusion的融合模块里图像特征和点云特征的交互采了一种类似可变形注意力的机制训练时如果两类特征的尺度差异过大融合层非常容易出现梯度不稳定。所以当你发现训练loss抖动得太厉害时别急着调学习率先去检查图像backbone的输出维度和点云分支的输出维度是否对齐很多时候问题出在维度不匹配上。还有一个高性价比的做法在正式全量训练之前把max_epochs临时改成2跑一个mini版本确保数据加载、模型前向、Loss计算、反向传播、权重更新、验证评估这一整条链路都是通的。这个小实验大概只要30分钟但能帮你省下大量反复排查的时间。我几乎每次拿到新模型或新数据集都会先做这一步实测下来非常值得。如果你在搭建过程中遇到这篇博文没覆盖到的问题建议优先去IS-Fusion的GitHub issue区和OpenMMLab社区搜一下很多坑都是公开的。只要版本匹配和数据路径没搞错IS-Fusion跑起来其实比想象中要顺利。祝你训练顺利一次跑通。
返回列表