【实验记录】使用 CenterNet(Objects as Points)训练数据集

论文:https://arxiv.org/abs/1904.07850
代码:https://github.com/xingyizhou/CenterNet


1. 环境配置

官方配置文档:CenterNet/readme/INSTALL.md

官方在 这里 给的环境配置是 PyTorch 0.4.1 + CUDA 9.0 + CUDNN 7.1,但是我按照这个配出来的环境在跑训练时报了这个错:

RuntimeError: cuda runtime error (11) : invalid argument at /opt/conda/conda-bld/pytorch_1535491974311/work/aten/src/THC/THCGeneral.cpp:663

(不得不说这个错误非常气人!!)最开始找到的原因说 cuda 和 pytorch 版本有问题,要升级到 cuda 10.0 以上,但是 cuda 10.0 支持的 PyTorch 版本必须在 1.3.0 以上,这又导致代码无法支持 PyTorch 1.3.0,绕了一圈又绕回来了!最后终于找到了相关解决方案:参考1参考 2。也就是需要 CUDA 9.2 而不是 9.0!所以我的环境配置和官方这点不太一样,仅供参考。

  • NVIDIA GeForce RTX 2080 Ti
  • Ubuntu 16.04
  • Python 3.6
  • PyTorch 0.4.1
  • CUDA 9.2
  • CUDNN 7.5.1
  • Numpy 1.16.1

环境配置过程:

# 创建并激活 conda 环境
conda create --name CenterNet python=3.6
conda activate CenterNet

# 安装PyTorch
conda install pytorch=0.4.1 torchvision cudatoolkit=9.2 -c pytorch

# 禁用 cudnn batch normalization(作者说这里如果不禁用会导致训练时出问题)
PYTORCH=/data1/zyy/usr/local/anaconda/envs/CenterNet/lib/python3.6/site-packages/  # 这里根据自己的路径修改
# for pytorch v0.4.0
sed -i "1194s/torch\.backends\.cudnn\.enabled/False/g" ${PYTORCH}/torch/nn/functional.py
# for pytorch v0.4.1(上面安装的是 pytorch 0.4.1,所以这一步输入下面这句代码)
sed -i "1254s/torch\.backends\.cudnn\.enabled/False/g" ${PYTORCH}/torch/nn/functional.py
# 对于其他 pytoch 版本,可以直接修改 torch/nn/functional.py 文件中的 torch.backends.cudnn.enabled,将其置为 False 即可

# 安装 COCO API
COCOAPI=/data1/zyy/code/centernet/cocoapi   # 自己修改想要存放的路径
git clone https://github.com/cocodataset/cocoapi.git $COCOAPI
cd $COCOAPI/PythonAPI
make   # 报错记录1
python setup.py install --user  # 报错记录2

# clone CenterNet repo
CenterNet_ROOT=/data1/zyy/code/centernet/CenterNet  # 自己修改想要存放的路径
git clone https://github.com/xingyizhou/CenterNet $CenterNet_ROOT  # 报错记录3

# 安装依赖
cd CenterNet
pip install -r requirements.txt

# 编译可变形卷积(DCNv2)
cd $CenterNet_ROOT/src/lib/models/networks/DCNv2
./make.sh  # 报错记录4

# [可选] 只有使用extremenet或多尺度测试时才需要编译NMS
cd $CenterNet_ROOT/src/lib/external
make

【报错记录1】 安装 COCO API 时,执行 make 报错

gcc: error: pycocotools/_mask.c: 没有那个文件或目录

解决方法:安装 Cython。编译 COCO API 需要依赖库 Cython,安装完成后重新 make 即可。编译完成后,执行 import pycocotools,不报错即成功。

pip3 install cython

【报错记录2】 执行 setup.py 报错

error: Setup script exited with 
Beginning with Matplotlib 3.4, Python 3.7 or above is required.
You are using Python 3.6.13.

解决方法:原因是自动安装时安装的都是最新版本,自动安装的是 Matplotlib 3.4,需要 Python 至少在 3.7 以上,但我们的 Python 是 3.6 的,而不想升级 Python 版本,只需要降低 Matplotlib 版本即可。查看 setup.py,要求 Matplotlib >=2.1.0,因此我们手动安装 Matplotlib 即可。完成后重新执行 setup.py。

