MMSegmentation的用法(手把手入门教程)搭配Colab,对自己的数据进行训练

本文所用到的所有资料和代码已上传到Github,欢迎star:GitHub - zlr-zmm/MMSeg

1 介绍

MMSegmentation是一个基于Pytorch的开源语义分割工具箱,他是OpenMMLab项目的一部分 GitHub:GitHub - open-mmlab/mmsegmentation: OpenMMLab Semantic Segmentation Toolbox and Benchmark. MMseg提供的模块化设计极大便利了使用者,特别是用于入门学习,对于各类常用网络模型的即插即用集合,非常适合快速上手。

 这是mmsegmentation文件的预览,接下来,本文将以自己的数据集,利用谷歌云盘和谷歌colab服务器来重现一下MMsegmentation的使用方法

2 数据集准备

将mmsegmentation文件下载到本地来进行操作

本次数据集采用MICCAI2023牙齿分割挑战的数据集

下载来的数据集按照CHASE_DB1数据集的格式分配好,CHASE_DB1数据集格式如下:

CHASE_DB1
│   ├── images
│   │   ├── training
│   │   ├── validation
│   ├── annotations
│   │   ├── training
│   │   ├── validation

然后把数据压缩,命名为CHASEDB1.zip,使用mmseg给的数据集转换工具来转换:

使用时注意路径,需要先cd到该文件的路径,在我电脑上就是:

cd E:\mmsegmentation\mmsegmentation  # 这条指令就是把当前路径放到这个文件夹这里
python tools/dataset_converters/chase_db1.py /path/to/CHASEDB1.zip   # 使用数据转换工具

转换后的数据标签的深度是8位的,看上去是全黑的,具体显示效果如下:


(右边是给定的标签,可以将图像像素值x255,这样就看得到标签了)

这里仅仅展示这一个数据集的转换方法,其他数据集转换方法也类似,读者可以按照自己的需求进行选择。数据转换完成之后,工作就完成了一大半,接下来介绍如何利用Google Colab和Google Drive完成数据训练

3 Google Colab和Google Drive介绍

!!!使用需要科学上网!!!

Google Colab是谷歌提供的一个在线的工作平台,用户可以通过浏览器访问,最最最重要的是他提供免费的GPU算力,可以帮助落魄学生进行简单的模型训练,Colab的用法和Jupyter NoteBook一直,都是基于.ipynb格式的文件。

Colab可以最长运行时间为12小时,使用的时候需要把控这个时间,免费的GPU算力可能无法满足你的项目需求,Colab也支持氪金,但是略贵

如果没有visa支付的国内用户,可以去某宝下单,会更便宜,一个项目可以买一个pro。
对于存储,推荐使用谷歌云盘(Google Drive),谷歌云盘提供免费的5GB内存(很适合白嫖),如果数据集很大,或者运行保存的模型很大,推荐氪金,没有很贵

(MOP是澳币,这里是梯子的问题,所以显示的是澳币),200GB一般够用,如果不够用订阅2T就行了,某宝可以帮助用户订阅,而且如果需要更多的内存,补差价就行了,还是很方便的。

了解了谷歌平台的使用,读者需要在Google Drive中新建一个文件夹,点击左上角的新建按钮,然后新建文件夹,命名为Dataset,这里我已经新建好了这个文件夹,把自己的命名为CHASE_DB1的数据集上传到这里,不需要压缩上传,直接拖进来就可以上传,上传速度与网速有关。

4 MMSegmentation使用(以SegFormer为例)

