使用Mask Scoring RCNN 训练自己的数据
转载链接
本文主要参考上面链接,并做了一些细节调整,具体内容可以去看原博主的文章。
一、相关准备
1、相关资源
- 论文《Mask Scoring R-CNN:Path Aggregation Network for Instance Segmentation》(CVPR2019 oral)【论文地址 】
mask scoring rcnn
代码地址【github】mask rcnn benchmark
代码地址【github】
2、安装环境
conda create --name maskrcnn_benchmark
source activate maskrcnn_benchmark
conda install ipython
pip install ninja yacs cython matplotlib pyqt5
conda install pytorch-nightly torchvision=0.2.1 cudatoolkit=9.0 -c pytorch
注:cuda 版本必须为9.0,torchvision 版本必须为0.2.1,否则会报错,具体可参考【github_issues】
3、安装cocoapi & apex
export INSTALL_DIR=$PWD
# install pycocotools
git clone https://github.com/cocodataset/cocoapi.git
cd cocoapi/PythonAPI
python setup.py build_ext install
# install apex
cd $INSTALL_DIR
git clone https://github.com/NVIDIA/apex.git
cd apex
python setup.py install --cuda_ext --cpp_ext
4、编译模型代码
# install PyTorch Detection
cd $INSTALL_DIR
git clone https://github.com/zjhuang22/maskscoring_rcnn
cd maskscoring_rcnn
python setup.py build develop
二、训练自己的数据
1、数据准备
Mask Scoring RCNN
模型使用的是coco
数据集标准,所以,可以把自己的数据集转换成coco
数据集标准格式,网上有很多脚本可以完成转换工作,也可以参考原博文。
如果需要预训练模型,可以下载并放到maskscoring_rcnn
目录下面
这里我使用的数据以及预训练模型的目录结构,如下:
├── maskscoring_rcnn
│ ├── datasets
│ │ └── annotations
│ │ │ ├── coco_mydata_train.json
│ │ │ ├── coco_mydata_test.json
│ │ └── coco_mydata_train
│ │ └── coco_mydata_test
│ │
│ ├── ImageNetPretrained
│ │ └── R-101.pkl
│ │ └── R-50.pkl
...
注: annotations
:目录下面放的是数据的label
信息,coco_mydata_xxx:
目录下放的是原始图像信息,ImageNetPretrained:
目录下放的是两个pkl
格式的预训练模型。
2、修改相关参数
- 修改
maskscoring_rcnn/configs
目录下的配置文件:
(1)添加预训练模型路径。
(2)添加要训练的自己数据数据集
例如:选择其中的 e2e_ms_rcnn_R_50_FPN_1x.yaml
训练脚本,修改如下:
MODEL:
META_ARCHITECTURE: "GeneralizedRCNN"
WEIGHT: "catalog://ImageNetPretrained/MSRA/R-50"
PRETRAINED_MODELS: 'ImageNetPretrained'
DATASETS:
TRAIN: ("coco_train_xxx",) # 1.设置训练验证集,名字可以随意起,和其他配置文件对应即可。
TEST: ("coco_val_xxx",)
- 修改
maskscoring_rcnn/maskrcnn_benchmark/config
下的paths_catalog.py
文件:
(1)添加自己的数据集路径信息,在相应的代码段后面添加两行即可
。
DATASETS = {
"coco_2014_train": ( "coco/train2014", "coco/annotations/instances_train2014.json",),
"coco_2014_val": ("coco/val2014", "coco/annotations/instances_val2014.json"),
"coco_2014_minival": ( "coco/val2014", "coco/annotations/instances_minival2014.json", ),
"coco_2014_valminusminival": (
"coco/val2014", "coco/annotations/instances_valminusminival2014.json", ),
"coco_train_xxx": ("coco_mydata_train", "annotations/coco_mydata_train.json"),
"coco_val_xxx": ("coco_mydata_test", "annotations/coco_mydata_test.json"),
}
- 修改
maskscoring_rcnn/maskrcnn_benchmark/config
下的defaults.py
配置文件:
(1)这个主要修改训练模型的相关参数,例如 分类数、学习率、check point数量、batch、最后模型保存路径等
_C.MODEL.ROI_BOX_HEAD.NUM_CLASSES = 3 # 1.修改分类数量,coco对应81(80+1)
_C.SOLVER.BASE_LR = 0.0005 # 2.修改学习率,默认为0.001
_C.SOLVER.CHECKPOINT_PERIOD = 1000 # 3.修改check point数量,根据需要自定义
_C.SOLVER.IMS_PER_BATCH = 4 # 4.修改batch size,默认16
_C.TEST.IMS_PER_BATCH = 4 # 5.修改test batch size,默认8
_C.OUTPUT_DIR = "weights/" # 6.设置模型保存路径(对应自定义文件夹)
- 开始训练:
python tools/train_net.py --config-file configs/e2e_ms_rcnn_R_50_FPN_1x.yaml
python tools/test_net.py --config-file configs/e2e_ms_rcnn_R_50_FPN_1x.yaml
训练日志:
2019-10-24 21:02:12,782 maskrcnn_benchmark.trainer INFO: eta: 1:44:55 iter: 640 loss: 0.0682 (0.2568) loss_classifier: 0.0255 (0.0699) loss_box_reg: 0.0103 (0.0365) loss_mask: 0.0294 (0.1299) loss_maskiou: 0.0006 (0.0072) loss_objectness: 0.0033 (0.0112) loss_rpn_box_reg: 0.0004 (0.0021) time: 0.7591 (0.7531) data: 0.0158 (0.0160) lr: 0.020000 max mem: 3857
2019-10-24 21:02:27,324 maskrcnn_benchmark.trainer INFO: eta: 1:44:34 iter: 660 loss: 0.0639 (0.2511) loss_classifier: 0.0178 (0.0684) loss_box_reg: 0.0073 (0.0356) loss_mask: 0.0301 (0.1270) loss_maskiou: 0.0006 (0.0070) loss_objectness: 0.0013 (0.0109) loss_rpn_box_reg: 0.0005 (0.0021) time: 0.7410 (0.7523) data: 0.0160 (0.0160) lr: 0.020000 max mem: 3857
2019-10-24 21:02:42,145 maskrcnn_benchmark.trainer INFO: eta: 1:44:16 iter: 680 loss: 0.0539 (0.2454) loss_classifier: 0.0166 (0.0670) loss_box_reg: 0.0059 (0.0348) loss_mask: 0.0282 (0.1241) loss_maskiou: 0.0005 (0.0068) loss_objectness: 0.0015 (0.0107) loss_rpn_box_reg: 0.0003 (0.0020) time: 0.7449 (0.7520) data: 0.0153 (0.0159) lr: 0.020000 max mem: 3857
注: 可能会遇到 maskrcnn_benchmark/utils/model_zool.py
错误,修改接口即可:
from torch.hub import _download_url_to_file
from torch.hub import urlparse
from torch.hub import HASH_REGEX
三、模型预测\推理
1、修改相关参数
- 修改
maskscoring_rcnn/configs
路径下的对应的yaml
文件的权重路径
MODEL:
META_ARCHITECTURE: "GeneralizedRCNN"
WEIGHT: "weights/model_0010000.pth" # 训练好的模型路径
BACKBONE:
CONV_BODY: "R-50-FPN"
OUT_CHANNELS: 256
- 修改
maskscoring_rcnn/demo
路径下的predictor.py
文件,添加类别信息。
注意,这个文件应该不存在,可以在【mask rcnn benchmark 】的demo文件下复制过来即可。而且在运行的过程中,会报错找不到文件或者无法导入相关的库,可以从 mask rcnn benchmark 对应的文件夹内复制到,相应的文件夹内即可。
class COCODemo(object):
# COCO categories for pretty print
CATEGORIES = [
"__background",
"cla_a",
"cla_b",
"cla_c",
]
- 在
maskscoring_rcnn/demo
下新建 predict.py,用于预测
#!/usr/bin/env python
# coding=UTF-8
import os, sys
import numpy as np
import cv2
from maskrcnn_benchmark.config import cfg
from predictor import COCODemo
# 1.修改后的配置文件
config_file = "configs/e2e_ms_rcnn_R_50_FPN_1x.yaml"
# 2.配置
cfg.merge_from_file(config_file) # merge配置文件
cfg.merge_from_list(["MODEL.MASK_ON", True]) # 打开mask开关
cfg.merge_from_list(["MODEL.DEVICE", "cuda"]) # or设置为CPU ["MODEL.DEVICE", "cpu"]
#cfg.merge_from_list(["MODEL.DEVICE", "cpu"])
coco_demo = COCODemo(
cfg,
min_image_size=800,
confidence_threshold=0.5, # 3.设置置信度
)
if __name__ == '__main__':
in_folder = '../datasets/test_images/'
out_folder = '../datasets/test_images_out/'
if not os.path.exists(out_folder):
os.makedirs(out_folder)
for file_name in os.listdir(in_folder):
if not file_name.endswith(('jpg', 'png')):
continue
# load file
img_path = os.path.join(in_folder, file_name)
image = cv2.imread(img_path)
# method1. 直接得到opencv图片结果
#predictions = coco_demo.run_on_opencv_image(image)
#save_path = os.path.join(out_folder, file_name)
#cv2.imwrite(save_path, predictions)
# method2. 获取预测结果
predictions = coco_demo.compute_prediction(image)
top_predictions = coco_demo.select_top_predictions(predictions)
# draw
img = coco_demo.overlay_boxes(image, top_predictions)
img = coco_demo.overlay_mask(img, predictions)
img = coco_demo.overlay_class_names(img, top_predictions)
save_path = os.path.join(out_folder, file_name)
cv2.imwrite(save_path, img)
# print results
boxes = top_predictions.bbox.numpy()
labels = top_predictions.get_field("labels").numpy() #label = labelList[np.argmax(scores)]
scores = top_predictions.get_field("scores").numpy()
masks = top_predictions.get_field("mask").numpy()
for i in range(len(boxes)):
print('box:', i, ' label:', labels[i])
x1,y1,x2,y2 = [round(x) for x in boxes[i]] # = map(int, boxes[i])
print('x1,y1,x2,y2:', x1,y1,x2,y2)
- 运行程序
CUDA_VISIBLE_DEVICES=0 python demo/predict.py
四、总结
在测试的过程中,使用了100多张自己标注的图片,训练10000次保存一次模型,在预测的过程出现resize错误、维度不统一
等。估计是过拟合引起的,后来改成1000次保存一次模型,可以正常运行处结果。