conda install matplotlib=2.1.0

【报错记录3】 git clone 代码超时

fatal: unable to access 'https://github.com/xingyizhou/CenterNet/': Failed to connect to github.com port 443: 连接超时

解决方法:输入下面两条命令

git config --global http.proxy
git config --global --unset http.proxy

【报错记录4】 编译 DCNv2 报错

./make.sh: 行 5: nvcc: 未找到命令   # 问题1
bash: ./make.sh: 权限不够    # 问题2

解决方法:1)问题1,是因为没有安装 nvcc,在管理员权限下执行 apt-get install nvidia-cuda-toolkit;2)问题2,加个执行权限,执行 chmod +x ./make.sh

# 问题3
dcn_v2_im2col_cuda_double.cu(248): error: no instance of overloaded function "atomicAdd" matches the argument list
            argument types are: (double *, double)
1 error detected in the compilation of "/tmp/tmpxft_00001e56_00000000-5_dcn_v2_im2col_cuda_double.cpp4.ii".
dcn_v2_psroi_pooling_cuda_double.cu(247): error: no instance of overloaded function "atomicAdd" matches the argument list
            argument types are: (double *, double)
dcn_v2_psroi_pooling_cuda_double.cu(248): error: no instance of overloaded function "atomicAdd" matches the argument list
            argument types are: (double *, double)
dcn_v2_psroi_pooling_cuda_double.cu(249): error: no instance of overloaded function "atomicAdd" matches the argument list
            argument types are: (double *, double)
dcn_v2_psroi_pooling_cuda_double.cu(250): error: no instance of overloaded function "atomicAdd" matches the argument list
            argument types are: (double *, double)
dcn_v2_psroi_pooling_cuda_double.cu(265): error: no instance of overloaded function "atomicAdd" matches the argument list
            argument types are: (double *, double)
dcn_v2_psroi_pooling_cuda_double.cu(266): error: no instance of overloaded function "atomicAdd" matches the argument list
            argument types are: (double *, double)
6 errors detected in the compilation of "/tmp/tmpxft_00001e9d_00000000-5_dcn_v2_psroi_pooling_cuda_double.cpp4.ii".

gcc: error: /data1/zyy/code/centernet/CenterNet/src/lib/models/networks/DCNv2/src/cuda/dcn_v2_im2col_cuda_double.cu.o: 没有那个文件或目录
gcc: error: /data1/zyy/code/centernet/CenterNet/src/lib/models/networks/DCNv2/src/cuda/dcn_v2_psroi_pooling_cuda_double.cu.o: 没有那个文件或目录

解决方法:还是 CUDA 版本问题,这是之前环境没配好的时候出现的问题,如果按照前面的 CUDA 9.2 + PyTorch 0.4.1 应该不会遇到。

2. 执行 demo

model zoo 下载训练好的检测模型 ctdet_coco_dla_2x,放在 CenterNet/models/ 文件夹下。执行 demo.py 可以测试一下检测效果:

cd path/to/CenterNet/src
python demo.py ctdet --demo ../images/17790319373_bd19b24cfc_k.jpg --load_model ../models/ctdet_coco_dla_2x.pth

上面选取了 repo 里自带的一张图片,检测效果如下:
在这里插入图片描述
执行 demo.py 时可能遇到 RuntimeError: CUDA error: out of memory 这个问题,查看了相关 issues70,没找到根本原因,但一个可行的解决方法是将 CenterNet/src/lib/opts.py 的第 338 行 [512,512] 改成 [480,480] 或者 [640,640] ,都可以解决 out of memory 这个问题。

在这里插入图片描述
在命令中加上 --debug 2,可以看到中央点的 heatmap:

python demo.py ctdet --debug 2 --demo ../images/17790319373_bd19b24cfc_k.jpg --load_model ../models/ctdet_coco_dla_2x.pth

在这里插入图片描述

3. 数据准备 & 训练 & 测试

3.1 数据集