接下来关注到configs这个文件夹,打开mmsegmentation/configs/segformer文件夹,可以看到里面有很多文件,(mmseg中SegFormer地址:https://github.com/open-mmlab/mmsegmentation/tree/main/configs/segformer

 这里讲解一下这些文件命名规则:segformer是网络模型,mit-b0是使用的backbone,160k是训练轮次,cityscapes是使用的数据集,512x512是crop size。点开segformer_mit-b0_8xb2-160k_ade20k-512x512.py可以看到有如下内容:

_base_ = [
    '../_base_/models/segformer_mit-b0.py', '../_base_/datasets/ade20k.py',
    '../_base_/default_runtime.py', '../_base_/schedules/schedule_160k.py'
]
crop_size = (512, 512)
data_preprocessor = dict(size=crop_size)
checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pretrain/segformer/mit_b0_20220624-7e0fe6dd.pth'  # noqa
model = dict(
    data_preprocessor=data_preprocessor,
    backbone=dict(init_cfg=dict(type='Pretrained', checkpoint=checkpoint)),
    decode_head=dict(num_classes=150))

optim_wrapper = dict(
    _delete_=True,
    type='OptimWrapper',
    optimizer=dict(
        type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01),
    paramwise_cfg=dict(
        custom_keys={
            'pos_block': dict(decay_mult=0.),
            'norm': dict(decay_mult=0.),
            'head': dict(lr_mult=10.)
        }))

param_scheduler = [
    dict(
        type='LinearLR', start_factor=1e-6, by_epoch=False, begin=0, end=1500),
    dict(
        type='PolyLR',
        eta_min=0.0,
        power=1.0,
        begin=1500,
        end=160000,
        by_epoch=False,
    )
]
train_dataloader = dict(batch_size=2, num_workers=2)
val_dataloader = dict(batch_size=1, num_workers=4)
test_dataloader = val_dataloader

其中

_base_ = [
    '../_base_/models/segformer_mit-b0.py', '../_base_/datasets/ade20k.py',
    '../_base_/default_runtime.py', '../_base_/schedules/schedule_160k.py'
]

这里定义了模型、数据集、一些默认参数,运行轮次参数,接下来在config当中新建一个文件夹,给定一个任意的名字,这就是我们自己项目的config文件,并新建一个python文件叫做baseline

将segformer_mit-b0_8xb2-160k_ade20k-512x512.py或者按照你的需求,把整个文件中的内容复制到baseline.py里面

接着来介绍一下_base_里面的内容

 datasets文件存放了各种数据集的数据读取文件,和data_load差不多,点开chase_db1.py,里面有这些内容:

# dataset settings
dataset_type = 'ChaseDB1Dataset'
data_root = 'data/CHASE_DB1'
img_scale = (960, 999)
crop_size = (128, 128)
train_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='LoadAnnotations'),
    dict(
        type='RandomResize',
        scale=img_scale,
        ratio_range=(0.5, 2.0),
        keep_ratio=True),
    dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),
    dict(type='RandomFlip', prob=0.5),
    dict(type='PhotoMetricDistortion'),
    dict(type='PackSegInputs')
]
test_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='Resize', scale=img_scale, keep_ratio=True),
    # add loading annotation after ``Resize`` because ground truth
    # does not need to do resize data transform
    dict(type='LoadAnnotations'),
    dict(type='PackSegInputs')
]
img_ratios = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75]
tta_pipeline = [
    dict(type='LoadImageFromFile', backend_args=None),
    dict(
        type='TestTimeAug',
        transforms=[
            [
                dict(type='Resize', scale_factor=r, keep_ratio=True)
                for r in img_ratios
            ],
            [
                dict(type='RandomFlip', prob=0., direction='horizontal'),
                dict(type='RandomFlip', prob=1., direction='horizontal')
            ], [dict(type='LoadAnnotations')], [dict(type='PackSegInputs')]
        ])
]

train_dataloader = dict(
    batch_size=4,
    num_workers=4,
    persistent_workers=True,
    sampler=dict(type='InfiniteSampler', shuffle=True),
    dataset=dict(
        type='RepeatDataset',
        times=40000,
        dataset=dict(
            type=dataset_type,
            data_root=data_root,
            data_prefix=dict(
                img_path='images/training',
                seg_map_path='annotations/training'),
            pipeline=train_pipeline)))

val_dataloader = dict(
    batch_size=1,
    num_workers=4,
    persistent_workers=True,
    sampler=dict(type='DefaultSampler', shuffle=False),
    dataset=dict(
        type=dataset_type,
        data_root=data_root,
        data_prefix=dict(
            img_path='images/validation',
            seg_map_path='annotations/validation'),
        pipeline=test_pipeline))
test_dataloader = val_dataloader

val_evaluator = dict(type='IoUMetric', iou_metrics=['mDice'])
test_evaluator = val_evaluator

这里就定义了数据集的一些如图像大小、数据集路径等系列东西,复制里面的所有内容然后粘贴到我们自己的baseline.py里面

models文件里面存放了各类模型定义文件,找到segformer_mit-b0.py,里面存放的东西如下:
 

# model settings
norm_cfg = dict(type='SyncBN', requires_grad=True)
data_preprocessor = dict(
    type='SegDataPreProcessor',
    mean=[123.675, 116.28, 103.53],
    std=[58.395, 57.12, 57.375],
    bgr_to_rgb=True,
    pad_val=0,
    seg_pad_val=255)
model = dict(
    type='EncoderDecoder',
    data_preprocessor=data_preprocessor,
    pretrained=None,
    backbone=dict(
        type='MixVisionTransformer',
        in_channels=3,
        embed_dims=32,
        num_stages=4,
        num_layers=[2, 2, 2, 2],
        num_heads=[1, 2, 5, 8],
        patch_sizes=[7, 3, 3, 3],
        sr_ratios=[8, 4, 2, 1],
        out_indices=(0, 1, 2, 3),
        mlp_ratio=4,
        qkv_bias=True,
        drop_rate=0.0,
        attn_drop_rate=0.0,
        drop_path_rate=0.1),
    decode_head=dict(
        type='SegformerHead',
        in_channels=[32, 64, 160, 256],
        in_index=[0, 1, 2, 3],
        channels=256,
        dropout_ratio=0.1,
        num_classes=19,
        norm_cfg=norm_cfg,
        align_corners=False,
        loss_decode=dict(
            type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)),
    # model training and testing settings
    train_cfg=dict(),
    test_cfg=dict(mode='whole'))

