Swin Transformer实战实例分割:训练自己的数据集
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swin Transformer实战实例分割:训练自己的数据集相关的知识,希望对你有一定的参考价值。
参考技术A 刚好用了swin,做分类和目标检测,也来试试分割的,而且很多场景分割更有效果,比如积水识别,安全带,土坑裂缝等等案例来自比赛
https://www.dcic-china.com/competitions/10021
这回真是小试牛刀了,因为是智慧农业赛题——牛只图像分割竞赛
以牛只实例分割图像数据作为训练样本,参赛选手需基于训练样本构建模型,对提供的测试集中的牛只图像进行实例分割检测。方法不限于实例分割,
目标检测是识别图像中存在的内容和检测其位置,
语义分割是对图像中的每个像素打上类别标签,实例分割其实是目标检测和语义分割的结合,在图像中将目标检测出来(目标检测),然后对每个像素打上标签(语义分割)。 语义分割不区分属于相同类别的不同实例(所有人都标为红色),实例分割区分同类的不同实例(使用不同颜色区分不同的人)。所以题目严格意义是语义分割,但是要标出每只牛。
看下数据就是牛棚里的,标签是多边形 polygon,标的还是一般,数据有点模糊,而且角度是俯视,用coco的cow恐怕差太多,图片比较少训练200张,牛2千多,测试100张;
可以通过标注软件查看和修改标注,比如cvat,不过这个是网页版
这里就先用swin-transformer-object-detection跑个baseline吧
https://github.com/SwinTransformer/Swin-Transformer-Object-Detection
部署swin环境同目标检测,这里用paddlex来处理数据集,所以部署环境
conda create -n paddlex python=3.7
conda activate paddlex
pip install cython
git clone https://github.com/philferriere/cocoapi.git
cd .\cocoapi\PythonAPI
python3 setup.py build_ext install
pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple
pip install paddlex -i https://mirror.baidu.com/pypi/simpleor
git clone https://github.com/PaddlePaddle/PaddleX.git
cd PaddleX
git checkout develop
python setup.py install
环境搭建好了,
现在将数据集格式为
划分数据集,也可以省略测试集
paddlex --split_dataset --format COCO --dataset_dir 200 --val_value 0.2 --test_value 0.1
将图片转移到训练和验证文件夹
处理好图片就开始配置swinT了,
两个地方 改为具体类别数 设为1
主要修改类别为自己的类别数 cat changeclass.py
相应修改configs/ base /datasets/coco_instance.py中数据集路径
修改模型权重参数等
修改configs\swin\mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco.py中的max_epochs、lr
参数文件改为coco_instance的
_base_ = [
]
注意一个类也要逗号,还要进行编译 python setup.py install
训练
python tools/train.py configs/swin/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco.py
这里提交后只有0.6多,后面还需要调优参数,增强数据,或者试试swin 分割 ,swin-Unet之类。
目标检测/实例分割Mask R-CNN简介与Swin Transformer实践测试
前言
之前在看Swin Transformer的时候,发现该算法在目标检测、实例分割等各种视觉任务上屠榜,于是想来实践测试一下。
官方地址:https://github.com/SwinTransformer/Swin-Transformer-Object-Detection
查看源码,发现Swin Transformer并不是作为一套单独的算法进行使用,而是嵌入在mask_rcnn算法中,作为该算法的backbone。(当然,也可以使用别的算法,只是该仓库目前仅实现了mask_rcnn和cascade_mask_rcnn)
因此,有必要先对Mask R-CNN算法做一个了解。
Mask R-CNN简介
Mask R-CNN是何凯明大神继Faster-RCNN后的又一力作,在Fasker R-CNN的基础上,集成了物体检测和实例分割两大功能。
论文链接:https://arxiv.org/pdf/1703.06870.pdf
中文翻译:https://blog.csdn.net/weixin_43066351/article/details/106613654
这里顺便补充一个知识点:实例分割和语义分割的区别
如图所示,中间那幅图是语义分割,只需要把不同的类别和背景分割出来即可,右侧图是实例分割,不仅需要把类别分割出来,还需要把每个个体分割出来,因此,实例分割的难度比语义分割更高。
整体结构
Mask R-CNN添加一个分支来预测每个关注区域(RoI)上的分割蒙版,从而扩展了Faster R-CNN,与现有的用于分类和边界框回归的分支并行,整体结构如下图所示:
RoIAlign替代RoIPool
Mask R-CNN和Fast R-CNN一样,均属于两阶段的目标检测,第一阶段是从原图中提取感兴趣区域(Rol)。
在Fast RCNN中,采用了RoIPool,能够通过卷积和池化将原图映射成固定尺寸的特征图,不过在处理过程中,进行了两次量化,造成了精度损失。
因此在Mask R-CNN中,使用了RoIAlign来替代RoIPool,核心思想是通过双线性插值法来避免两次量化产生的误差。
下表展示了替代之后的效果,左边这栏是实例分割的mAP,右边这栏(bb)是目标检测的mAP,可以看到替代之后对于结果的提升还是非常显著的。
这部分具体细节可以参考这两篇文章:
检测头结构
第二阶段是从Rol处理之后的特征图进行检测/分割,作者在这部分讨论了两种不同的检测头结构,如下图所示:
下图左边是不带FPN结构的Mask分支,右侧是带有FPN结构的Mask分支(灰色部分为原Faster R-CNN预测box, class信息的分支,白色部分为Mask分支)
对此,作者对不同的网络结构进行了实验比较,结果如下图所示:
可以看到ResNeXt-101-FPN这个结构起到最好的效果。
结果展示
最后作者展示了在不同算法在COCO数据集上的比较结果:
进一步拓展:可以将目标检测部分替换成人体关键点检测,结果如下图所示:
优化过程解读
最后,作者在附录中记录了对于COCO数据集的调参以及优化过程,感觉对于后续的竞赛会有帮助,研究一下:
-
Updated baseline
这一步就是对一些超参数进行修改,包括延长迭代次数到18万轮;从12万轮到16万轮学习率降低10点;将NMS阈值从0.3调整到0.5
这一步mask AP提升0.3,box AP提升0.9 -
End-to-end training
之前的训练策略是先单独对一阶段的RPN网络进行训练,之后再对二阶段的Mask R-CNN检测头进行训练,这一步端到端的优化就是将两者结合起来一起训练
这一步mask AP提升0.6,box AP提升1.2 -
ImageNet-5k pre-training
这一步很简单,就是扩充数据集,引入ImageNet-5k数据集进行预训练
这一步mask AP提升1.0,box AP提升1.0 -
Train-time augmentation
这一步就是在训练的时候,对原始数据进行数据增强,这里作者采用的数据增强策略是随机在[640, 800]像素范围内进行缩放,并且将迭代次数增加到26万轮
这一步mask AP提升0.6,box AP提升0.8 -
Deeper
deeper就是将使用更深的网络结构,这里作者101-ResNeXt升级为152-ResNeXt
这一步mask AP提升0.5,box AP提升0.6 -
Non-local
Non-local类似残差结构一样,可以在不改变原有网络结构的基础上,作为一种通用的结构插入,具体我没仔细了解,详细内容可以参考这篇论文笔记【论文笔记】Non-local Neural Networks
这一步mask AP提升0.6,box AP提升0.9 -
Test-time augmentation
这一步就是在测试时对测试数据也进行数据增强,具体的策略包括每间隔100张图片,对数据随机在[400, 1200]像素范围内进行缩放,并进行水平翻转
这一步mask AP提升1.5,box AP提升2.3
总结:从上面的实验过程不难看出,扩充数据集/对数据增强提升效果比修改网络结构提升得更为明显,这和我以往的实验经验一致。同时,对测试集进行增强检测,提升的效果最多,个人猜测是因为对测试集进行数据增强之后,测试集更贴近训练集(训练集也进行了数据增强),因此目标更容易被检测。
实践测试
下面又到了快乐的实践环节。
官方的代码实际是用mmdection框架进行实现的,而且用的版本比较老,在mmdet/__init__.py
文件中,指明了mmcv的版本范围为1.2.4-1.4.0
,而在mmdection最新仓库中,mmcv的最高版本已支持1.7.0
。
将其版本手动扩大,尝试运行,结果报错:
TypeError: MaskRCNN: SwinTransformer: init() got an unexpected keyword argument ‘ape’
查询到官方的issues#92,发现也有人遇到了同样的问题,采用python setup.py develop
等方式,并无法解决该问题,遂放弃,使用最新版本的mmdection进行实践。
mmdection地址:https://github.com/open-mmlab/mmdetection
mmdection的简介和安装可以参考我之前的博文【目标检测】MMDetection的安装与基础使用,mmcv和mmdection的版本配套比较麻烦,建议使用python3.7版本。
安装配置好之后,在configs/swin
下可以看到官方实现的几个mask_rcnn算法,这里采用mask_rcnn_swin-s-p4-w7_fpn_fp16_ms-crop-3x_coco.py
之后建立一个checkpoint
文件夹,下载mask_rcnn_swin-s-p4-w7_fpn_fp16_ms-crop-3x_coco_20210903_104808-b92c91f1.pth
和swin_small_patch4_window7_224.pth
两个模型权重,下载方式见官方的ModelZoo
。
检测图片
在源码的demo
文件夹中,有检测图片的程序,这里为了运行方便,在根目录下新建一个infer.py
from mmdet.apis import init_detector, inference_detector, show_result_pyplot
import warnings
warnings.filterwarnings("ignore")
config_file = 'configs/swin/mask_rcnn_swin-s-p4-w7_fpn_fp16_ms-crop-3x_coco.py'
checkpoint_file = 'checkpoint/mask_rcnn_swin-s-p4-w7_fpn_fp16_ms-crop-3x_coco_20210903_104808-b92c91f1.pth'
device = 'cuda:0'
# 初始化检测器
model = init_detector(config_file, checkpoint_file, device=device)
# 推理演示图像
img = 'demo/demo.jpg'
result = inference_detector(model, img)
show_result_pyplot(model, img, result, score_thr=0.3, out_file='1.jpg')
这里的out_file指定输出的图片名,检测效果如下图所示:
检测视频
检测视频和检测图片类似,在demo中有对应的代码,这里同样在根目录下新建一个infer_video.py
import argparse
import os
import cv2 as cv
import torch
from mmdet.apis import inference_detector, init_detector
import warnings
import time
warnings.filterwarnings("ignore")
file_path = __file__
dir_path = os.path.dirname(file_path)
output_video_path = os.path.join(dir_path, 'result.mp4')
def parse_args():
parser = argparse.ArgumentParser(description='MMDetection webcam demo')
parser.add_argument('config', help='test config file path')
parser.add_argument('checkpoint', help='checkpoint file')
parser.add_argument(
'--device', type=str, default='cuda:0', help='CPU/CUDA device option')
parser.add_argument(
'--camera-id', type=int, default=0, help='camera device id')
parser.add_argument(
'--score-thr', type=float, default=0.5, help='bbox score threshold')
parser.add_argument(
'--file', type=str, help='where the test video path')
parser.add_argument(
'--out', type=str, default=output_video_path, help='the out put video path')
args = parser.parse_args()
return args
def main():
args = parse_args()
if not args.file:
print('No target file!')
exit(0)
device = torch.device(args.device)
print('device:', args.device)
model = init_detector(args.config, args.checkpoint, device=device)
camera = cv.VideoCapture(args.file)
camera_width = int(camera.get(cv.CAP_PROP_FRAME_WIDTH))
camera_hight = int(camera.get(cv.CAP_PROP_FRAME_HEIGHT))
# print(camera_hight, camera_width)
fps = camera.get(cv.CAP_PROP_FPS)
video_writer = cv.VideoWriter(args.out, cv.VideoWriter_fourcc(*'mp4v'),
fps, (camera_width, camera_hight))
count = 0
tt = 0
while True:
torch.cuda.empty_cache()
ret_val, img = camera.read()
if ret_val:
if count < 0:
count += 1
print("Write in result Successfuly!".format(count))
continue
result = inference_detector(model, img)
frame = model.show_result(img, result, score_thr=args.score_thr, wait_time=1, show=False)
# cv.imshow('frame', frame)
if len(frame) >= 1:
# 添加帧率检测
# cv.putText(frame, "FPS::.1f".format(1. / (time.time() - tt)), (20, 50), cv.FONT_HERSHEY_SIMPLEX, 2,
# (235, 0, 0), 4)
# tt = time.time()
video_writer.write(frame)
count += 1
print("Write in result Successfuly!".format(count))
else:
# print('Load fail!')
break
camera.release()
video_writer.release()
# cv.destroyWindow()
if __name__ == '__main__':
main()
终端输入:
python infer_video.py configs/swin/mask_rcnn_swin-s-p4-w7_fpn_fp16_ms-crop-3x_coco.py ch
eckpoint/mask_rcnn_swin-s-p4-w7_fpn_fp16_ms-crop-3x_coco_20210903_104808-b92c91f1.pth --file demo/demo.mp4
等待片刻,即可在根目录下生成视频结果'result.mp4'
这里我使用ResNet-50,ResNet-101,Swin-S,Swin-T四种不同的backbone,对比效果如下:
Mask R-CNN遇上ikun
实测发现,对于这段30帧的视频,Mask R-CNN的帧率基本不超过3fps(RTX 2060单显卡推理),作为二阶段的算法,推理速度还是比较慢的。
视频中,有几帧会把kun的白带识别为手提包,因为是直接采用coco数据集上训练的模型进行检测,该特征和包的提手很像。
模型测试
官方下载的模型是在coco数据集进行训练的,因此使用coco数据集可以直接进行模型测试。
首先需要下载coco数据集:https://pan.baidu.com/s/1D_J3qGfQZWhaTxMvW5LzBA?pwd=8888
下载好之后,位置结构如图所示:
然后在configs/_base_/datasets/coco_instance.py
中,修改数据集的路径:
修改好之后,运行tools/test.py
即可进行模型测试:
终端输入:
python tools/test.py configs/swin/mask_rcnn_swin-t-p4-w7_fpn_1x_coco.py checkpoint/mask_rcnn_swin-t-p4-w7_fpn_1x_coco_20210902_120937-9d6b7cfa.pth --eval bbox segm
结果输出:
注:bbox是目标检测的相关指标,segm是实例分割的相关指标
Evaluating bbox...
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.427
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=1000 ] = 0.652
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=1000 ] = 0.468
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=1000 ] = 0.265
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=1000 ] = 0.459
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=1000 ] = 0.566
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.559
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=300 ] = 0.559
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=1000 ] = 0.559
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=1000 ] = 0.383
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=1000 ] = 0.596
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=1000 ] = 0.703
Evaluating segm...
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.393
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=1000 ] = 0.622
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=1000 ] = 0.422
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=1000 ] = 0.205
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=1000 ] = 0.418
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=1000 ] = 0.578
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.519
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=300 ] = 0.519
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=1000 ] = 0.519
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=1000 ] = 0.345
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=1000 ] = 0.555
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=1000 ] = 0.675
OrderedDict([('bbox_mAP', 0.427), ('bbox_mAP_50', 0.652), ('bbox_mAP_75', 0.468), ('bbox_mAP_s', 0.265), ('bbox_mAP_m', 0.459), ('bb
ox_mAP_l', 0.566), ('bbox_mAP_copypaste', '0.427 0.652 0.468 0.265 0.459 0.566'), ('segm_mAP', 0.393), ('segm_mAP_50', 0.622), ('seg
m_mAP_75', 0.422), ('segm_mAP_s', 0.205), ('segm_mAP_m', 0.418), ('segm_mAP_l', 0.578), ('segm_mAP_copypaste', '0.393 0.622 0.422 0.
205 0.418 0.578')])
模型训练
下面同样尝试利用coco数据集进行训练,数据集路径在上一节已经修改完毕,这一节主要需要修改训练参数。
我使用的是单卡GPU,显存较小,因此将configs/_base_/default_runtime.py
中的base_batch_size
改成1
然后修改configs/_base_/datasets/coco_instance.py
文件中的samples_per_gpu
和workers_per_gpu
,同样修改为1
最后运行tools/train.py
即可开始训练:
终端输入:
python tools/train.py configs/swin/mask_rcnn_swin-t-p4-w7_fpn_1x_coco.py
训练时会显示预估剩余时间,单卡2060在coco数据集上实测训练mask_rcnn_swin-t模型一轮需要花费近一天时间,这个模型参数量着实恐怖。
代码备份
包含完整代码/下载的权重:
https://pan.baidu.com/s/19zpIljdlkJG-BJD7w2NzCA?pwd=8888
以上是关于Swin Transformer实战实例分割:训练自己的数据集的主要内容,如果未能解决你的问题,请参考以下文章
Swin Transformer实战:使用 Swin Transformer实现图像分类。
Swin Transformer实战:使用 Swin Transformer实现图像分类。
Swin Transformer v2实战:使用Swin Transformer v2实现图像分类
Swin Transformer v2实战:使用Swin Transformer v2实现图像分类