复现pointrcnn
在复现pointrcnn过程中,最容易报错的地方是编译cuda代码,github的issue中大多是在强调gcc和pytorch的版本问题,但我用的是3080显卡,只支持>=cuda11.0,所以安装低版本的pytorch还是会报错,以下是我复现的过程。
1.配置环境
- ubuntu:16.04
- gcc:5.4.0
- 显卡驱动:470.63.01
- cuda:11.0
- cudnn:8.0.1
- pytorch:1.7.1+cu11
ubuntu和gcc
ubuntu18.04是安装不了gcc5.4.0的,所以我一开始脑子糊涂就重装了系统,跑通之后感觉重装系统好像没必要。所以如果你的系统不是ubuntu16.04,可以先不考虑重装系统和跟换gcc版本(但我没试过,如果你成功了,可以写在评论区)。
查看gcc版本
gcc -v
显卡驱动
显卡驱动是向下兼容cuda的,所以越高越好
cuda
因为3080的算力是8.6,而cuda10.2只支持到7.5,所以必须安装cuda11.0以上的版本
cudnn
这个很少出问题,只要和cuda匹配就行
pytorch
安装pytorch时要注意它的cudatoolkit版本,cudatoolkit的版本要<=cuda版本
conda install pytorch==1.7.1 torchvision==0.8.2 torchaudio==0.7.2 cudatoolkit=11.0 -c pytorch
2.改代码
主要是改了三个模块的cpp代码,为避免麻烦,可以直接在gitee中下载后替换相应文件。
PointRCNN/pointnet2_lib/pointnet2/src
PointRCNN/lib/utils/iou3d/src
PointRCNN/lib/utils/roipool3d/src
1. 将所有cpp文件中以下代码替换
#define CHECK_CUDA(x) AT_CHECK(x.type().is_cuda(), #x, " must be a CUDAtensor ")
#define CHECK_CONTIGUOUS(x) AT_CHECK(x.is_contiguous(), #x, " must be contiguous ")
#define CHECK_INPUT(x) CHECK_CUDA(x);CHECK_CONTIGUOUS(x)
替换为
#define CHECK_CUDA(x) AT_ASSERTM(x.type().is_cuda(), #x " must be a CUDA tensor")
#define CHECK_CONTIGUOUS(x) AT_ASSERTM(x.is_contiguous(), #x " must be contiguous")
#define CHECK_INPUT(x) CHECK_CUDA(x); CHECK_CONTIGUOUS(x)
这一段代码就是检查输入的数据类型是否为tensor,只会报warning,我还在其他cpp中文件中加入了这些代码,可以不改的。
2.将所有cpp文件中以下代码注释掉
extern THCState *state;
和
cudaStream_t stream = THCState_getCurrentStream(state);
3.将所有cpp文件中调用核函数的参数stream替换为
c10::cuda::getCurrentCUDAStream()
4.编译
1.直接编译
sh build_and_install.sh
会报错
nvcc fatal : Unsupported gpu architecture 'compute_86'
ninja: build stopped: subcommand failed.
2.降低算力要求
这个报错信息是指不支持当前算力为8.6的gpu,执行以下命令解决
export TORCH_CUDA_ARCH_LIST="8.0"
但我之后还遇到了一个问题
ImportError: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.22‘ not found
解决办法参考,更为全面,以下是我个人的实践过程
首先这个报错就是说找不到GLIBCXX_3.4.22这个文件
3.补充GLIBCXX_3.4.22文件
(1)使用指令先看下目前都有哪些版本的
strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX
(2)查找有没有更高版本的libstdc++.so,参考的那个查找太耗时了,所以我就直接在anaconda/lib文件夹下找libstdc++.so,如下
然后找到libstdc++.so.6.0.26文件所在位置
我的为/home/ld/anaconda3/lib/libstdc++.so.6.0.26
(3)将文件复制以下
sudo cp /home/ld/anaconda3/lib/libstdc++.so.6.0.26 /usr/lib/x86_64-linux-gnu/
(4)然后删除原来的软链接
sudo rm /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(5)建立新的软链接(sudo ln -s 复制的文件位置 软链接名)
sudo ln -s /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.26 /usr/lib/x86_64-linux-gnu/libstdc++.so.6
4.再次编译
sh build_and_install.sh
5. 准备数据及和权重
(1)将数据集排布如下
PointRCNN
├── data
│ ├── KITTI
│ │ ├── ImageSets
│ │ ├── object
│ │ │ ├──training
│ │ │ ├──calib & velodyne & label_2 & image_2 & (optional: planes)
│ │ │ ├──testing
│ │ │ ├──calib & velodyne & image_2
├── lib
├── pointnet2_lib
├── tools
将权重文件PointRCNN.pth放在tools文件夹下
(2)进行测试评估
python eval_rcnn.py --cfg_file cfgs/default.yaml --ckpt PointRCNN.pth --batch_size 1 --eval_mode rcnn --set RPN.LOC_XZ_FINE False
(3)进行训练
python train_rcnn.py --cfg_file cfgs/default.yaml --batch_size 16 --train_mode rpn --epochs 200