|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- # 2: 在自定义数据集上进行训练
-
- 通过本文档,你将会知道如何使用自定义数据集对预先定义好的模型进行推理,测试以及训练。我们使用 [balloon dataset](https://github.com/matterport/Mask_RCNN/tree/master/samples/balloon) 作为例子来描述整个过程。
-
- 基本步骤如下:
-
- 1. 准备自定义数据集
- 2. 准备配置文件
- 3. 在自定义数据集上进行训练,测试和推理。
-
- ## 准备自定义数据集
-
- MMDetection 一共支持三种形式应用新数据集:
-
- 1. 将数据集重新组织为 COCO 格式。
- 2. 将数据集重新组织为一个中间格式。
- 3. 实现一个新的数据集。
-
- 我们通常建议使用前面两种方法,因为它们通常来说比第三种方法要简单。
-
- 在本文档中,我们展示一个例子来说明如何将数据转化为 COCO 格式。
-
- **注意**:MMDetection 现只支持对 COCO 格式的数据集进行 mask AP 的评测。
-
- 所以用户如果要进行实例分割,只能将数据转成 COCO 格式。
-
- ### COCO标注格式
-
- 用于实例分割的 COCO 数据集格式如下所示,其中的键(key)都是必要的,参考[这里](https://cocodataset.org/#format-data)来获取更多细节。
- ```json
- {
- "images": [image],
- "annotations": [annotation],
- "categories": [category]
- }
-
-
- image = {
- "id": int,
- "width": int,
- "height": int,
- "file_name": str,
- }
-
- annotation = {
- "id": int,
- "image_id": int,
- "category_id": int,
- "segmentation": RLE or [polygon],
- "area": float,
- "bbox": [x,y,width,height],
- "iscrowd": 0 or 1,
- }
-
- categories = [{
- "id": int,
- "name": str,
- "supercategory": str,
- }]
- ```
- 现在假设我们使用 balloon dataset。
-
- 下载了数据集之后,我们需要实现一个函数将标注格式转化为 COCO 格式。然后我们就可以使用已经实现的 `COCODataset` 类来加载数据并进行训练以及评测。
-
- 如果你浏览过新数据集,你会发现格式如下:
-
- ```json
- {'base64_img_data': '',
- 'file_attributes': {},
- 'filename': '34020010494_e5cb88e1c4_k.jpg',
- 'fileref': '',
- 'regions': {'0': {'region_attributes': {},
- 'shape_attributes': {'all_points_x': [1020,
- 1000,
- 994,
- 1003,
- 1023,
- 1050,
- 1089,
- 1134,
- 1190,
- 1265,
- 1321,
- 1361,
- 1403,
- 1428,
- 1442,
- 1445,
- 1441,
- 1427,
- 1400,
- 1361,
- 1316,
- 1269,
- 1228,
- 1198,
- 1207,
- 1210,
- 1190,
- 1177,
- 1172,
- 1174,
- 1170,
- 1153,
- 1127,
- 1104,
- 1061,
- 1032,
- 1020],
- 'all_points_y': [963,
- 899,
- 841,
- 787,
- 738,
- 700,
- 663,
- 638,
- 621,
- 619,
- 643,
- 672,
- 720,
- 765,
- 800,
- 860,
- 896,
- 942,
- 990,
- 1035,
- 1079,
- 1112,
- 1129,
- 1134,
- 1144,
- 1153,
- 1166,
- 1166,
- 1150,
- 1136,
- 1129,
- 1122,
- 1112,
- 1084,
- 1037,
- 989,
- 963],
- 'name': 'polygon'}}},
- 'size': 1115004}
- ```
- 标注文件时是 JSON 格式的,其中所有键(key)组成了一张图片的所有标注。
-
- 其中将 balloon dataset 转化为 COCO 格式的代码如下所示。
-
- ```python
-
- import os.path as osp
-
- def convert_balloon_to_coco(ann_file, out_file, image_prefix):
- data_infos = mmcv.load(ann_file)
-
- annotations = []
- images = []
- obj_count = 0
- for idx, v in enumerate(mmcv.track_iter_progress(data_infos.values())):
- filename = v['filename']
- img_path = osp.join(image_prefix, filename)
- height, width = mmcv.imread(img_path).shape[:2]
-
- images.append(dict(
- id=idx,
- file_name=filename,
- height=height,
- width=width))
-
- bboxes = []
- labels = []
- masks = []
- for _, obj in v['regions'].items():
- assert not obj['region_attributes']
- obj = obj['shape_attributes']
- px = obj['all_points_x']
- py = obj['all_points_y']
- poly = [(x + 0.5, y + 0.5) for x, y in zip(px, py)]
- poly = [p for x in poly for p in x]
-
- x_min, y_min, x_max, y_max = (
- min(px), min(py), max(px), max(py))
-
-
- data_anno = dict(
- image_id=idx,
- id=obj_count,
- category_id=0,
- bbox=[x_min, y_min, x_max - x_min, y_max - y_min],
- area=(x_max - x_min) * (y_max - y_min),
- segmentation=[poly],
- iscrowd=0)
- annotations.append(data_anno)
- obj_count += 1
-
- coco_format_json = dict(
- images=images,
- annotations=annotations,
- categories=[{'id':0, 'name': 'balloon'}])
- mmcv.dump(coco_format_json, out_file)
-
- ```
-
- 使用如上的函数,用户可以成功将标注文件转化为 JSON 格式,之后可以使用 `CocoDataset` 对模型进行训练和评测。
-
- ## 准备配置文件
-
- 第二步需要准备一个配置文件来成功加载数据集。假设我们想要用 balloon dataset 来训练配备了 FPN 的 Mask R-CNN ,如下是我们的配置文件。假设配置文件命名为 `mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_balloon.py`,相应保存路径为 `configs/ballon/`,配置文件内容如下所示。
-
- ```python
- # 这个新的配置文件继承自一个原始配置文件,只需要突出必要的修改部分即可
- _base_ = 'mask_rcnn/mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_coco.py'
-
- # 我们需要对头中的类别数量进行修改来匹配数据集的标注
- model = dict(
- roi_head=dict(
- bbox_head=dict(num_classes=1),
- mask_head=dict(num_classes=1)))
-
- # 修改数据集相关设置
- dataset_type = 'COCODataset'
- classes = ('balloon',)
- data = dict(
- train=dict(
- img_prefix='balloon/train/',
- classes=classes,
- ann_file='balloon/train/annotation_coco.json'),
- val=dict(
- img_prefix='balloon/val/',
- classes=classes,
- ann_file='balloon/val/annotation_coco.json'),
- test=dict(
- img_prefix='balloon/val/',
- classes=classes,
- ann_file='balloon/val/annotation_coco.json'))
-
- # 我们可以使用预训练的 Mask R-CNN 来获取更好的性能
- load_from = 'checkpoints/mask_rcnn_r50_caffe_fpn_mstrain-poly_3x_coco_bbox_mAP-0.408__segm_mAP-0.37_20200504_163245-42aa3d00.pth'
- ```
-
- ## 训练一个新的模型
-
- 为了使用新的配置方法来对模型进行训练,你只需要运行如下命令。
-
- ```shell
- python tools/train.py configs/balloon/mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_balloon.py
- ```
-
- 参考[情况 1](./1_exist_data_model.md)来获取更多详细的使用方法。
-
- ## 测试以及推理
-
- 为了测试训练完毕的模型,你只需要运行如下命令。
-
- ```shell
- python tools/test.py configs/balloon/mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_balloon.py work_dirs/mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_balloon.py/latest.pth --eval bbox segm
- ```
-
- 参考[情况 1](./1_exist_data_model.md)来获取更多详细的使用方法。
|