本文官方鏈接: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=%7B%22request%5Fid%22%3A%22160515033819725222412279%22%2C%22scm%22%3A%2220140713.130102334.pc%5Fblog.%22%7D&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可以解決。(我自己這邊可能遇到的問題)
小弟不才,同時謝謝友情贊助!