这里就是一些模型的参数等等,同样复制这个文件粘贴到baseline.py,剩下的'../base/default_runtime.py', '../base/schedules/schedule_160k.py'这两个文件以此类推进行复制粘贴。这里可以发现官方介绍没有CHASEDB1数据集格式,但是我们采用了,读者要根据自己的实际需求去模块化穿插就行了。

经过上述处理,可以得到一个完整的baseline.py,这样把这些内容复制粘贴到一个文件,可以避免对其他文件进行改动,接下来按照实际对baseline.py进行修改

修改1:

 num_classes需要按照自己的实际情况进行修改,我这里是分割牙齿,因此num_classes是1+1=2(需要算上背景),调整完数据集格式,需要到mmsegmentation/mmseg/datasets/chase_db1.py里面去调整自己的标签名字和数据集格式

 修改2:

然后需要更改数据存放的位置,'/content/drive/MyDrive/Dataset/CHASE_DB1/'就是我们数据集在谷歌云盘存储的位置

截至这里,初步的一些操作都已经完成,接下来将整个mmsegmentation文件夹上传到谷歌云盘,也可以将configs文件里面除了我们自己的文件夹(我的叫做teeth_seg),其他都删掉上传
上传完成之后谷歌云盘如上

5 在Colab中使用数据

1、选择高性能运行环境

 点击右上角的向下箭头,出现菜单栏,接着选择查看资源
 

 点击更改运行时类型
 

选择T4 GPU,这样就可以使(bai)用(piao)谷歌的云算力

 2、链接Colab和谷歌云盘

from google.colab import drive
drive.mount('/content/drive')

 点击这个类似播放按钮运行这个单元,运行完成之后会提示“Mounted at /content/drive“

使用下述指令,将当前目录跳转到mmsegmentation中:

!cd /content/drive/MyDrive/mmsegmentation

安装需要的库:

!pip install openmim
!mim install mmengine
!mim install mmcv
!mim install mmsegmentation

这里需要替换到mmseg中datasets里面chase_db1.py这个文件,因为我们刚才对这个文件夹进行了修改,指令如下:

%cd /usr/local/lib/python3.10/dist-packages/mmseg/datasets
!rm chase_db1.py
!cp /content/drive/MyDrive/mmsegmentation/mmseg/datasets/chase_db1.py chase_db1.py

/usr/local/lib/python3.10/ 这个路径是mmseg下载保存的位置,可能会不一样,可以打印路径查看到底放在lib里面那个版本的python中

这里是打印datasets文件夹内文件的示例,可以按照实际需求进行更改

3、运行baseline.py

首先确保当前路径在mmsegmentation中,以防万一,可以先cd到这个文件夹

!cd /content/drive/MyDrive/mmsegmentation

然后是计算参数量,这一步可以测试baseline.py代码的逻辑是否存在问题

!python /content/drive/MyDrive/mmsegmentation/tools/analysis_tools/get_flops.py /content/drive/MyDrive/mmsegmentation/configs/teeth_seg/baseline.py

如果成功打印出参数量和计算量,就可以开始训练模型

!python tools/train.py configs/teeth_seg/baseline.py --work-dir work_dir/baseline

测试代码:

!python tools/test.py configs/teeth_seg/baseline.py work_dir/baseline/iter_40000.pth  --out test_result/baseline/iter_40000.pkl --show-dir test_result/baseline

这里为了快,只训练了40000轮,按照上述流程应该训练的是160000轮。测试结果(左图label,右图是预测结果):

这里只是介绍快速入手,更多的训练和测试详细使用可以参阅官方给的文档:教程4:使用现有模型进行训练和测试 — MMSegmentation 1.1.1 文档

这里介绍的是在colab上使用的情况,在本地使用流程相似,在本地新建一个notebook用来执行指令,然后更改文件路径

mmsegmentation是一个很便于使用的工具箱,读者在了解如何进行基础训练之后可以更多关注mmseg这个文件中对各种模型模块化的设计
 

读者可以根据自己的需要,在mmseg中进行修改,需要注意的是:修改完上传到云盘后,记得按照刚才的指令把文件和user中的文件替换一下。

这里以添加loss为例子,读者在新建python文件设计了自己的loss function之后,需要在init.py中声明一下,然后才可以在baseline.py中使用。

以上就是本博客的所有内容,仅限快速入门使用这个工具箱,后续如果有深入使用技巧,会持续更新,有问题欢迎留言或私信提问

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值