1. 环境搭建:从零开始的避坑指南
搞3D目标检测,特别是想复现IS-Fusion这种多模态融合的SOTA模型,第一步的环境搭建往往就能劝退一大半人。我刚开始折腾的时候,光是版本冲突就花了两天时间,不是这个库不兼容,就是那个依赖装不上。所以,咱们今天不整虚的,直接上干货,手把手带你走一遍我踩过坑、验证过的环境配置流程,目标是让你一次成功,把时间留给更重要的模型调优。
IS-Fusion这个框架,简单说就是把激光雷达(LiDAR)点云和摄像头(Camera)图像的信息“捏”在一起,让模型既能“看到”物体的精确三维形状和位置,又能“理解”图像的丰富纹理和语义。它基于OpenMMLab家族的MMDetection3D构建,所以你得先搞定MMDetection3D那一套生态。别怕,跟着我的步骤来,咱们一步步拆解。
1.1 创建并激活Conda虚拟环境
第一步,也是最重要的一步:务必使用虚拟环境。这是血泪教训,直接在你的系统Python里瞎搞,一旦玩崩了,重装系统的心都有。我推荐用Conda,包管理比pip清晰得多。
打开你的终端,执行下面这行命令。这里我指定了Python 3.8,这是经过验证与PyTorch 1.10、CUDA 11.1组合比较稳定的版本。别轻易尝试更高版本,兼容性是个玄学。
conda create -n isfusion python=3.8 -y创建完成后,激活这个环境。以后所有操作,都要确保在这个isfusion环境下进行。
conda activate isfusion接下来,把IS-Fusion的源代码克隆到本地。建议找个路径干净的地方,比如你的工作目录~/workspace。
git clone https://github.com/yinjunbo/IS-Fusion.git cd IS-Fusion1.2 安装核心依赖:PyTorch与关键Python包
进入正题,安装PyTorch。这里有个巨坑:你必须先确认自己显卡驱动支持的CUDA版本。打开终端,输入nvidia-smi,看右上角显示的CUDA Version。比如显示的是11.4,那么你安装的PyTorch最好选择CUDA 11.1或11.3的版本,向下兼容一般没问题,但向上兼容经常出幺蛾子。
假设我们用的是CUDA 11.1,那么安装命令如下。注意,PyTorch和Torchvision的版本是锁死的,别自己换。
pip install torch==1.10.1+cu111 torchvision==0.11.2+cu111 torchaudio==0.10.1 -f https://download.pytorch.org/whl/torch_stable.html安装成功后,强烈建议写个测试脚本验证一下:
import torch print(torch.__version__) # 应该输出 1.10.1+cu111 print(torch.cuda.is_available()) # 应该输出 True print(torch.cuda.get_device_name(0)) # 输出你的显卡型号,比如 RTX 3090接下来安装项目所需的Python包。先别急着装requirements.txt,因为里面有些包的版本可能已经过时了。我们先手动安装几个关键的。
pip install opencv-python pandas ipdb setuptools==59.5.0 -i https://pypi.tuna.tsinghua.edu.cn/simple重点来了:spconv的安装。spconv是一个用于稀疏卷积计算的库,对3D检测至关重要,但也是版本冲突的重灾区。对于PyTorch 1.10 + CUDA 11.1,必须使用spconv-cu111==2.1.21。如果你用其他CUDA版本,可以去spconv的GitHub仓库找对应的wheel文件。
pip install spconv-cu111==2.1.21 -i https://pypi.tuna.tsinghua.edu.cn/simple最后,安装nuScenes数据集的处理工具包。
pip install nuscenes-devkit -i https://pypi.tuna.tsinghua.edu.cn/simple1.3 安装OpenMMLab全家桶
这是MMDetection3D的生态基础,安装顺序有讲究。首先安装mmcv-full,这是OpenMMLab的计算机视觉基础库。切记,一定要根据你的PyTorch和CUDA版本选择对应的mmcv-full版本。官网提供了查询链接,我这里给出PyTorch 1.10.1 + CUDA 11.1的组合命令。
pip install mmcv-full==1.4.0 -f https://download.openmmlab.com/mmcv/dist/cu111/torch1.10.1/index.html接着安装MMDetection(2D检测库)和MMSegmentation(分割库),IS-Fusion的某些模块会用到它们。
pip install mmdet==2.14.0 mmsegmentation==0.14.1 -i https://pypi.tuna.tsinghua.edu.cn/simple现在,进入项目目录,安装一些自定义的操作符(Ops)。首先编译TorchEx。
cd mmdet3d/ops/TorchEx python setup.py develop cd ../../.. # 回到IS-Fusion根目录最后,以“开发模式”安装MMDetection3D框架本身。-v是显示详细安装信息,-e .代表“可编辑模式”,这样你修改源码后无需重新安装。
pip install -v -e .如果一切顺利,没有报红字错误,那么恭喜你,最磨人的环境搭建部分已经完成了。你可以尝试导入一下关键模块做个简单验证:python -c "import mmdet3d; print(mmdet3d.__version__)"。
2. 数据集准备:nuScenes数据预处理详解
环境好了,接下来就得喂数据了。nuScenes是一个大型自动驾驶多模态数据集,包含了激光雷达、6个摄像头、雷达等多种传感器数据。原始数据不能直接扔给模型,需要经过一系列预处理,转换成.pkl等格式。这个过程比较耗时,但理解它对你后续调试非常有帮助。
2.1 下载与组织数据集结构
首先,你需要去nuScenes官网注册并下载数据集。对于初次实验,我强烈建议先使用Mini版本(v1.0-mini),它只有完整版的十分之一大小,下载快,处理快,能让你快速跑通整个流程验证环境。把下载好的v1.0-mini文件夹放在一个空间充足的路径下,比如/data/nuscenes/。
然后,我们需要在IS-Fusion项目目录下创建软链接,这是一种不占用额外空间,又能让代码找到数据的好方法。在IS-Fusion根目录下执行:
mkdir -p data/nuscenes ln -s /你的路径/nuscenes/v1.0-mini ./data/nuscenes/v1.0-mini这样,项目里的data/nuscenes/v1.0-mini就指向了你实际的数据位置。你的目录结构应该看起来像这样:
IS-Fusion/ ├── configs/ ├── data/ │ └── nuscenes/ │ └── v1.0-mini/ (这是一个软链接) │ ├── samples/ │ ├── sweeps/ │ ├── maps/ │ └── v1.0-mini.json ├── mmdet3d/ └── ...2.2 运行数据创建脚本
IS-Fusion提供了数据预处理脚本tools/create_data.py。但直接运行可能会因为路径问题报错。更稳妥的做法是参考原始文章,自己写一个shell脚本。在项目根目录下创建一个create_data.sh文件,内容如下:
#!/bin/bash CREATE_DATA='tools/create_data.py' DATASET_NAME='nuscenes' ROOT_PATH_PROJ=$(pwd) # 获取当前项目根目录路径 ROOT_PATH="--root-path ${ROOT_PATH_PROJ}/data/nuscenes/v1.0-mini" OUT_DIR="--out-dir ${ROOT_PATH_PROJ}/data/nuscenes/v1.0-mini" EXTRA_TAG='--extra-tag nuscenes' VERSION='--version v1.0-mini' python ${CREATE_DATA} ${DATASET_NAME} ${ROOT_PATH} ${OUT_DIR} ${EXTRA_TAG} ${VERSION}给脚本加上执行权限并运行:
chmod +x tools/create_data.sh bash tools/create_data.sh这个脚本会干很多事情:它会解析原始的.json标注文件,计算每个点云场景的信息,生成训练和验证所需的.pkl文件(如nuscenes_infos_train.pkl),以及数据库采样文件nuscenes_dbinfos_train.pkl。这个过程可能会持续几分钟到十几分钟,取决于你的CPU和磁盘速度。看到终端打印出“Data preparation finished”之类的信息,就表示成功了。
关键检查点:处理完成后,去data/nuscenes/v1.0-mini/目录下看看,应该新生成了几个.pkl文件。如果只有原始的.json文件,说明预处理没成功,需要检查错误信息,常见问题是指定的数据路径不对。
3. 模型训练:配置文件调优与实战
数据就绪,终于到了最激动人心的训练环节。IS-Fusion的配置文件是它的“大脑”,所有模型结构、训练策略、数据流水线都在这里定义。直接使用默认配置可能不适合你的硬件或目标,所以我们必须学会“魔改”它。
3.1 下载预训练模型
在深度学习里,站在巨人的肩膀上总是好的。IS-Fusion的作者提供了在nuScenes上预训练好的模型(比如IS-Fusion_epoch_10.pth)。下载它有两个好处:一是可以用于后续的测试和推理,快速看效果;二是我们可以用它进行微调(Fine-tuning),这比从零训练快得多,效果也通常更好。
你可以从论文作者的GitHub Release页面或者OpenMMLab的Model Zoo找到下载链接。下载后,在项目根目录创建一个ckpts/文件夹,把模型文件放进去。这样,在配置文件中就可以通过load_from = 'ckpts/IS-Fusion_epoch_10.pth'来加载它了。
3.2 深度解析与修改配置文件
配置文件configs/isfusion/isfusion_0075voxel.py是重中之重。我们打开它,逐部分理解并调整。我把它分成几个关键模块来讲。
第一部分:基础参数与模型结构文件开头定义了数据类别、体素大小、点云范围等。这些参数决定了模型如何“看”世界。
voxel_size = [0.075, 0.075, 0.2]:这是将连续的点云空间离散化成体素网格的尺寸。[0.075, 0.075]意味着在X和Y平面上,每0.075米划分为一个格子,0.2是Z轴高度。调小它(如[0.05, 0.05, 0.1])会得到更精细的体素,提升对小物体的检测能力,但会急剧增加内存消耗和计算量。如果你的显卡显存小于16GB,轻易不要动。point_cloud_range = [-54, -54, -5, 54, 54, 3]:这定义了模型处理的点云范围,格式是[x_min, y_min, z_min, x_max, y_max, z_max]。它裁剪掉了远处和过高/过低的点。这个范围需要和voxel_size一起计算bev_size(鸟瞰图特征图大小)。公式是:voxel_shape = int((range_max - range_min) / voxel_size)。这里x方向从-54到54,共108米,除以0.075得到1440。bev_size = voxel_shape // out_size_factor(下采样倍数),这直接影响了后续特征图的分辨率。
第二部分:数据流水线(Pipeline)这是数据进入模型前经历的“预处理流水线”,在train_pipeline和test_pipeline里定义。有几个关键操作值得关注:
ObjectSampleV2:数据增强策略,从数据集中采样一些真实物体(如车辆、行人)放到当前场景中,增加数据的多样性和复杂性。里面的db_sampler配置了采样规则,比如每类物体采样的数量(sample_groups)。GlobalRotScaleTransV2和RandomFlip3DV2:全局的旋转、缩放、平移和翻转,是增强模型泛化能力的核心手段。resize_lim和rot_lim定义了增强的强度。ImageAug3D:针对图像的数据增强,包括调整尺寸、随机裁剪、旋转等。注意final_dim需要和模型图像分支的输入尺寸匹配。ModalMask3D:这是IS-Fusion的一个特色,在训练早期随机“掩盖”掉图像或点云模态,强迫模型学习单一模态的特征,后期再融合,据说能提升融合效果。
第三部分:训练超参数在文件靠后的data、optimizer等字典里。
samples_per_gpu=2:这是批大小(Batch Size)。这是最影响显存占用的参数。如果训练时出现“CUDA out of memory”错误,首先把它改成1。但批大小变小可能会影响训练稳定性,可能需要同时调小学习率。workers_per_gpu=6:数据加载的进程数。如果你的CPU核心多,可以调高这个值(比如8或16)来加速数据读取,防止GPU等数据。但设得太高可能会占满内存。optimizer里的lr=0.0001:学习率。如果你用了预训练模型进行微调,通常可以使用更小的学习率,比如5e-5。如果是从头训练,这个值可以保持或稍大。runner里的max_epochs=10:总训练轮数。对于nuScenes mini数据集,10个epoch可能就够了。对于完整数据集,通常需要20个epoch甚至更多。
修改实战:假设我们显卡是RTX 4090 24G,想尝试更精细的体素。我们可以把voxel_size改为[0.05, 0.05, 0.1],同时必须重新计算point_cloud_range和voxel_size推导出的bev_size等参数,否则会报维度错误。这是一个连锁反应,新手建议先保持默认。
3.3 启动训练与监控
配置文件改好后,我们写一个训练脚本train_demo.sh来启动训练。
#!/bin/bash TEST_PY='tools/train.py' CONFIG_FILE='configs/isfusion/isfusion_0075voxel.py' python ${TEST_PY} ${CONFIG_FILE} --work-dir work_dirs/isfusion_exp1这里--work-dir指定了输出目录,所有训练日志、模型检查点(checkpoint)、TensorBoard文件都会保存在这里。运行它:
bash tools/train_demo.sh如果一切正常,你会看到终端开始滚动输出日志,包括当前epoch、迭代次数、损失值等。重点观察初始的几个迭代:如果损失值从非常巨大的数开始快速下降,一般是正常的;如果损失值是NaN,那可能是学习率太高、数据有问题或模型初始化失败。
打开另一个终端,进入你的work_dirs/isfusion_exp1目录,可以使用TensorBoard来可视化训练过程:
tensorboard --logdir ./然后在浏览器打开localhost:6006,你就能看到损失曲线、学习率变化等,非常直观。这是监控训练状态、判断模型是否收敛(损失不再下降)或者过拟合(训练损失下降但验证损失上升)的必备工具。
4. 模型测试与性能评估
模型训练完成后(或者你下载了预训练模型),我们需要评估它在验证集上的表现。nuScenes数据集有自己的官方评估指标,比如NDS(NuScenes Detection Score)和mAP(mean Average Precision),这些指标会综合考量检测的精度、位置、尺寸、方向、速度等多个维度。
4.1 编写测试脚本
创建一个测试脚本test_demo.sh。你需要指定配置文件、训练好的模型权重文件,以及评估指标。
#!/bin/bash TEST_PY='tools/test.py' CONFIG_FILE='configs/isfusion/isfusion_0075voxel.py' # 使用我们刚刚训练好的最后一个检查点 PTH='work_dirs/isfusion_exp1/latest.pth' # 或者使用官方预训练模型 # PTH='ckpts/IS-Fusion_epoch_10.pth' python ${TEST_PY} ${CONFIG_FILE} ${PTH} --eval bbox --eval-options 'jsonfile_prefix=./results/isfusion_exp1'这里--eval bbox表示进行3D边界框的评估。--eval-options可以传递更多参数,比如jsonfile_prefix指定了结果文件的输出前缀。运行这个脚本:
bash tools/test_demo.sh评估过程会遍历整个验证集,进行推理并计算指标。这个过程会比较慢,因为模型需要对每个样本进行前向传播。完成后,终端会打印出详细的评估表格,包括每个类别(Car, Pedestrian等)的AP(平均精度)和ATE、ASE、AOE等各项误差,以及最终的综合分数NDS。
4.2 结果分析与常见问题排查
拿到结果后,怎么判断模型好坏呢?在nuScenes上,一个在完整数据集上训练良好的IS-Fusion模型,NDS分数可以达到0.45以上,mAP在0.35以上。如果你用的是mini数据集,分数会低很多,这很正常,因为数据量小。
如果结果非常差(比如NDS低于0.1),可能是以下原因:
- 数据预处理失败:这是最常见的原因。确保
nuscenes_infos_val.pkl等文件正确生成,并且路径在配置文件中设置正确。 - 配置文件错误:检查
data_root、ann_file的路径。特别是如果你移动了数据或软链接,这里的路径可能需要更新为绝对路径。 - 模型权重未加载:检查
load_from参数是否指向了正确的.pth文件。如果这个参数被注释掉或路径错误,模型就是随机初始化的,效果肯定很差。 - 类别不匹配:确认配置文件中的
class_names列表和数据集标注的类别完全一致,顺序都不能错。 - 硬件/版本隐式错误:有时候CUDA、PyTorch、spconv的版本不兼容会导致计算出现静默错误,结果看似正常但全是乱码。可以尝试用预训练模型在单个样本上做一次前向传播,看看输出的边界框坐标是否在合理范围内(应该在点云范围内)。
调试时,一个有用的技巧是使用--show或--show-dir参数进行可视化。修改测试脚本,增加--show-dir ./vis_results,模型会输出一些检测结果的可视化图片或点云,你可以直观地看到模型预测的框和真实框的对比,这对于定位问题非常有帮助。
最后,记得环境配置和模型训练是个系统工程,耐心和细心最重要。每次修改配置后,不妨先用小批量数据(比如在配置文件中设置data = dict(samples_per_gpu=1, workers_per_gpu=2)并只取前几个样本)跑一个迭代,确保没有语法或维度错误,再开始长时间的全量训练。