官方文档:[1] DATA.md;[2] DEVELOP.md

  1. 第一步:首先将自己的数据标注处理为 COCO 数据集的格式,标注细节参考:COCO数据集标注&代码
  2. 第二步:在 CenterNet 代码 src/lib/datasets/dataset 目录下添加数据集的处理文件,可以直接把 src/lib/datasets/dataset/coco.py 的内容复制过来,修改一下数据集的名称、类别等信息即可。
  3. 第三步:将你的数据集注册到 src/lib/datasets/dataset_factory。比如新增 from .dataset.refuge import Refugedataset_factory = {'refuge': Refuge}
  4. 第四步:在 src/lib/utils/debugger.py 文件中注册你的数据集,比如在 Debugger 中添加 elif dataset == 'refuge': self.names = refuge_class_name,和 refuge_class_name = ['disc', 'cup']

数据集组织如下:

CenterNet_ROOT
|-- data
`-- |-- refuge
    `-- |-- annotations
        |   |-- train.json
        |   |-- val.json
        |   |-- test.json
        |-- images
        |   |-- train
        |   |-- val
        `-- |-- test

3.2 训练

官方文档:GETTING_STARTED.md

执行训练命令:

python main.py ctdet --dataset refuge --exp_id refuge_090109 --num_epochs 140 --batch_size 16 --master_batch 8 --lr 1.25e-4  --gpus 0,1

exp_id:实验 id 号,可以自行设定,在训练意外中断时,可以利用同样的 exp_id 并在上面的命令行加入 --resume 继续训练。master_size:对于多 GPU 训练,默认情况下 batch size 会平均分配在每个 GPU 上;否则,可以通过 master_batch 来设置放在主 GPU 上的 batch 大小,且 master_batch 必须小于 batch_size。训练更详细的设定可以在 opts.py 中查看。

执行训练报错:

[1] ValueError: numpy.ufunc size changed, may indicate binary incompatibility. Expected 216 from C header, got 192 from PyObject

解决方法:numpy 版本低了,目前是 1.15.1,执行 conda install numpy=1.16.1 更换到 1.16.1。

[2] RuntimeError: cuda runtime error (11) : invalid argument at /opt/conda/conda-bld/pytorch_1535491974311/work/aten/src/THC/THCGeneral.cpp:663

解决方法:就是在记录开头提到的问题,环境更换为 CUDA 9.2 + PyTorch 0.4.1 + CUDNN 7.5.1。

成功执行训练以后,显示如下:

train: [1][24/25]|Tot: 0:00:25 |ETA: 0:00:01 |loss 17.4448 |hm_loss 15.6720 |wh_loss 14.7425 |off_loss 0.2985 |Data 0.003s(0.066s) |Net 1.015s

参数含义:第一个位置表示该阶段是 train 还是 validation,这里显示为 train。接着 [1] 表示当前执行到第几个 epoch,[24/25] 表示 [当前在第24个iteration / 共25个iteration],[Tot] 表示一个 epoch 的训练时常,[ETA] 表示当前 epoch 的剩余训练时间。后面的 [loss] 均表示损失值。
在这里插入图片描述
训练的模型就存放在 CenterNet/exp/ctdet/refuge_090109 目录下。

3.3 测试

执行测试命令:

python test.py ctdet --dataset refuge --exp_id refuge_090109_test --load_model ../exp/ctdet/refuge_090109/model_best.pth --K 2 --gpus 0,1
# K 规定了测试时能够预测的最大目标个数

【2021/9/1】

  • 修改 test.pybase_detector.pydetectors/ctdet.py 代码逻辑,令测试过程可以直接保存检测结果。
  • 修改了测试结果保存路径的指定问题,根据 --load_model 将可视化检测结果保存在相应的文件夹下。
python test.py ctdet --debug 0 --dataset refuge --load_model ../exp/ctdet/refuge_090109/model_best.pth --K 2 --gpus 0,1 --trainval
# trainval用于区分使用验证集还是测试集来做测试,这里意味着在测试集上

执行测试报错:

RuntimeError: CUDA error: out of memory

解决方法:和执行 demo.py 的 bug 一摸一样,这里把 CenterNet/src/lib/datasets/dataset/coco.py 的第 15 行 default_resolution = [512, 512] 改为 [640, 640] 或者 [480, 480] 即可。

测试结果
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不吃饭就会放大招

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值