注: 本博客参考https://github.com/PaddlePaddle,仅为学习交流使用,如有侵权,请联系删除!
如果数据符合COCO或VOC数据集格式,可以直接进入2.选择模型,否则需要将数据集转换至COCO格式或VOC格式。
在./tools/
中提供了x2coco.py
用于将labelme标注的数据集或cityscape数据集转换为COCO数据集:
python ./ppdet/data/tools/x2coco.py \
--dataset_type labelme \
--json_input_dir ./labelme_annos/ \
--image_input_dir ./labelme_imgs/ \
--output_dir ./cocome/ \
--train_proportion 0.8 \
--val_proportion 0.2 \
--test_proportion 0.0 \
参数说明:
--dataset_type
:需要转换的数据格式,目前支持:'labelme'
和'cityscape'
--json_input_dir
:使用labelme标注的json文件所在文件夹--image_input_dir
:图像文件所在文件夹--output_dir
:转换后的COCO格式数据集存放位置--train_proportion
:标注数据中用于train的比例--val_proportion
:标注数据中用于validation的比例--test_proportion
:标注数据中用于infer的比例VOC数据集所必须的文件内容如下所示,数据集根目录需有VOCdevkit/VOC2007
或VOCdevkit/VOC2012
文件夹,该文件夹中需有Annotations
,JPEGImages
和ImageSets/Main
三个子目录,Annotations
存放图片标注的xml文件,JPEGImages
存放数据集图片,ImageSets/Main
存放训练trainval.txt和测试test.txt列表。
VOCdevkit
├──VOC2007(或VOC2012)
│ ├── Annotations
│ ├── xxx.xml
│ ├── JPEGImages
│ ├── xxx.jpg
│ ├── ImageSets
│ ├── Main
│ ├── trainval.txt
│ ├── test.txt
执行以下脚本,将根据ImageSets/Main
目录下的trainval.txt和test.txt文件在数据集根目录生成最终的trainval.txt
和test.txt
列表文件:
python dataset/voc/create_list.py -d path/to/dataset
参数说明:
-d
或--dataset_dir
:VOC格式数据集所在文件夹路径如果数据集有新的格式需要添加进PaddleDetection中,您可自行参考数据处理文档中的添加新数据源文档部分,开发相应代码完成新的数据源支持,同时数据处理具体代码解析等可阅读数据处理文档
PaddleDetection中提供了丰富的模型库,具体可在模型库中查看各个模型的指标,您可依据实际部署算力的情况,选择合适的模型:
同时也可以根据使用场景不同选择合适的模型:
同时也可以尝试PaddleDetection中开发的YOLOv3增强模型、YOLOv4模型与Anchor Free模型等。
选择好模型后,需要在configs
目录中找到对应的配置文件,为了适配在自定义数据集上训练,需要对参数配置做一些修改:
数据路径配置: 在yaml配置文件中,依据1.数据准备中准备好的路径,配置TrainReader
、EvalReader
和TestReader
的路径。
dataset:
!COCODataSet
image_dir: val2017 # 图像数据基于数据集根目录的相对路径
anno_path: annotations/instances_val2017.json # 标注文件基于数据集根目录的相对路径
dataset_dir: dataset/coco # 数据集根目录
with_background: true # 背景是否作为一类标签,默认为true。
dataset:
!VOCDataSet
anno_path: trainval.txt # 训练集列表文件基于数据集根目录的相对路径
dataset_dir: dataset/voc # 数据集根目录
use_default_label: true # 是否使用默认标签,默认为true。
with_background: true # 背景是否作为一类标签,默认为true。
说明: 如果您使用自己的数据集进行训练,需要将use_default_label
设为false
,并在数据集根目录中修改label_list.txt
文件,添加自己的类别名,其中行号对应类别号。
num_classes: XX
。with_background: true
,那么num_classes数必须是真实类别数+1(背景也算作1类)LearningRate
相关参数:
max_iters
,以及LearningRate
中的milestones
(学习率变化界限)。pretrain_weights: path/to/weights
参数可以配置路径,可以是链接或权重文件路径。可直接沿用配置文件中给出的在ImageNet数据集上的预训练模型。同时我们支持训练在COCO或Obj365数据集上的模型权重作为预训练模型,做迁移学习,详情可参考迁移学习文档。我们以AI识虫数据集
为例,对自定义数据集上训练过程进行演示,该数据集提供了2183张图片,其中训练集1693张,验证集与测试集分别有245张,共包含7种昆虫。在AIStudio上有很多用户公开了此数据集,您可以进行搜索并下载,如:链接1,链接2等。
由于该数据集标注文件都是xml文件,所以在准备数据步骤中选择方式二:将数据集转换为VOC格式。
由于该数据集中缺少已标注图片名列表文件trainval.txt和test.txt,所以需要进行生成,利用如下python脚本,在数据集根目录下执行,便可生成trainval.txt
和test.txt
文件:
import os
file_train = open('trainval.txt', 'w')
file_test = open('test.txt', 'w')
for xml_name in os.listdir('train/annotations/xmls'):
file_train.write(xml_name[:-4] + '\n')
for xml_name in os.listdir('val/annotations/xmls'):
file_test.write(xml_name[:-4] + '\n')
file_train.close()
file_test.close()
模仿VOC数据集目录结构,新建VOCdevkit
文件夹并进入其中,然后继续新建VOC2007
文件夹并进入其中,之后新建Annotations
、JPEGImages
和ImageSets
文件夹,最后进入ImageSets
文件夹中新建Main
文件夹,至此完成VOC数据集目录结构的建立。
将该数据集中的train/annotations/xmls
与val/annotations/xmls
下的所有xml标注文件拷贝到VOCdevkit/VOC2007/Annotations
中,将该数据集中的train/images/
与val/images/
下的所有图片拷贝到VOCdevkit/VOC2007/JPEGImages
中,将第一步生成的trainval.txt
和test.txt
文件移动到VOCdevkit/VOC2007/ImageSets/Main
中。
最后在数据集根目录下输出最终的trainval.txt
和test.txt
文件:
python dataset/voc/create_list.py -d path/to/dataset
注意: 最终的trainval.txt
和test.txt
文件与第一步生成的两个文件不同之处在于最终的文件存储的是标注文件路径与图片路径,初始生成的文件只有已标注的图片名称。
由于昆虫比较小,属于小物体检测范畴,我们选择Faster-Rcnn系列模型。
然后基于configs/faster_rcnn_r50_fpn_1x.yml
文件进行修改:
修改Reader模块:为了方便模型评估需要将metric改为VOC
;Reader部分已经在faster_fpn_reader.yml
中定义完成,此处将要修改的内容覆写即可,如下yaml配置所示:
...
metric: VOC
...
_READER_: 'faster_fpn_reader.yml'
TrainReader:
dataset:
!VOCDataSet
dataset_dir: path/to/dataset
anno_path: trainval.txt
use_default_label: false
batch_size: 2
EvalReader:
inputs_def:
fields: ['image', 'im_info', 'im_id', 'im_shape', 'gt_bbox', 'gt_class', 'is_difficult']
dataset:
!VOCDataSet
dataset_dir: path/to/dataset
anno_path: test.txt
use_default_label: false
TestReader:
dataset:
!ImageFolder
anno_path: path/to/dataset/label_list.txt
use_default_label: false
修改训练轮数与学习率等参数:
batch_size
大小计算epoch数,然后将epoch数换算得到训练总轮数max_iters
。milestones
(学习率变化界限)也是同理。原配置文件中总batch_size
=2*8=16(8卡训练),训练集数量约为12万张,max_iters
=90000,所以epoch数=16x90000/120000=12。在AI识虫数据集中,训练集数量约为1700,在单卡GPU上训练,max_iters
=12x1700/2=10200。同理计算milestones为: [6800, 9000]。faster_rcnn_r50_fpn
模型是在8卡GPU环境下训练得到的,所以我们要将学习率除以8:max_iters: 10200
...
LearningRate:
base_lr: 0.0025
schedulers:
- !PiecewiseDecay
gamma: 0.1
milestones: [6800, 9000]
为了使模型更快的收敛,我们使用在COCO数据集上训好的模型进行迁移学习,并且增加--eval
参数,表示边训练边测试:
export CUDA_VISIBLE_DEVICES=0
python -u tools/train.py -c configs/faster_rcnn_r50_fpn_1x.yml \
-o pretrain_weights=https://paddlemodels.bj.bcebos.com/object_detection/faster_rcnn_r50_fpn_1x.tar \
finetune_exclude_pretrained_params=['cls_score','bbox_pred'] \
--eval
在P40机器上单卡训练40分钟左右就可完成训练,最终的mAP(0.50, 11point)=71.60,如果想让模型收敛的更好,可以继续增大max_iters,训练2x、3x等模型,但并不是意味着训练轮数越多效果越好,要防止过拟合的出现。
训完之后,可以任意挑选一张测试集图片进行测试,输出的结果图片会默认保存在output目录中:
python -u tools/infer.py -c configs/faster_rcnn_r50_fpn_1x.yml \
--infer_img=path/to/dataset/2572.jpeg