一、MMSegmentation介紹
MMSegmentation是openmmlab項目下開源的圖像語義分割框架,目前支持pytorch,由于其擁有pipeline加速,完善的數(shù)據(jù)增強體系,完善的模型庫,作為大數(shù)據(jù)語義分割訓練及測試的代碼框架是再好不過了。
二、MMSegmentation基本框架
理解MMSeg最重要的就是弄懂Config文件,共有4類:
(1)model config
(2)dataset config
(3)runtime config
(4)schedule config
如果你想知道為什么分成這四大類,請參考本文附錄部分,對這個不感興趣就繼續(xù)往下看。其實3和4大多數(shù)人都用不到的,重點還是在1和2,下面就從這兩個角度給大家來一個不算精細的講解。
1、model設置
如果采用的是MMSegmentation里面支持的模型,那么固然是不需要自己寫class了,自己挑一個模型就可以了。這些model的目錄保存在了configs/_base/models里面了。
models文件夾下的模型名稱:第一個下劃線前面的都好理解,就是模型的名字,那r50-d8可能就是resnet的類型了,有人會問,那resnet101和resnet152哪去了,別急,其實這些只是baseline,它的backbone是可以改的,比如說我們要使用的是danet_r50-d8.py,我們先打開它(這部分,如果需要單GPU訓練,將SyncBN改成BN):
只需要把model.backbone.depth設為101或者152就可以使用resnet101或者resnet152啦,如果你的本地沒有模型,mmSeg就會從model_zoo里面下載一個,如果本地有(應該是保存在了checkpoint里面),則自動加載本地的,不會重復下載。其他的操作后面會講,另外如果你是多GPU操作就選擇使用SyncBN,否則就使用BN就可以了。如果使用了SyncBN卻只有一塊可用的GPU,那可能會報類似AssertionError:Default process group is not initialized的錯誤。有人可能問那我直接改了這個文件不就把原來的默認參數(shù)給覆蓋了嘛,不要緊,看到后面大家就會明白這個問題很容易解決,這里只是給大家做一個demo。
2、dataset設置
數(shù)據(jù)集設置比model的稍微復雜一點,這里會直接定義一個自己的數(shù)據(jù)集(Custom Dataset)來說明其原理。數(shù)據(jù)集需要準備的文件有三個:
(1)Dataset Class文件
(2)Dataset Config文件
(3)Total Config文件
在第四章中1節(jié)提到的config文件就是Total config(頂層設置文件),也是train.py文件直接調(diào)用的config文件,而Dataset Class文件是用來定義數(shù)據(jù)集的類別數(shù)和標簽名稱的,Dataset Config文件則是用來定義數(shù)據(jù)集目錄、數(shù)據(jù)集信息(例如圖片大?。?、數(shù)據(jù)增強操作以及pipeline的。
2.1 Dataset Class文件配置
首先來說Dataset Class文件,這個文件存放在 mmseg/datasets/ 目錄下:
在這個目錄下自己建一個數(shù)據(jù)集文件,并命個名,我這里命名為:my_custom.py。配置文件實際上是繼承該目錄下custom.py當中的CustomDataset父類的,這樣寫起了就簡單多了,大多數(shù)情況下(當你的數(shù)據(jù)集是以一張張圖片出現(xiàn)并且可用PIL模塊讀入時),你只需要設置兩個參數(shù)即可——類別標簽名稱(CLASSES)和類別標簽上色的RGB顏色(PALETTE)。以我的配置文件為例,代碼如下:
代碼中的img_suffix和seg_map_suffix分別是你的數(shù)據(jù)集圖片的后綴和標簽圖片的后綴,因個人差異而定,tif格式的圖片還沒有試過,但是jpg和png的肯定是可以的。
設置好之后記得保存在mmseg/datasets/目錄下(我的文件名叫my_custom.py)。另外還需要設置一下該目錄下的__init__文件:
需要改兩個地方,①import的時候要把自己的Dataset加載進來,②__all__數(shù)組里面需要加入自己的Dataset類名稱,修改完成之后保存。這兩部操作完成之后還不行,由于訓練的時候需要txt文件指示訓練集、驗證集和測試集的txt文件,一開始我以為這只是一個optional option,但無奈Custom Dataset的__init___下面給我來了一句assert osp.exists(self.img_dir) and self.split is not None,那好吧,不知道刪了and后面的條件會有什么后果,還是自己創(chuàng)一個吧,寫來一個簡單的劃分數(shù)據(jù)集并保存到txt的demo,大家可以把這個py文件放到你的數(shù)據(jù)集上一級目錄上并對著稍微改改:
import mmcv
import os.path as osp
data_root = "/data3/datasets/Custom/Lab/Segmentation/"
ann_dir = "ann_png1"
split_dir = 'splits'
mmcv.mkdir_or_exist(osp.join(data_root, split_dir))
filename_list = [osp.splitext(filename)[0] for filename in mmcv.scandir(
osp.join(data_root, ann_dir), suffix='.png')]
with open(osp.join(data_root, split_dir, 'train.txt'), 'w') as f:
# select first 4/5 as train set
train_length = int(len(filename_list)*4/5)
f.writelines(line + '\n' for line in filename_list[:train_length])
with open(osp.join(data_root, split_dir, 'val.txt'), 'w') as f:
# select last 1/5 as train set
f.writelines(line + '\n' for line in filename_list[train_length:])
data_root寫自己的工作目錄名稱,ann_dir寫標簽圖片所在的目錄,split_dir則是在data_root下生成split txt文件保存的文件夾目錄,其他的就不需要怎么改了。如果你在data_root/split_dir/下成功找到了train.txt和val.txt文件,就沒有問題了。
2.2 Dataset Config文件配置
Dataset Config文件在 configs/base/datasets 目錄下,需要自己新建一個xxx.py文件。
以我自己的Custom Dataset(idrid.py)為例,它的書寫格式如下:
# dataset settings
"""
rgb mean:
[116.51282647 56.43716432 16.30857136]
rgb std:
[80.20605713 41.23209693 13.29250962]
"""
dataset_type = 'LesionDataset'
# data_root = '../data/IDRID'
data_root = '/home/pengdao.xu/python/pytorch/M2MRF-Lesion-Segmentation/data/IDRID'
img_norm_cfg = dict(
mean=[116.513, 56.437, 16.309], std=[80.206, 41.232, 13.293], to_rgb=True)
image_scale = (1440, 960)
crop_size = (960, 1440)
palette = [
[0, 0, 0],
[128, 0, 0], # EX: red
[0, 128, 0], # HE: green
[128, 128, 0], # SE: yellow
[0, 0, 128] # MA: blue
]
classes = ['bg', 'EX', 'HE', 'SE', 'MA']
train_pipeline = [
dict(type='LoadImageFromFile'),
dict(type='LoadAnnotations'),
dict(type='Resize', img_scale=image_scale, ratio_range=(0.5, 2.0)),
dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),
dict(type='RandomFlip', flip_ratio=0),
dict(type='PhotoMetricDistortion'),
dict(type='Normalize', **img_norm_cfg),
dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=0),
dict(type='DefaultFormatBundle'),
dict(type='Collect', keys=['img', 'gt_semantic_seg']),
]
test_pipeline = [
dict(type='LoadImageFromFile'),
dict(
type='MultiScaleFlipAug',
img_scale=image_scale,
# img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],
flip=False,
transforms=[
dict(type='Resize', keep_ratio=True),
# dict(type='RandomFlip'),
dict(type='Normalize', **img_norm_cfg),
dict(type='ImageToTensor', keys=['img']),
dict(type='Collect', keys=['img']),
])
]
data = dict(
samples_per_gpu=1,
workers_per_gpu=1,
train=dict(
img_dir='image/train',
ann_dir='label/train/annotations',
data_root=data_root,
classes=classes,
palette=palette,
type=dataset_type,
pipeline=train_pipeline),
val=dict(
img_dir='image/test',
ann_dir='label/test/annotations',
data_root=data_root,
classes=classes,
palette=palette,
type=dataset_type,
pipeline=test_pipeline),
test=dict(
img_dir='image/test',
ann_dir='label/test/annotations',
data_root=data_root,
classes=classes,
palette=palette,
type=dataset_type,
pipeline=test_pipeline))
需要改的地方有以下幾個:
(1)img_norm_cfg:數(shù)據(jù)集的方差和均值
(2)crop_size:數(shù)據(jù)增強時裁剪的大小. img_dir:
(3)img_scale:原圖像尺寸
(4)data_root:工作目錄
(5)img_dir:工作目錄下存圖片的目錄
(6)ann_dir:工作目錄下存標簽的目錄
(7)split:之前操作做txt文件的目錄(我這里沒有用到)
(8)sample_per_gpu:batch size
(9)workers_per_gpu:dataloader的線程數(shù)目,一般設2,4,8,根據(jù)CPU核數(shù)確定,或使用os.cpu_count()函數(shù)代替
(10)PhotoMetricDistortion是數(shù)據(jù)增強操作,有四個參數(shù)(參考博客)分別是亮度、對比度、飽和度和色調(diào),它們的默認設定如下:
brightness_delta=32; # 32
contrast_range=(0.5, 1.5); # (0.5, 1.5),下限-上限
saturation_range=(0.5, 1.5); # (0.5, 1.5),下限-上限
hue_delta=18; # 18
如果不想使用默認設定,仿照其他選項將自定義參數(shù)寫在后面即可,例如
dict(type='PhotoMetricDistortion',contrast_range=(0.5, 1.0))
改好之后保存 configs/base/datasets 目錄下。
2.3 Total Config文件配置
Total Config文件是train.py直接調(diào)用的config文件,在第四章中1也有介紹,在此只說明如何即可。該文件在 config/ 目錄下的xxx(model名),你選用的是哪一個model,就選擇哪一個目錄。
以m2mrf為例,我們書寫一個total config文件,并保存在configs/m2mrf的文件夾下:
_base_ = [
'../_base_/models/fcn_hr48.py',
'../_base_/datasets/idrid.py',
'../_base_/default_runtime.py',
'../_base_/schedules/schedule_40k_idrid.py'
]
model = dict(
use_sigmoid=True,
backbone=dict(
type='HRNet_M2MRF_C', # DownSample/UpSample: Cascade/One-Step
m2mrf_patch_size=(8, 8),
m2mrf_encode_channels_rate=4,
m2mrf_fc_channels_rate=64,
),
decode_head=dict(
num_classes=4,
loss_decode=dict(type='BinaryLoss', loss_type='dice', loss_weight=1.0, smooth=1e-5)
)
)
test_cfg = dict(mode='whole', compute_aupr=True)
這個代碼就一個__base__的數(shù)組,第一個元素代表模型路徑,也就是在第二章1中介紹的模型文件;第二個元素代表數(shù)據(jù)集的Dataset config文件(第二章中2.2 Dataset Config文件配置 );第三個元素和第四個元素本教程未涉及到,按照默認參數(shù)寫也沒有太大問題,如果想修改訓練的代數(shù)以及l(fā)og和save的頻率就修改第4元素及響應文件,在此就不再贅述了。另外如果你的模型不是19類的(因為是原模型是根據(jù)cityscapes寫的,輸出通道為19),需按照上面修改一下。
三、運行代碼
在項目目錄下,輸入python tools/train.py xxxconfig.py --work-dir=xxx即可運行,其中xxxconfig.py就是我們剛剛保存的Total config文件(記得要把完整路徑也加上),work-dir其實就是保存log和model的目錄(如果沒有會自己創(chuàng)建)。如果發(fā)現(xiàn)import mmseg找不到這個包,那八成是調(diào)試器運行目錄不在根目錄下造成的,要不就配置run的目錄,要不就直接吧tools/train.py復制到根目錄下運行。運行結(jié)果差不多是這樣:
四、附錄
1、MMSegmentation框架解釋
在MMSegmentation的項目目錄下,打開**Configs/**下面的目錄
隨便打開一個文件(如上圖選中.py文件),可以看到:
_base_ = [
'../_base_/models/fcn_hr48.py',
'../_base_/datasets/idrid.py',
'../_base_/default_runtime.py',
'../_base_/schedules/schedule_40k_idrid.py'
]
model = dict(
use_sigmoid=True,
backbone=dict(
type='HRNet_M2MRF_C', # DownSample/UpSample: Cascade/One-Step
m2mrf_patch_size=(8, 8),
m2mrf_encode_channels_rate=4,
m2mrf_fc_channels_rate=64,
),
decode_head=dict(
num_classes=4,
loss_decode=dict(type='BinaryLoss', loss_type='dice', loss_weight=1.0, smooth=1e-5)
)
)
test_cfg = dict(mode='whole', compute_aupr=True)
從文件的名字也可以看出,它是模型(baseline+backbone、數(shù)據(jù)集、schedule的組合(runtime是default設置,就沒包含在名稱內(nèi))。
2、MMSegmentation使用的預訓練backbone
預訓練backbone下載鏈接為:
mmcv預訓練模型下載地址(.json文件,復制對應模型的鏈接即可下載)
{
"vgg16_caffe": "https://download.openmmlab.com/pretrain/third_party/vgg16_caffe-292e1171.pth",
"detectron/resnet50_caffe": "https://download.openmmlab.com/pretrain/third_party/resnet50_caffe-788b5fa3.pth",
"detectron2/resnet50_caffe": "https://download.openmmlab.com/pretrain/third_party/resnet50_msra-5891d200.pth",
"detectron/resnet101_caffe": "https://download.openmmlab.com/pretrain/third_party/resnet101_caffe-3ad79236.pth",
"detectron2/resnet101_caffe": "https://download.openmmlab.com/pretrain/third_party/resnet101_msra-6cc46731.pth",
"detectron2/resnext101_32x8d": "https://download.openmmlab.com/pretrain/third_party/resnext101_32x8d-1516f1aa.pth",
"resnext50_32x4d": "https://download.openmmlab.com/pretrain/third_party/resnext50-32x4d-0ab1a123.pth",
"resnext101_32x4d": "https://download.openmmlab.com/pretrain/third_party/resnext101_32x4d-a5af3160.pth",
"resnext101_64x4d": "https://download.openmmlab.com/pretrain/third_party/resnext101_64x4d-ee2c6f71.pth",
"contrib/resnet50_gn": "https://download.openmmlab.com/pretrain/third_party/resnet50_gn_thangvubk-ad1730dd.pth",
"detectron/resnet50_gn": "https://download.openmmlab.com/pretrain/third_party/resnet50_gn-9186a21c.pth",
"detectron/resnet101_gn": "https://download.openmmlab.com/pretrain/third_party/resnet101_gn-cac0ab98.pth",
"jhu/resnet50_gn_ws": "https://download.openmmlab.com/pretrain/third_party/resnet50_gn_ws-15beedd8.pth",
"jhu/resnet101_gn_ws": "https://download.openmmlab.com/pretrain/third_party/resnet101_gn_ws-3e3c308c.pth",
"jhu/resnext50_32x4d_gn_ws": "https://download.openmmlab.com/pretrain/third_party/resnext50_32x4d_gn_ws-0d87ac85.pth",
"jhu/resnext101_32x4d_gn_ws": "https://download.openmmlab.com/pretrain/third_party/resnext101_32x4d_gn_ws-34ac1a9e.pth",
"jhu/resnext50_32x4d_gn": "https://download.openmmlab.com/pretrain/third_party/resnext50_32x4d_gn-c7e8b754.pth",
"jhu/resnext101_32x4d_gn": "https://download.openmmlab.com/pretrain/third_party/resnext101_32x4d_gn-ac3bb84e.pth",
"msra/hrnetv2_w18_small": "https://download.openmmlab.com/pretrain/third_party/hrnetv2_w18_small-b5a04e21.pth",
"msra/hrnetv2_w18": "https://download.openmmlab.com/pretrain/third_party/hrnetv2_w18-00eb2006.pth",
"msra/hrnetv2_w32": "https://download.openmmlab.com/pretrain/third_party/hrnetv2_w32-dc9eeb4f.pth",
"msra/hrnetv2_w40": "https://download.openmmlab.com/pretrain/third_party/hrnetv2_w40-ed0b031c.pth",
"msra/hrnetv2_w48": "https://download.openmmlab.com/pretrain/third_party/hrnetv2_w48-d2186c55.pth",
"bninception_caffe": "https://download.openmmlab.com/pretrain/third_party/bn_inception_caffe-ed2e8665.pth",
"kin400/i3d_r50_f32s2_k400": "https://download.openmmlab.com/pretrain/third_party/i3d_r50_f32s2_k400-2c57e077.pth",
"kin400/nl3d_r50_f32s2_k400": "https://download.openmmlab.com/pretrain/third_party/nl3d_r50_f32s2_k400-fa7e7caa.pth",
"res2net101_v1d_26w_4s": "https://download.openmmlab.com/pretrain/third_party/res2net101_v1d_26w_4s_mmdetv2-f0a600f9.pth",
"regnetx_400mf": "https://download.openmmlab.com/pretrain/third_party/regnetx_400mf-a5b10d96.pth",
"regnetx_800mf": "https://download.openmmlab.com/pretrain/third_party/regnetx_800mf-1f4be4c7.pth",
"regnetx_1.6gf": "https://download.openmmlab.com/pretrain/third_party/regnetx_1.6gf-5791c176.pth",
"regnetx_3.2gf": "https://download.openmmlab.com/pretrain/third_party/regnetx_3.2gf-c2599b0f.pth",
"regnetx_4.0gf": "https://download.openmmlab.com/pretrain/third_party/regnetx_4.0gf-a88f671e.pth",
"regnetx_6.4gf": "https://download.openmmlab.com/pretrain/third_party/regnetx_6.4gf-006af45d.pth",
"regnetx_8.0gf": "https://download.openmmlab.com/pretrain/third_party/regnetx_8.0gf-3c68abe7.pth",
"regnetx_12gf": "https://download.openmmlab.com/pretrain/third_party/regnetx_12gf-4c2a3350.pth",
"resnet18_v1c": "https://download.openmmlab.com/pretrain/third_party/resnet18_v1c-b5776b93.pth",
"resnet50_v1c": "https://download.openmmlab.com/pretrain/third_party/resnet50_v1c-2cccc1ad.pth",
"resnet101_v1c": "https://download.openmmlab.com/pretrain/third_party/resnet101_v1c-e67eebb6.pth",
"mmedit/vgg16": "https://download.openmmlab.com/mmediting/third_party/vgg_state_dict.pth",
"mmedit/res34_en_nomixup": "https://download.openmmlab.com/mmediting/third_party/model_best_resnet34_En_nomixup.pth",
"mmedit/mobilenet_v2": "https://download.openmmlab.com/mmediting/third_party/mobilenet_v2.pth",
"contrib/mobilenet_v3_large": "https://download.openmmlab.com/pretrain/third_party/mobilenet_v3_large-bc2c3fd3.pth",
"contrib/mobilenet_v3_small": "https://download.openmmlab.com/pretrain/third_party/mobilenet_v3_small-47085aa1.pth",
"resnest50": "https://download.openmmlab.com/pretrain/third_party/resnest50_d2-7497a55b.pth",
"resnest101": "https://download.openmmlab.com/pretrain/third_party/resnest101_d2-f3b931b2.pth",
"resnest200": "https://download.openmmlab.com/pretrain/third_party/resnest200_d2-ca88e41f.pth",
"darknet53": "https://download.openmmlab.com/pretrain/third_party/darknet53-a628ea1b.pth",
"mmdet/mobilenet_v2": "https://download.openmmlab.com/mmdetection/v2.0/third_party/mobilenet_v2_batch256_imagenet-ff34753d.pth"
}
3、官方幫助文檔
可在**docs/**中查看
希望本文對您有幫助,謝謝閱讀!文章來源:http://www.zghlxwxcb.cn/news/detail-768164.html
參考文章來源
以上是我參考另一位博主的文章以及自己實現(xiàn)過程進行綜合完成的,博主的文章來源:https://blog.csdn.net/weixin_44044411/article/details/118196847?spm=1001.2014.3001.5506文章來源地址http://www.zghlxwxcb.cn/news/detail-768164.html
到了這里,關于【Python:Pycharm】mmSegmentation語義分割框架教程的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!