论文地址:https://arxiv.org/abs/2111.13673
代码地址:https://github.com/SysCV/transfiner
一、 数据集预处理
1.标注数据集(labelme)
①安装labelme
pip install labelme#提前配置好环境
②按照如下目录格式准备数据
├── img_data: 存放你要标注的所有图片
├── data_annotated: 存放后续标注好的所有json文件
└── label.txt: 所有类别信息
③创建label.txt,内容如下:
__ignore__
_background_
car
④启动labelme并读取标签文件
labelme --labels label.txt
将img_data文件夹在labelme中打开,选择Create Polygonts绘制多边形和Create rectangle绘制矩形,将生成的json标签保存在data_annotated中。
2.将数据集转化为coco格式
将图片和标签按照一定比例分为训练集和验证集
运行下面的代码,得到coco格式的标签
python labelme2voc.py data_annotated data_dataset_coco --labels label.txt
最终数据集目录如下:
3.环境配置
conda create -n transfiner python=3.7 -y
conda activate transfiner
conda install pytorch==1.7.1 torchvision==0.8.2 torchaudio==0.7.2 cudatoolkit=11.0 -c pytorch
# Coco api and visualization dependencies
pip install ninja yacs cython matplotlib tqdm
pip install opencv-python==4.4.0.40
# Boundary dependency
pip install scikit-image
pip install kornia==0.5.11
export INSTALL_DIR=$PWD
# install pycocotools. Please make sure you have installed cython.
cd $INSTALL_DIR
git clone https://github.com/cocodataset/cocoapi.git
cd cocoapi/PythonAPI
python setup.py build_ext install
# install transfiner
cd $INSTALL_DIR
git clone --recursive https://github.com/SysCV/transfiner.git
cd transfiner/
python3 setup.py build develop
unset INSTALL_DIR
4.在detectron2注册数据集
首先将数据集文件夹datasets移动到transfiner文件夹下
在transfiner/tools/train_net.py中增添以下代码,将car数据集注册到detectron2中
from detectron2.data import DatasetCatalog, MetadataCatalog
from detectron2.data.datasets.coco import load_coco_json
import pycocotools
os.environ['CUDA_VISIBLE_DEVICES'] = '1'
CLASS_NAMES = ["_background_", "car"]
DATASET_ROOT = '/home/zl/myprojects/transfiner/datasets/car'
ANN_ROOT = os.path.join(DATASET_ROOT, 'COCOformat')
TRAIN_PATH = DATASET_ROOT
VAL_PATH = DATASET_ROOT
TRAIN_JSON = os.path.join(ANN_ROOT, 'train.json')
VAL_JSON = os.path.join(ANN_ROOT, 'val.json')
PREDEFINED_SPLITS_DATASET = {
"coco_my_train": (TRAIN_PATH, TRAIN_JSON),
"coco_my_val": (VAL_PATH, VAL_JSON),
}
def plain_register_dataset():
# 训练集
DatasetCatalog.register(
"coco_my_train", lambda: load_coco_json(TRAIN_JSON, TRAIN_PATH))
MetadataCatalog.get("coco_my_train").set(thing_classes=CLASS_NAMES,
evaluator_type='coco',
json_file=TRAIN_JSON,
image_root=TRAIN_PATH)
# 验证/测试集
DatasetCatalog.register(
"coco_my_val", lambda: load_coco_json(VAL_JSON, VAL_PATH))
MetadataCatalog.get("coco_my_val").set(thing_classes=CLASS_NAMES,
evaluator_type='coco',
json_file=VAL_JSON,
image_root=VAL_PATH)
# def setup(args):
# """
# Create configs and perform basic setups.
# """
# cfg = get_cfg()
# cfg.merge_from_file(args.config_file)
# cfg.merge_from_list(args.opts)
# cfg.freeze()
# default_setup(cfg, args)
# return cfg
def setup(args):
"""
Create configs and perform basic setups.
"""
cfg = get_cfg()
args.config_file = "configs/transfiner/mask_rcnn_R_50_FPN_1x.yaml"
cfg.merge_from_file(args.config_file) # 从config file 覆盖配置
cfg.merge_from_list(args.opts) # 从CLI参数 覆盖配置
# 更改配置参数
cfg.DATASETS.TRAIN = ("coco_my_train",) # 训练数据集名称
cfg.DATASETS.TEST = ("coco_my_val",)
cfg.DATALOADER.NUM_WORKERS = 4 # 单线程
cfg.INPUT.CROP.ENABLED = True
cfg.INPUT.MAX_SIZE_TRAIN = 4090 # 训练图片输入的最大尺寸
cfg.INPUT.MAX_SIZE_TEST = 4090 # 测试数据输入的最大尺寸
cfg.INPUT.MIN_SIZE_TRAIN = (512, 768) # 训练图片输入的最小尺寸,可以设定为多尺度训练
cfg.INPUT.MIN_SIZE_TEST = 640
# cfg.INPUT.MIN_SIZE_TRAIN_SAMPLING,其存在两种配置,分别为 choice 与 range :
# range 让图像的短边从 512-768随机选择
# choice : 把输入图像转化为指定的,有限的几种图片大小进行训练,即短边只能为 512或者768
cfg.INPUT.MIN_SIZE_TRAIN_SAMPLING = 'range'
# 本句一定要看下注释!!!!!!!!
# 类别数+1(因为有background,也就是你的 cate id 从 1 开始,如果您的数据集Json下标从 0 开始,这个改为您对应的类别就行,不用再加背景类!!!!!)
cfg.MODEL.RETINANET.NUM_CLASSES = 2
# cfg.MODEL.WEIGHTS="/home/yourstorePath/.pth"
# cfg.MODEL.WEIGHTS = "/home/zl/myprojects/transfiner/pretrained_model/output_1x_transfiner_r50.pth" # 预训练模型权重
# batch_size=2; iters_in_one_epoch = dataset_imgs/batch_size
cfg.SOLVER.IMS_PER_BATCH = 4
# 根据训练数据总数目以及batch_size,计算出每个epoch需要的迭代次数
# 9000为你的训练数据的总数目,可自定义
ITERS_IN_ONE_EPOCH = int(500 / cfg.SOLVER.IMS_PER_BATCH)
# 指定最大迭代次数
cfg.SOLVER.MAX_ITER = (ITERS_IN_ONE_EPOCH * 12) - 1 # 12 epochs,
# 初始学习率
cfg.SOLVER.BASE_LR = 0.002
# 优化器动能
cfg.SOLVER.MOMENTUM = 0.9
# 权重衰减
cfg.SOLVER.WEIGHT_DECAY = 0.0001
cfg.SOLVER.WEIGHT_DECAY_NORM = 0.0
# 学习率衰减倍数
cfg.SOLVER.GAMMA = 0.1
# 迭代到指定次数,学习率进行衰减
cfg.SOLVER.STEPS = (7000,)
# 在训练之前,会做一个热身运动,学习率慢慢增加初始学习率
cfg.SOLVER.WARMUP_FACTOR = 1.0 / 1000
# 热身迭代次数
cfg.SOLVER.WARMUP_ITERS = 1000
cfg.SOLVER.WARMUP_METHOD = "linear"
# 保存模型文件的命名数据减1
cfg.SOLVER.CHECKPOINT_PERIOD = ITERS_IN_ONE_EPOCH - 1
# 迭代到指定次数,进行一次评估
cfg.TEST.EVAL_PERIOD = ITERS_IN_ONE_EPOCH
#cfg.TEST.EVAL_PERIOD = 100
# cfg.merge_from_file(args.config_file)
# cfg.merge_from_list(args.opts)
cfg.freeze()
default_setup(cfg, args)
return cfg
二、 训练
cd transfiner
python train_net.py --num-gpus 1
训练过程如下:
三、 验证
1.定量
python tools/train_net.py --num-gpu 1 --eval-only MODEL.WEIGHTS /home/zl/myprojects/transfiner/output_r50_1x/best.pth
2.定性