centernet 训练自己数据集ubuntu16.04, pytorch1.1.0,cuda10.0
本文官方链接:https://www.cnblogs.com/yanghailin/p/13977665.html
Centernet github地址:
https://github.com/xingyizhou/CenterNet
加qq群一起学习讨论交流:1020395892
centernet论文与实验剖析
https://www.cnblogs.com/yanghailin/p/14034984.html
1.环境配置
1.1 torch安装
conda create -n centernet_2020 python=3.7
source activate centernet_2020
conda install pytorch=1.1 torchvision cudatoolkit=10.0 -c pytorch
有时候conda下载失败或者很慢,可以试试下面的命令,改下版本号或者torchvision不需要安装就去掉:
pip install torch==1.0.0 torchvision==0.2.1 -i https://mirror.baidu.com/pypi/simple
1.2 依赖安装
cd CenterNet-master
pip install -r requirements.txt
1.3 COCOAPI安装
git clone https://github.com/cocodataset/cocoapi.git
cd cocoapi/PythonAPI
make
python setup.py install --user
1.4 DCNV2编译
cd $CenterNet_ROOT/src/lib/models/networks/DCNv2
./make.sh
报错:
Traceback (most recent call last):
File "build.py", line 3, in <module>
from torch.utils.ffi import create_extension
File "/data_1/Anaconda1105/envs/centernet_2020/lib/python3.7/site-packages/torch/utils/ffi/__init__.py", line 1, in <module>
raise ImportError("torch.utils.ffi is deprecated. Please use cpp extensions instead.")
ImportError: torch.utils.ffi is deprecated. Please use cpp extensions instead.
Traceback (most recent call last):
File "build_double.py", line 3, in <module>
from torch.utils.ffi import create_extension
File "/data_1/Anaconda1105/envs/centernet_2020/lib/python3.7/site-packages/torch/utils/ffi/__init__.py", line 1, in <module>
raise ImportError("torch.utils.ffi is deprecated. Please use cpp extensions instead.")
ImportError: torch.utils.ffi is deprecated. Please use cpp extensions instead.
因为pytorch1.1torch.utils.ffi已经弃用了。
下载最新的DCNV2
在目录./CenterNet-master/src/lib/models/下
mv DCNv2 DCNv2-src
git clone https://github.com/CharlesShang/DCNv2
cd DCNv2
./make.sh
编译成功最下面会打印
Processing dependencies for DCNv20.1
Finished processing dependencies for DCNv20.1
由于不需要nms,就不需要编译external
(这里有点儿好玩,两组==之间会使得文字加颜色)
2.数据准备:
2.1 voc数据文件夹介绍
我的数据是voc格式的,需要转成coco格式
Annotations #存放的是标注好的xml
JPEGImages #存放的是图片
两个文件夹下面的文件数量需要一样!
2.2 voc2coco_2020.py脚本
转voc只需要Annotations 里面的xml转成coco格式的一个文件json
打开voc2coco_2020.py脚本,最下面一行,只需要修改xml_path为自己文件夹路径就好.
voc2coco_2020.py---戳我
跑完,会在当前目录下面生成一个train.json文件。由于很大是打不开的。但是我们是需要打开查看类别信息,
因为在这个json下面记录了类别信息。
法1:是直接cat train.json在终端上面显示,如果类别信息在最后就可以看到,如果不在最后就需要看法2.
法2:装一个jq插件才能打开。具体参考:
https://blog.csdn.net/yang332233/article/details/97205120?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160515033819725222412279%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=160515033819725222412279&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_v1~rank_blog_v1-2-97205120.pc_v1_rank_blog_v1&utm_term=coco&spm=1018.2118.3001.4450
执行
cat train.json |jq . >train_jq.json
然后可以直接打开train_jq.json,拉到最下面查看,类别和标签:
"categories": [
{
"supercategory": "none",
"id": 1,
"name": "car"
},
{
"supercategory": "none",
"id": 2,
"name": "bird"
},
{
"supercategory": "none",
"id": 3,
"name": "dog"
}
。。。
这个需要填写到代码里面。这里需要注意一下,因为还有个测试文件,一般情况下也是安装上面的流程来生成test.json或者val.json.这里就有个问题就是这个脚本是根据xml来生成json,遇到一个新的类别就加到后面,test里面的好多xml,按照当前的文件夹xml来的。所以生成的类别可能会和train.json里面的顺序不一样!
我是干脆把train.json复制重命名为test.json或者val.json。然后跑训练的时候让他不测试(不测试修改的地方见3.4),因为我们有自己的测试数据集和测试脚本,离线测试。
3.训练自己数据代码修改
3.1数据存放
当我们生成json文件之后,来到CenterNet这个工程里,在CenterNet-master/data文件夹下新建一个文件夹,名字就是你数据集的名字(例如取名:MyDataTest)
再在这个文件夹里面建两个文件夹(annotations里面存放的是我们之前生成的json文件;名字随意,比如train.json,test.json,val.json,下面代码里会改(见3.2.7),images存放的是所有的图片,包括训练测试验证三个,所有的)
3.2 自己的数据类---复制coco.py修改
1.在CenterNet-master/src/lib/datasets/dataset/文件夹里面,复制coco.py并从命名为my_test.py
打开my_test.py修改:
3.2.1 line13:class COCO修改成class my_test
3.2.2 line14:num_classes = 13 #注意这里不包含背景类
3.2.3 line15:default_resolution = [512, 512] 修改自己需要的训练图片大小
3.2.4 line16,18:均值方差改自己的,或者也可以不改
3.2.5 Line22:super(COCO, self).init()里面的COCO换成自己的类名my_test
3.2.6 Line23,24:修改自己的数据路径
self.data_dir = os.path.join(opt.data_dir, 'coco')
self.img_dir = os.path.join(self.data_dir, '{}2017'.format(split))
改成自己数据文件夹名字如下:
self.data_dir = os.path.join(opt.data_dir, 'MyDataTest')##刚刚取的数据文件夹名字
self.img_dir = os.path.join(self.data_dir, 'images')
3.2.7 line26-37:修改自己json文件名:
if split == 'test':
self.annot_path = os.path.join(
self.data_dir, 'annotations',
'test.json').format(split)
else:
if opt.task == 'exdet':
self.annot_path = os.path.join(
self.data_dir, 'annotations',
'train.json').format(split)
else:
self.annot_path = os.path.join(
self.data_dir, 'annotations',
'train.json').format(split)
3.2.8 line39:类别名字和类别id改成自己的
self.class_name = [
'__background__', 'class_1', 'class_2', 'class_3', 'class_4', 'class_5',
'class_6', 'class_7', 'class_8', 'class_9', 'class_10', 'class_11',
'class_12', 'class_13']
self._valid_ids = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,12, 13]
3.3 dataset_factory.py修改
将数据集加入CenterNet-master/src/lib/datasets/dataset_factory.py
Line14 添加:from .dataset.my_test import my_test
Line29添加: ‘my_test':my_test
格式为 '你之前创建的Python文件的名字':你自己类(数据集)的名字
3.4 /src/lib/opts.py修改
3.4.1 加入自己数据集
self.parser.add_argument('--dataset', default='coco',
help='coco | kitti | coco_hp | pascal')
修改成:
self.parser.add_argument('--dataset', default='my_test',
help='coco | kitti | coco_hp | pascal |my_test')
3.4.2 line336: 修改ctdet任务使用的默认数据集为新添加的数据集,如下(修改分辨率,类别数,均值,方差,数据集名字):
'ctdet': {'default_resolution': [512, 512], 'num_classes': 37,
'mean': [0.408, 0.447, 0.470], 'std': [0.289, 0.274, 0.278],
'dataset': 'objvehicle_small'},
3.4.3几个重要的参数可供选择修改
此外,opts里面还有几个重要的参数可供选择修改:
'--print_iter', type=int, default=0, #默认0,可以给出数字每隔多少打印
('--val_intervals', type=int, default=5, #这里默认5个epoch测试,不想测试的话调500000
help='number of epochs to run validation.')
骨干网络的选择:
self.parser.add_argument('--arch', default='dla_34',
help='model architecture. Currently tested'
'res_18 | res_101 | resdcn_18 | resdcn_101 |'
'dlav0_34 | dla_34 | hourglass')
注意,这里选择的骨干网络有的会遇到下载预训练模型失败的问题,原因在于作者那里没有写好,需要改下hash什么的。
3.5 CenterNet-master/src/lib/utils/debugger.py修改(这步可选,不是必须的,因为后面用自己跑前向推理的脚本就不需要这步,用官方提供的跑前向推理需要)
Line 458添加:
my_test_class_name = [
'cheliang', 'chewei', 'chelian', 'dibiao_20', 'sanjiaojia',
'qizhibiaozhi', 'motorbike', 'dibiao_0', 'dibiao_qd', 'xiaochebiaozhipai', 'tingchebiaozhipai',
'fanguangbeixin', 'dibiao_10'
]
Line45添加:
elif num_classes == 80 or dataset == 'coco':
self.names = coco_class_name
elif num_classes == 13 or dataset == 'my_test':
self.names = my_test_class_name
elif num_classes == 20 or dataset == 'pascal':
self.names = pascal_class_name
4.训练指令 python main.py ctdet --exp_id my_test --batch_size 4 --lr 0.001 --gpus 1 --num_workers 8
cd CenterNet-master/src
python main.py ctdet --exp_id my_test --batch_size 4 --lr 0.001 --gpus 1 --num_workers 8
继续上次训练直接加--resume即可:
python main.py ctdet --exp_id my_test --batch_size 4 --lr 0.001 --gpus 1 --num_workers 8 --resume
5.跑前向代码---测试或者查看效果
https://blog.csdn.net/yang332233/article/details/109007342
6.运行报错排查
6.1
CenterNet-master/src/lib/models/networks/DCNv2/dcn_v2.py
ModuleNotFoundError: No module named ‘_ext‘
解决方案:
在目录【DCNv2】文件下使用
python setup.py install develop
6.2 解决xml中filename名字与文件名不一样问题,
xml_change_filename.py可以解决。(我自己这边可能遇到的问题)
小弟不才,同时谢谢友情赞助!