從零開始使用MMSegmentation訓(xùn)練Segformer
寫在前面:最新想要用最新的分割算法如:Segformer or SegNeXt 在自己的數(shù)據(jù)集上進(jìn)行訓(xùn)練,但是有不是搞語義分割出身的,而且也沒有系統(tǒng)的學(xué)過MMCV以及MMSegmentation。所以就折騰了很久,感覺利用MMSegmentation搭建框架可能比較系統(tǒng),但是對(duì)于不熟悉的或者初學(xué)者非常不友好,因此記錄一下自己training Segformer的心路歷程。
Segformer paper: https://arxiv.org/abs/2105.15203>
官方實(shí)現(xiàn): https://github.com/NVlabs/SegFormer>
純Torch版Segformer: https://github.com/camlaedtke/segmentation_pytorch
方法
由于本人不是研究語義分割的,所以只能簡(jiǎn)要地介紹一下Segformer。
SegFormer的動(dòng)機(jī)在于:
① ViT作為backbone只能輸出固定分辨率的特征圖,這對(duì)于密集預(yù)測(cè)任務(wù)顯然不夠友好;
② 由于self-attention操作的存在,transformer的運(yùn)算量和參數(shù)兩都非常大,不利于大尺度圖像的分割。
為此作者提出了相應(yīng)的創(chuàng)新:
① 先是對(duì)transformer進(jìn)行層次化結(jié)構(gòu)設(shè)計(jì),得到多層級(jí)的特征圖;
② 構(gòu)造輕量級(jí)的decoder,僅使用MLP進(jìn)行特征聚合。
③ 除此之外,SegFormer拋棄了位置信息編碼,選擇采用MixFCN來學(xué)習(xí)位置信息,這樣可以很好地?cái)U(kuò)充到不同尺度的測(cè)試環(huán)境下(避免由于尺寸變化,需要對(duì)positional-encoding進(jìn)行插值,從而影響性能)。最后提出的模型在ADE20k上達(dá)到了新sota,并且在速度、性能和魯棒性上都表現(xiàn)很好。
程序復(fù)現(xiàn)
在重新訓(xùn)練過程中主要參考了:手把手教你使用Segformer訓(xùn)練自己的數(shù)據(jù)
作者給的教程比較詳細(xì), 但是有幾處修改并不合適,導(dǎo)致我復(fù)現(xiàn)出來的結(jié)果沒啥效果,因此記錄一下自己的采坑記錄。
自己的主要配置為:
CUDA 10.1
Pytorch 1.10.0, torchvision 0.11.1
MMCV-full 1.3.0
其中在安裝MMCV-full過程中還遇到了很多問題,主要是版本不適配的原因?qū)е碌摹?br> 在安裝好環(huán)境后,首先從Github下載SegFormer的項(xiàng)目工程: https://github.com/NVlabs/SegFormer
然后進(jìn)去SegFormer目錄:
pip install -r requirements.txt
pip install -e . --user
安裝需要的依賴。
數(shù)據(jù)集準(zhǔn)備
代碼默認(rèn)用的是ADE20K數(shù)據(jù)集進(jìn)行訓(xùn)練
ADE20K數(shù)據(jù)集 格式如下,按照要求放就完了
├── data
│ ├── ade
│ │ ├── ADEChallengeData2016
│ │ │ ├── annotations
│ │ │ │ ├── training
│ │ │ │ ├── validation
│ │ │ ├── images
│ │ │ │ ├── training
│ │ │ │ ├── validation
但是@中科哥哥使用的是VOC的數(shù)據(jù)格式,因此就使用了VOC的數(shù)據(jù)格式
├── VOCdevkit
│ ├── VOC2012
│ │ ├── ImageSets
│ │ │ ├── Segmentation
│ │ │ │ ├── train.txt
│ │ │ │ ├── val.txt
│ │ │ │ ├── trainval.txt
│ │ │ ├── JPEGImages
│ │ │ │ ├── *.jpg #所有圖片
│ │ │ ├── SegmentationClass
│ │ │ │ ├── *.jpg #所有標(biāo)簽圖
在這里可以根據(jù)自己的需要修改
下面是我自己的數(shù)據(jù)格式:
├── VOCdevkit
│ ├── VOC2012
│ │ ├── ImageSets
│ │ │ ├── Segmentation
│ │ │ │ ├── train.txt
│ │ │ │ ├── val.txt
│ │ │ │ ├── test.txt
│ │ │ ├── JPEGImages
│ │ │ │ ├── *.png#所有圖片
│ │ │ ├── SegmentationClass
│ │ │ │ ├── *.png #所有標(biāo)簽圖
其實(shí)完全可以簡(jiǎn)潔一點(diǎn):
├── MFNet
│ ├── Segmentation
│ │ ├── train.txt
│ │ ├── val.txt
│ │ ├── test.txt
│ ├── Images
│ │ ├── *.png#所有圖片
│ ├── Label
│ │ ├── *.png #所有標(biāo)簽圖
其中: train.txt; val.txt; test.txt; 只要圖片名,不需要后綴和路徑 如下
后面的程序修改都基于復(fù)雜的版本進(jìn)行介紹(自己在程序復(fù)現(xiàn)時(shí)使用的復(fù)雜的目錄,因?yàn)槭前凑盏慕坛虂淼模?br> 數(shù)據(jù)準(zhǔn)備好 之后可以在SegFormer目錄先新建一個(gè)/datasets/ 目錄來存放自己的數(shù)據(jù)集
程序修改
-
在 mmseg/datasets/voc.py修改自己數(shù)據(jù)集的類別即修改CLASSES 和 PALETTE在我自己的數(shù)據(jù)集中一共由于9個(gè)類別,所以修改如下:
-
在 mmseg/models/decode_heads/segformer_head.py 中BatchNorm 方式(如果使用單卡訓(xùn)練的話就修改,多卡訓(xùn)練的話就不用修改)。 將第59行的SyncBN 修改為 BN
-
修改 local_configs/segformer/B5/segformer.b5.640x640.ade.160k.py 的配置文件(這里我們使用的是B5模型,需要使用哪個(gè)模型就修改對(duì)應(yīng)的配置文件即可,配置文件都位于:**local_configs/segformer/**下 );主要修改
__base__=[]中的數(shù)據(jù)集文件路徑(也就是下圖中的第二行)
指定dataset_type的類型,此處
dataset_type = 'PascalVOCDataset'
data_root = '/data1/timer/Segmentation/SegFormer/datasets/VOC2012' 也可以給相對(duì)路徑。
然后根據(jù)自己的數(shù)據(jù)需要修改文件中的crop_size, train_pipline中的img_scale,以及test_pipline中的img_scale
同時(shí)還需要在data字典中指定 img_dir, ann_dir, 以及split的路徑,如果是單卡訓(xùn)練的話需要將norm_cfg 的type由的SyncBN 修改為 BN
接下來繼續(xù)修改模型相關(guān)的文件,主要是給定預(yù)訓(xùn)練權(quán)重的位置即修改:pretrained 以及backbone[‘type’],這里的type因?yàn)槭褂玫氖荁5的結(jié)構(gòu)所以type就指定為mit_b5,然后預(yù)訓(xùn)練權(quán)重需要從項(xiàng)目中給定的鏈接下載。值得注意的是還需要指定decode_head[‘num_classes’] (這個(gè)需要根據(jù)你的數(shù)據(jù)集來指定,因?yàn)槲业臄?shù)據(jù)集中包含9類,所以這里就設(shè)置為9了)
- 在 local_configs/base/models/segformer.py 修改
norm_cfg[‘type’]=‘BN’
num_classes=9 (這里修改成你數(shù)據(jù)集對(duì)應(yīng)的類別的數(shù)量)
5. 在 tools/train.py中修改
parser.add_argument('--config', default='/data1/timer/Segmentation/SegFormer/local_configs/segformer/B5/segformer.b5.640x640.ade.160k.py')
parser.add_argument('--work-dir', default='res_MFNet')
其中 /data1/timer/Segmentation/SegFormer/local_configs/segformer/B5/segformer.b5.640x640.ade.160k.py 是配置文件的路徑
res_MFNet是訓(xùn)練日志和模型保存的路徑
同時(shí)指定GPU的卡號(hào)
group_gpus.add_argument(
'--gpu-ids',
type=int,
default=[0],
help='ids of gpus to use '
'(only applicable to non-distributed training)')
6. 進(jìn)入tools目錄下運(yùn)行文章來源:http://www.zghlxwxcb.cn/news/detail-484590.html
python train.py
即可開始訓(xùn)練模型。
由于本人也在摸索階段,有不當(dāng)之處,懇請(qǐng)各位不吝賜教。也歡迎大家交流:2458707789@qq.com文章來源地址http://www.zghlxwxcb.cn/news/detail-484590.html
到了這里,關(guān)于從零開始使用MMSegmentation訓(xùn)練Segformer的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!