mmsegmentation实战一:ISBI2012数据实战

2023-05-16

文章目录

  • 一、数据格式转换
  • 二、dataset class文件配置;
    • 1.设置数据集文件
    • 2.修改mmseg/datasets/目录下的_init_.py
  • 三、在configs/_ base _/datasets下面对数据加载进行定义
  • 四、在configs/下面选择你需要的模型参数进行修改
  • 五、返回tools/train.py进行训练
  • 六、推理


一、数据格式转换

在tools/convert_datasets路径下新建ISBI2012.py,使得原本的tif格式数据能被程序读取。

# Copyright (c) OpenMMLab. All rights reserved.
import argparse
import cv2
import os
import os.path as osp
import tempfile
import zipfile
from skimage import io


import mmcv



def parse_args():
    parser = argparse.ArgumentParser(
        description='Convert ISBI2012 dataset to mmsegmentation format')

    # No "--" means use default paraments

    parser.add_argument('--dataset_path', default="openmmlab/dataset/ISBI2012/", help='path of ISBI2012 DATASET')
    parser.add_argument('--tmp_dir', help='path of the temporary directory')
    parser.add_argument('-o', '--out_dir', help='output path')
    args = parser.parse_args()
    return args


def main():
    ISBI2012_TRAIN = 20
    args = parse_args()

    dataset_path = args.dataset_path
    if args.out_dir is None:
        out_dir = osp.join('data', 'ISBI2012')
    else:
        out_dir = args.out_dir

    print('Making directories...')
    mmcv.mkdir_or_exist(out_dir)
    mmcv.mkdir_or_exist(osp.join(out_dir, 'images'))
    mmcv.mkdir_or_exist(osp.join(out_dir, 'images', 'training'))
    mmcv.mkdir_or_exist(osp.join(out_dir, 'images', 'validation'))
    mmcv.mkdir_or_exist(osp.join(out_dir, 'images', 'test'))
    mmcv.mkdir_or_exist(osp.join(out_dir, 'annotations'))
    mmcv.mkdir_or_exist(osp.join(out_dir, 'annotations', 'training'))
    mmcv.mkdir_or_exist(osp.join(out_dir, 'annotations', 'validation'))


    train_volume = io.imread(osp.join(dataset_path, "train-volume.tif"))
    train_labels = io.imread(osp.join(dataset_path, "train-labels.tif"))
    train_labels[train_labels == 255] = 1
    train_labels = 1 - train_labels
    test_volume = io.imread(osp.join(dataset_path, "test-volume.tif"))

    print('Generating training dataset...')
    for raw_index in range(0, ISBI2012_TRAIN):
        cv2.imwrite(osp.join(out_dir, 'images', 'training',
                           "%05d"%raw_index + '.png'), train_volume[raw_index, :, :], [cv2.IMWRITE_PNG_COMPRESSION, 0])
    
    print('Generating training label...')
    for label_index in range(0, ISBI2012_TRAIN):
        cv2.imwrite(osp.join(out_dir, 'annotations', 'training',
                           "%05d"%label_index + '.png'), train_labels[label_index, :, :], [cv2.IMWRITE_PNG_COMPRESSION, 0])



    print('Generating validation dataset...')
    for raw_index in range(ISBI2012_TRAIN, train_volume.shape[0]):
        cv2.imwrite(osp.join(out_dir, 'images', 'validation',
                           "%05d"%raw_index + '.png'), train_volume[raw_index, :, :], [cv2.IMWRITE_PNG_COMPRESSION, 0])


    print('Generating validation label...')
    for label_index in range(ISBI2012_TRAIN, train_labels.shape[0]):
        cv2.imwrite(osp.join(out_dir, 'annotations', 'validation',
                           "%05d"%label_index + '.png'), train_labels[label_index, :, :], [cv2.IMWRITE_PNG_COMPRESSION, 0])

    print('Generating test dataset...')
    for raw_index in range(test_volume.shape[0]):
        cv2.imwrite(osp.join(out_dir, 'images', 'test',
                           "%05d"%raw_index + '.png'), test_volume[raw_index, :, :], [cv2.IMWRITE_PNG_COMPRESSION, 0])

    print('Done!')


if __name__ == '__main__':
    main()
    print("ok")

运行完成后,得到的效果如图所示:

在这里插入图片描述
由于ISBI2012数据集是灰度图,但mmsegmentation整个环境是基于彩色图编写,mmcv库默认读入进行转化,这里直接保存为灰度即可

https://github.com/open-mmlab/mmdetection/issues/178

二、dataset class文件配置;

1.设置数据集文件

在mmseg/datasets/目录下新建ISBI2012.py文件

# Copyright (c) OpenMMLab. All rights reserved.

from .builder import DATASETS
from .custom import CustomDataset


@DATASETS.register_module()
class ISBI2012Dataset(CustomDataset):
    """Isbi2012 dataset.

    In segmentation map annotation for Isbi2012, 0 stands for background,
    which is included in 2 categories. ``reduce_zero_label`` is fixed to False.
    The ``img_suffix`` is fixed to '.png' and ``seg_map_suffix`` is fixed to
    '.png'.
    """

    CLASSES = ('background', 'membrane')

    PALETTE = [[120, 120, 120], [6, 230, 230]]

    def __init__(self, **kwargs):
        super(ISBI2012Dataset, self).__init__(
            img_suffix='.png',
            seg_map_suffix='.png',
            reduce_zero_label=False,
            **kwargs)
        assert self.file_client.exists(self.img_dir)

其中
ISBI2012Dataset:表示自定义的数据集
CLASSES:表示你数据集的背景+类别
PALETTE:训练完后进行测试后的结果保存,mmseg默认为把分割出来的mask结果直接画在原图上进行显示,PALETTE好像指定了画上原图的mask蒙版的颜色。
img_suffix:原图图像后缀
seg_map_suffix:mask图像后缀

注意:mmseg要求mask的像素在[0,num_classes-1]范围内,比如我是2分类,背景像素值为0,那么目标像素值应该为1。如果你也是二分类,mask为单通道(8 bit)二值化的0(背景)/255(目标)图像的话,先去把图像改为0(背景)/1(目标)图像,否则能跑起来,但是指标异常,几乎全是0。(这是个大坑!!!一定要注意)

2.修改mmseg/datasets/目录下的_init_.py

末尾加入Isbi2012Dataset数据

# Copyright (c) OpenMMLab. All rights reserved.
from .ade import ADE20KDataset
from .builder import DATASETS, PIPELINES, build_dataloader, build_dataset
from .chase_db1 import ChaseDB1Dataset
from .cityscapes import CityscapesDataset
from .coco_stuff import COCOStuffDataset
from .custom import CustomDataset
from .dark_zurich import DarkZurichDataset
from .dataset_wrappers import (ConcatDataset, MultiImageMixDataset,
                               RepeatDataset)
from .drive import DRIVEDataset
from .hrf import HRFDataset
from .isaid import iSAIDDataset
from .isprs import ISPRSDataset
from .loveda import LoveDADataset
from .night_driving import NightDrivingDataset
from .pascal_context import PascalContextDataset, PascalContextDataset59
from .potsdam import PotsdamDataset
from .stare import STAREDataset
from .voc import PascalVOCDataset

from .ISBI2012 import ISBI2012Dataset # 注意添加!

__all__ = [
    'CustomDataset', 'build_dataloader', 'ConcatDataset', 'RepeatDataset',
    'DATASETS', 'build_dataset', 'PIPELINES', 'CityscapesDataset',
    'PascalVOCDataset', 'ADE20KDataset', 'PascalContextDataset',
    'PascalContextDataset59', 'ChaseDB1Dataset', 'DRIVEDataset', 'HRFDataset',
    'STAREDataset', 'DarkZurichDataset', 'NightDrivingDataset',
    'COCOStuffDataset', 'LoveDADataset', 'MultiImageMixDataset',
    'iSAIDDataset', 'ISPRSDataset', 'PotsdamDataset', 'ISBI2012Dataset'
]

三、在configs/_ base _/datasets下面对数据加载进行定义

在configs/__ base __/datasets/新建ISBI2012.py。

# dataset settings
dataset_type = 'ISBI2012Dataset' # 定义的数据集的名字
data_root = 'data/ISBI2012' # 数据集存储路径
img_norm_cfg = dict(
    mean=[127, 127, 127], std=[57, 57, 57], to_rgb=True) # 数据集的均值和标准差,空引用默认的,也可以网上搜代码计算
img_scale = (512, 512) # 原图数据大小
crop_size = (256, 256) # 数据增强时裁剪的大小
train_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='LoadAnnotations'),
    dict(type='Resize', img_scale=img_scale, ratio_range=(0.5, 2.0)),
    dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),
    dict(type='RandomFlip', prob=0.5),
    dict(type='PhotoMetricDistortion'),
    dict(type='Normalize', **img_norm_cfg),
    dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),
    dict(type='DefaultFormatBundle'),
    dict(type='Collect', keys=['img', 'gt_semantic_seg'])
]
test_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(
        type='MultiScaleFlipAug',
        img_scale=img_scale, # 测试集img_scale图像尺寸
        # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0],
        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=4, # batch_size
    workers_per_gpu=4, # nums gpu
    train=dict(
        type='RepeatDataset',
        times=40000,
        dataset=dict(
            type=dataset_type,
            data_root=data_root,
            img_dir='images/training', # 训练图像路径
            ann_dir='annotations/training', # 训练mask路径
            pipeline=train_pipeline)),
    val=dict(
        type=dataset_type,
        data_root=data_root,
        img_dir='images/validation', # 验证图像路径
        ann_dir='annotations/validation', # 验证mask路径
        pipeline=test_pipeline),
    test=dict(
        type=dataset_type,
        data_root=data_root,
        img_dir='images/test', # 测试图像路径
        # ann_dir='annotations/validation', # 无测试mask路径
        pipeline=test_pipeline))

四、在configs/下面选择你需要的模型参数进行修改

以U-Net为例,在configs/unet下新建fcn_unet_s5-d16_256x256_40k_isbi2012.py

_base_ = [
    '../_base_/models/fcn_unet_s5-d16_isbi2012.py',  # 这个是网络的骨架,使用单卡记得去骨架模型里将SyncBN改成BN
    '../_base_/datasets/ISBI2012.py', # 换成自己定义的数据集
    '../_base_/default_runtime.py', # 运行信息配置(加载预训练模型和断点训练)
    '../_base_/schedules/schedule_40k.py' # 运行信息配置(模型训练的最大次数、训练每个几次保留一个checkpoints、间隔多少次进行模型训练,模型训练评估的指标为、保留最好的模型)
]
model = dict(test_cfg=dict(crop_size=(256, 256), stride=(170, 170))) # 测试阶段剪切大小与滑动步长
evaluation = dict(metric='mDice')

新建对应的模型_base_/models/fcn_unet_s5-d16_isbi2012.py,是否有需要特别改动之处:

# model settings
norm_cfg = dict(type='BN', requires_grad=True) # SyncBN代表分布式训练,单卡训练将其改成BN
# norm_cfg = dict(type='SyncBN', requires_grad=True) # SyncBN代表分布式训练,单卡训练将其改成BN
model = dict(
    type='EncoderDecoder',
    pretrained=None,
    backbone=dict(
        type='UNet',
        in_channels=3, # 输入的通道数,ISBI2012是灰度图,自动转换为rgb,这里选择3即可
        base_channels=64,
        num_stages=5,
        strides=(1, 1, 1, 1, 1),
        enc_num_convs=(2, 2, 2, 2, 2),
        dec_num_convs=(2, 2, 2, 2),
        downsamples=(True, True, True, True),
        enc_dilations=(1, 1, 1, 1, 1),
        dec_dilations=(1, 1, 1, 1),
        with_cp=False,
        conv_cfg=None,
        norm_cfg=norm_cfg,
        act_cfg=dict(type='ReLU'),
        upsample_cfg=dict(type='InterpConv'),
        norm_eval=False),
    decode_head=dict(
        type='FCNHead',
        in_channels=64,
        in_index=4,
        channels=64,
        num_convs=1,
        concat_input=False,
        dropout_ratio=0.1,
        num_classes=2,
        norm_cfg=norm_cfg,
        align_corners=False,
        loss_decode=dict(
            type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), # type处可以指定loss类型
    auxiliary_head=dict(
        type='FCNHead',
        in_channels=128,
        in_index=3,
        channels=64,
        num_convs=1,
        concat_input=False,
        dropout_ratio=0.1,
        num_classes=2,
        norm_cfg=norm_cfg,
        align_corners=False,
        loss_decode=dict(
            type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)),# type处可以指定loss类型
    # model training and testing settings
    train_cfg=dict(),
    test_cfg=dict(mode='slide', crop_size=256, stride=170))

五、返回tools/train.py进行训练

训练命令:

python tools/train.py /path/to/fcn_unet_s5-d16_256x256_40k_isbi2012.py --work-dir ${YOUR_WORK_DIR}

/path/to/fcn_unet_s5-d16_256x256_40k_isbi2012.py:表示配置文件的位置,也就是上一步的fcn_unet_s5-d16_256x256_40k_isbi2012.py所在位置
work-dir:是用来存储模型和日志的地方,你可以自己指定,不指定的话会自己创建
也可以在tools/train.py里面进行指定,随后直接运行train.py就行

在train.py中你需要修改的只有以下几个内容:
1、–config指定网络文件加载配置文件的位置
2、–work-dir是你结果存储路径
3、–gpu-id是你指定哪个GPU进行训练,–gpus与–gpu-id作者在API文档中已经介绍这两弃用了,至于为啥不删,估计是在其他地方还在加载。

在这里插入图片描述

开始训练,并得到最终结果。

六、推理

在tools/test.py中进行如下设置

# Copyright (c) OpenMMLab. All rights reserved.
import argparse
import os
import os.path as osp
import shutil
import time
import warnings

import mmcv
import torch
from mmcv.cnn.utils import revert_sync_batchnorm
from mmcv.runner import (get_dist_info, init_dist, load_checkpoint,
                         wrap_fp16_model)
from mmcv.utils import DictAction

from mmseg import digit_version
from mmseg.apis import multi_gpu_test, single_gpu_test
from mmseg.datasets import build_dataloader, build_dataset
from mmseg.models import build_segmentor
from mmseg.utils import build_ddp, build_dp, get_device, setup_multi_processes


def parse_args():
    parser = argparse.ArgumentParser(
        description='mmseg test (and eval) a model')
    # parser.add_argument('config', help='test config file path')
    # parser.add_argument('checkpoint', help='checkpoint file')
    parser.add_argument('--config',
                        default='configs/unet/fcn_unet_s5-d16_256x256_40k_isbi2012.py',
                        help='train config file path')
    parser.add_argument('--checkpoint',
                        default='output/ISBI2012/unet/latest.pth', 
                        help='checkpoint file')
    parser.add_argument(
        '--work-dir',
        help=('if specified, the evaluation metric results will be dumped'
              'into the directory as json'))
    parser.add_argument(
        '--aug-test', action='store_true', help='Use Flip and Multi scale aug')
    # parser.add_argument('--out', help='output result file in pickle format')
    parser.add_argument('--out', help='output result file in pickle format')
    parser.add_argument(
        '--format-only',
        action='store_true',
        help='Format the output results without perform evaluation. It is'
        'useful when you want to format the result to a specific format and '
        'submit it to the test server')
    # parser.add_argument(
    #     '--eval',
    #     type=str,
    #     nargs='+',
    #     help='evaluation metrics, which depends on the dataset, e.g., "mIoU"'
    #     ' for generic datasets, and "cityscapes" for Cityscapes')
    parser.add_argument(
        '--eval',
        type=str,
        nargs='+',
        default='mDice',
        help='evaluation metrics, which depends on the dataset, e.g., "mIoU"'
        ' for generic datasets, and "cityscapes" for Cityscapes')
    # parser.add_argument('--show', action='store_true', help='show results')
    parser.add_argument('--show', 
        default=True,
        action='store_true', help='show results')
    # parser.add_argument(
    #     '--show-dir', help='directory where painted images will be saved')
    parser.add_argument(
        '--show-dir', 
        default='output/ISBI2012/unet/show_dir',
        help='directory where painted images will be saved')
    parser.add_argument(
        '--gpu-collect',
        action='store_true',
        help='whether to use gpu to collect results.')
    parser.add_argument(
        '--gpu-id',
        type=int,
        default=0,
        help='id of gpu to use '
        '(only applicable to non-distributed testing)')
    parser.add_argument(
        '--tmpdir',
        help='tmp directory used for collecting results from multiple '
        'workers, available when gpu_collect is not specified')
    parser.add_argument(
        '--options',
        nargs='+',
        action=DictAction,
        help="--options is deprecated in favor of --cfg_options' and it will "
        'not be supported in version v0.22.0. Override some settings in the '
        'used config, the key-value pair in xxx=yyy format will be merged '
        'into config file. If the value to be overwritten is a list, it '
        'should be like key="[a,b]" or key=a,b It also allows nested '
        'list/tuple values, e.g. key="[(a,b),(c,d)]" Note that the quotation '
        'marks are necessary and that no white space is allowed.')
    parser.add_argument(
        '--cfg-options',
        nargs='+',
        action=DictAction,
        help='override some settings in the used config, the key-value pair '
        'in xxx=yyy format will be merged into config file. If the value to '
        'be overwritten is a list, it should be like key="[a,b]" or key=a,b '
        'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" '
        'Note that the quotation marks are necessary and that no white space '
        'is allowed.')
    parser.add_argument(
        '--eval-options',
        nargs='+',
        action=DictAction,
        help='custom options for evaluation')
    parser.add_argument(
        '--launcher',
        choices=['none', 'pytorch', 'slurm', 'mpi'],
        default='none',
        help='job launcher')
    parser.add_argument(
        '--opacity',
        type=float,
        default=0.5,
        help='Opacity of painted segmentation map. In (0, 1] range.')
    parser.add_argument('--local_rank', type=int, default=0)
    args = parser.parse_args()
    if 'LOCAL_RANK' not in os.environ:
        os.environ['LOCAL_RANK'] = str(args.local_rank)

    if args.options and args.cfg_options:
        raise ValueError(
            '--options and --cfg-options cannot be both '
            'specified, --options is deprecated in favor of --cfg-options. '
            '--options will not be supported in version v0.22.0.')
    if args.options:
        warnings.warn('--options is deprecated in favor of --cfg-options. '
                      '--options will not be supported in version v0.22.0.')
        args.cfg_options = args.options

    return args


def main():
    args = parse_args()
    assert args.out or args.eval or args.format_only or args.show \
        or args.show_dir, \
        ('Please specify at least one operation (save/eval/format/show the '
         'results / save the results) with the argument "--out", "--eval"'
         ', "--format-only", "--show" or "--show-dir"')

    if args.eval and args.format_only:
        raise ValueError('--eval and --format_only cannot be both specified')

    if args.out is not None and not args.out.endswith(('.pkl', '.pickle')):
        raise ValueError('The output file must be a pkl file.')

    cfg = mmcv.Config.fromfile(args.config)
    if args.cfg_options is not None:
        cfg.merge_from_dict(args.cfg_options)

    # set multi-process settings
    setup_multi_processes(cfg)

    # set cudnn_benchmark
    if cfg.get('cudnn_benchmark', False):
        torch.backends.cudnn.benchmark = True
    if args.aug_test:
        # hard code index
        cfg.data.test.pipeline[1].img_ratios = [
            0.5, 0.75, 1.0, 1.25, 1.5, 1.75
        ]
        cfg.data.test.pipeline[1].flip = True
    cfg.model.pretrained = None
    cfg.data.test.test_mode = True

    if args.gpu_id is not None:
        cfg.gpu_ids = [args.gpu_id]

    # init distributed env first, since logger depends on the dist info.
    if args.launcher == 'none':
        cfg.gpu_ids = [args.gpu_id]
        distributed = False
        if len(cfg.gpu_ids) > 1:
            warnings.warn(f'The gpu-ids is reset from {cfg.gpu_ids} to '
                          f'{cfg.gpu_ids[0:1]} to avoid potential error in '
                          'non-distribute testing time.')
            cfg.gpu_ids = cfg.gpu_ids[0:1]
    else:
        distributed = True
        init_dist(args.launcher, **cfg.dist_params)

    rank, _ = get_dist_info()
    # allows not to create
    if args.work_dir is not None and rank == 0:
        mmcv.mkdir_or_exist(osp.abspath(args.work_dir))
        timestamp = time.strftime('%Y%m%d_%H%M%S', time.localtime())
        if args.aug_test:
            json_file = osp.join(args.work_dir,
                                 f'eval_multi_scale_{timestamp}.json')
        else:
            json_file = osp.join(args.work_dir,
                                 f'eval_single_scale_{timestamp}.json')
    elif rank == 0:
        work_dir = osp.join('./work_dirs',
                            osp.splitext(osp.basename(args.config))[0])
        mmcv.mkdir_or_exist(osp.abspath(work_dir))
        timestamp = time.strftime('%Y%m%d_%H%M%S', time.localtime())
        if args.aug_test:
            json_file = osp.join(work_dir,
                                 f'eval_multi_scale_{timestamp}.json')
        else:
            json_file = osp.join(work_dir,
                                 f'eval_single_scale_{timestamp}.json')

    # build the dataloader
    # TODO: support multiple images per gpu (only minor changes are needed)
    dataset = build_dataset(cfg.data.test)
    # The default loader config
    loader_cfg = dict(
        # cfg.gpus will be ignored if distributed
        num_gpus=len(cfg.gpu_ids),
        dist=distributed,
        shuffle=False)
    # The overall dataloader settings
    loader_cfg.update({
        k: v
        for k, v in cfg.data.items() if k not in [
            'train', 'val', 'test', 'train_dataloader', 'val_dataloader',
            'test_dataloader'
        ]
    })
    test_loader_cfg = {
        **loader_cfg,
        'samples_per_gpu': 1,
        'shuffle': False,  # Not shuffle by default
        **cfg.data.get('test_dataloader', {})
    }
    # build the dataloader
    data_loader = build_dataloader(dataset, **test_loader_cfg)

    # build the model and load checkpoint
    cfg.model.train_cfg = None
    model = build_segmentor(cfg.model, test_cfg=cfg.get('test_cfg'))
    fp16_cfg = cfg.get('fp16', None)
    if fp16_cfg is not None:
        wrap_fp16_model(model)
    checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu')
    if 'CLASSES' in checkpoint.get('meta', {}):
        model.CLASSES = checkpoint['meta']['CLASSES']
    else:
        print('"CLASSES" not found in meta, use dataset.CLASSES instead')
        model.CLASSES = dataset.CLASSES
    if 'PALETTE' in checkpoint.get('meta', {}):
        model.PALETTE = checkpoint['meta']['PALETTE']
    else:
        print('"PALETTE" not found in meta, use dataset.PALETTE instead')
        model.PALETTE = dataset.PALETTE

    # clean gpu memory when starting a new evaluation.
    torch.cuda.empty_cache()
    eval_kwargs = {} if args.eval_options is None else args.eval_options

    # Deprecated
    efficient_test = eval_kwargs.get('efficient_test', False)
    if efficient_test:
        warnings.warn(
            '``efficient_test=True`` does not have effect in tools/test.py, '
            'the evaluation and format results are CPU memory efficient by '
            'default')

    eval_on_format_results = (
        args.eval is not None and 'cityscapes' in args.eval)
    if eval_on_format_results:
        assert len(args.eval) == 1, 'eval on format results is not ' \
                                    'applicable for metrics other than ' \
                                    'cityscapes'
    if args.format_only or eval_on_format_results:
        if 'imgfile_prefix' in eval_kwargs:
            tmpdir = eval_kwargs['imgfile_prefix']
        else:
            tmpdir = '.format_cityscapes'
            eval_kwargs.setdefault('imgfile_prefix', tmpdir)
        mmcv.mkdir_or_exist(tmpdir)
    else:
        tmpdir = None

    cfg.device = get_device()
    if not distributed:
        warnings.warn(
            'SyncBN is only supported with DDP. To be compatible with DP, '
            'we convert SyncBN to BN. Please use dist_train.sh which can '
            'avoid this error.')
        if not torch.cuda.is_available():
            assert digit_version(mmcv.__version__) >= digit_version('1.4.4'), \
                'Please use MMCV >= 1.4.4 for CPU training!'
        model = revert_sync_batchnorm(model)
        model = build_dp(model, cfg.device, device_ids=cfg.gpu_ids)
        results = single_gpu_test(
            model,
            data_loader,
            args.show,
            args.show_dir,
            False,
            args.opacity,
            pre_eval=args.eval is not None and not eval_on_format_results,
            format_only=args.format_only or eval_on_format_results,
            format_args=eval_kwargs)
    else:
        model = build_ddp(
            model,
            cfg.device,
            device_ids=[int(os.environ['LOCAL_RANK'])],
            broadcast_buffers=False)
        results = multi_gpu_test(
            model,
            data_loader,
            args.tmpdir,
            args.gpu_collect,
            False,
            pre_eval=args.eval is not None and not eval_on_format_results,
            format_only=args.format_only or eval_on_format_results,
            format_args=eval_kwargs)

    rank, _ = get_dist_info()
    if rank == 0:
        if args.out:
            warnings.warn(
                'The behavior of ``args.out`` has been changed since MMSeg '
                'v0.16, the pickled outputs could be seg map as type of '
                'np.array, pre-eval results or file paths for '
                '``dataset.format_results()``.')
            print(f'\nwriting results to {args.out}')
            mmcv.dump(results, args.out)
        if args.eval:
            eval_kwargs.update(metric=args.eval)
            metric = dataset.evaluate(results, **eval_kwargs)
            metric_dict = dict(config=args.config, metric=metric)
            mmcv.dump(metric_dict, json_file, indent=4)
            if tmpdir is not None and eval_on_format_results:
                # remove tmp dir when cityscapes evaluation
                shutil.rmtree(tmpdir)


if __name__ == '__main__':
    main()
    print('ok')

如果没有标签的测试集中,在–eval参数中设置为None即可。

    parser.add_argument(
        '--eval',
        type=str,
        nargs='+',
        default=None, # change this parament
        help='evaluation metrics, which depends on the dataset, e.g., "mIoU"'
        ' for generic datasets, and "cityscapes" for Cityscapes')

如果想要输出最终的图像为Mask掩膜,不将原图数据作为背景,可以设置opacity参数为1

    parser.add_argument(
        '--opacity',
        type=float,
        default=1,
        help='Opacity of painted segmentation map. In (0, 1] range.')

最后结果:

warnings.warn(
[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] 30/30, 3.9 task/s, elapsed: 8s, ETA:     0

在这里插入图片描述

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mmsegmentation实战一:ISBI2012数据实战 的相关文章

  • 关于STARMAC旋翼机的计算系统组成分析

    摘要 xff1a STARMAC xff0c 全称为 the Stanford Testbed of Autonomous Rotorcraft for Multi Agent Control xff0c 是斯坦福大学为为了突破先前飞行器笨
  • 读史铁生随笔摘要

    人可以走向天堂 xff0c 不可以走到天堂 物质的天堂注定难为 xff0c 而精神的天堂恰于走向中成立 永远的限制是其永远成立的依据 无所眺望或有所眺望都证明到达之地并非圆满 xff0c 而你若永远地走向它 xff0c 你便随时都在它的光照
  • IMAX B6电路原理详解

    IMAX B6电路原理详解 本文出自 手电大家谈 xff0c 原帖 xff1a http www shoudian org thread 447417 1 1 html
  • arduino实验第三代码

    include lt avr eeprom h gt define PinA 2 中断0 define led1 1 define led2 3 define led3 4 define led4 5 define da 6 define
  • pytorch总结——1:初步introduction

    pytorch简介 先说Torch xff0c 这是一个与Numpy类似的张量 xff08 Tensor xff09 操作库 xff0c 与Numpy不同的是Torch对GPU支持的很好 xff0c Lua是Torch的上层包装 但是Lua
  • pytorch_RNN相关函数介绍

    1 RNN背景介绍 RNN结构 参数介绍 input size 输入x的特征数量 hiddien size 隐藏层的特征数量 num layers RNN的层数 nonlinearity 指定激活函数是tanh还是relu xff0c 默认
  • 一些tensorflow-VIN 的笔记

    1tensorflow 使用flags定义命令行参数 2 product的执行 3 xff0c round函数 保留小数点后几位 96 a 61 1 12345 result 61 round a 2 print result 1 12 4
  • rosbag录制固定话题,多话题等

    ROS框架下可以很方便的进行数据记录 并且将其转换为txt文件进行matlab处理 下面介绍一下rosbag的日常使用方法 1 查找你所需要的话题 xff1a rostopic list 在ros节点开启的情况下 span class to
  • 相机与IMU标定教程

    标定教程 way 相机与IMU联合标定 1 imu utils 标定IMU的内参 1 imu utils标定IMU的内参 xff0c 可以校准IMU的噪声密度和随机游走噪声 2 kalibr包标定相机的内外参数 xff0c 相机与IMU之间
  • 如何在Win11中安装wsl Ubuntu系统

    目录 前言正文一 环境二 在 Windows 11 上启用 WSL四 按照官方文档进行安装五 安装ubuntu系统六 下载vcxSrv七 运行wsl八 总结 参考 前言 在笔记本上安装一下环境 xff0c 便于平常的工作 正文 一 环境 w
  • 下载PX4固件时网络太慢,经常出现克隆失败

    下载PX4固件时 xff0c 官网给的指令是 git clone https github com PX4 PX4 Autopilot git recursive 需要进行循环克隆 xff0c 在克隆过程中可能出现以下的情况 无法克隆 39
  • roslaunch mavros px4.launch 出现的问题

    在运行roslaunch mavros px4 launch fcu url 61 udp 14540 64 127 0 0 1t 14557 时出现了以下错误 xff0c 这是由于 符号是中文符号导致的 xff0c 切换成英文的即可 RL
  • 解决Ubuntu执行sudo命令后提示无法解析主机

    解决Ubuntu执行sudo命令后提示无法解析主机 异常现象异常原因查看修改主机名普通用户与管理员间的切换 异常现象 异常原因 etc hostname和 etc hosts文件中主机名称不一致导致 xff0c 将其修改一致即可 修改此文件
  • rosdep update 指令超时问题

    在执行rosdep update后出现超时问题 xff0c 报如下错误 reading in sources list data from etc ros rosdep sources list d ERROR unable to proc
  • 使用git --recursive进行循环克隆,由于网络原因,出现克隆失败的情况。

    git clone recursive 用于循环克隆git子项目 xff0c 但由于网络原因 xff0c 经常会出现克隆失败的情况 xff0c 这时不得不删掉克隆文件夹 xff0c 全部重新来过 xff0c 我们可以先将主文件克隆下来 xf
  • minimumsnap(1)微分平坦特性(Differential Flatness)

    本文内容参考论文 Minimum Snap Trajectory Generation and Control for Quadrotors Daniel Mellinger and Vijay Kumar 从名字可以看出 xff0c 我们
  • 未安装Ceres

    编译VINs的时候 xff0c 遇到了这个问题 xff0c 是没安装Ceres导致的 96 CMake Error at VINS Mono camera model CMakeLists txt 19 find package By no
  • 费雪信息场增量建场实际实验

    写在前面 上一阶段的工作是基础是在张子潮大佬的费雪信息场这几篇论文的基础上进行的 Beyond Point Clouds Fisher Information Field for Active Visual Localization Zic
  • XTDrone+VINs+fast-planner

    接下来的工作需要把XTDrone VINS和fast planner集成到一起 在XTDrone集成VINs按照XTDrone使用手册来就可以了 xff0c 按照仿真平台基础配置 xff0c PX4飞控与EKF配置和视觉惯性里程计 xff0
  • 代码随想录算法训练营第19天|77. 组合

    代码随想录算法训练营第19天 77 组合 77 组合 题目链接 提交代码 span class token keyword class span span class token class name Solution span span

随机推荐

  • 【无标题】

    代码随想录算法训练营第1天 216 组合总和III 17 电话号码的字母组合 216 组合总和III 题目链接 提交代码 span class token keyword class span span class token class
  • 代码随想录算法训练营第20天回溯系列

    代码随想录算法训练营第1天 704 二分查找 27 移除元素 39 组合总和 题目链接 提交代码 span class token keyword class span span class token class name Solutio
  • SMPL-CN

    paper reading 为方便理解smpl文章的主要实现思想 xff0c 此文为论文中文解读 xff0c 资料来源zju 日后有空 xff0c 会写出论文的主要推导过程以及值得注意的重点 摘要 xff1a 我们提出了一个人体形状和姿势相
  • 自动驾驶的实现之路——几大关键传感器应用解析

    来源 xff1a MEMS 随着近两年来智慧汽车 车联网等等概念的兴起 xff0c 汽车自动驾驶的各种科技进展不断占据媒体版面 xff0c 引起了全球的关注和各国政府的支持 对于大部分人来说 xff0c 吃着火锅唱着歌 轻轻松松地直达目的地
  • 从零开始 CMake 学习笔记 (F)Build Type

    从零开始 CMake 学习笔记 xff08 F xff09 Build Type 开始前先默念三遍口诀 xff1a Declare a targetDeclare target s traitsIt s all about targets
  • 利用tf.reset_default_graph()重置default graph计算图以及nodes节点

    import tensorflow as tf tf reset default graph 利用这个可清空defualt graph以及nodes with tf variable scope Space a a 61 tf consta
  • c++继承多态知识感悟

    组合与继承 先说说组合 xff0c 当设计一个新的类的时候 xff0c 可以将一个已有类的对象作为成员 xff0c 然后通过成员对象实现已有类的功能 xff0c 类的对象成员与内置类型数据成员的声明语法一样 我们很早就开始接触并使用了 再说
  • Win10+Ubuntu18.04双系统安装教程

    一 说在前头 不同的配置安装方法不同 xff0c 我也是小白第一次安 xff0c 也是看了无数个教程不断重安了无数次才成功的 xff0c 所以我的教程不一定适合你的配置 xff0c 但你可以耐心的按照我的思路尝试 xff0c 如果你有更好的
  • ROS中的package.xml的使用

    文章目录 package xml作用package xml写法 来自VINS mono中 vins estimator package xml作用 pacakge xml 包含了package的名称 版本号 内容描述 维护人员 软件许可 编
  • 五、VINS-mono 代码解析——VIO初始化之SFM详解

    文章目录 前言系统流程图Estimator类processImage 函数initialStructure 初始化函数SFM初始化relativePose 函数getCorresponding 函数返回两帧匹配特征点3D坐标solveRel
  • 嵌入式软件工程师的四项基本能力

    能力1 xff1a 对C语言的深入掌握 xff0c 不犯低级语法错误 能力2 xff1a 对嵌入式芯片平台熟悉 xff0c 包括芯片各类外设的原理和使用方法 xff0c 以及相应的嵌入式操作系统 还包括芯片外围电路的设计能力 xff0c 包
  • windows中cuda版本切换

    一 安装 xff1a cuda的安装教程较多 xff0c 可以参考的博客 xff1a https blog csdn net zsc201825 article details 91129403 安装后的默认地址 xff1a C Progr
  • 阿里云配置ubuntu图形化界面

    购买阿里云ECS服务器 xff1a 阿里云官网地址 xff1a https www aliyun com 点击云服务器ECS xff0c 根据自身情况进行选购 购买后点击控制台 xff0c 找到实例 xff1a 找到自己的服务器实例 xff
  • ‘labelme‘ 不是内部或外部命令,也不是可运行的程序问题解决

    文章目录 一 安装labelme1 创建虚拟环境2 安装pyqt支持库3 安装Labelme 二 lableme启动 一 安装labelme 1 创建虚拟环境 命令行输入 conda create span class token oper
  • 超9成SCI论文发在国外!中文期刊到底差在哪?

    来源 科学网 撰文 卜叶 编辑 宗华 学术界不投中文期刊的原因是什么 xff1f 这一老生常谈的问题 xff0c 最近再次出现在某知识问答平台热榜 短短两周 xff0c 便吸引了180个回答 xff0c 浏览量超过34万 中文期刊到底差在哪
  • detectron2入门学习一:实现FruitsNut水果坚果分割任务以源码阅读

    学习目标 xff1a 学习detectron2数据集的注册以及基本的训练推理 一 工程文件下载与数据集准备 xff1a 整体的工程文件下载地址 xff1a https github com fenglingbai FruitsNutSeg
  • error: command ‘C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v10.1\\bin\\nvcc.exe‘ failed

    项目场景 xff1a 在win10 CUDA10 1 xff0c pytorch 61 1 8 1 第三方库Detectron2 version 61 61 0 6 安装后进行编译时 python setup span class toke
  • 移植已有的python环境至远程服务器(不需要联网重新下载相关环境)

    一 xff1a conda pcak使用 xff1a 由于实验室服务器不能联网 xff0c 唯一的方法是使用系统代理 xff0c 方法可以使用 ccproxy xff0c 这个可以在后续博客中介绍 xff0c 但该方法还是需要重新联网下载环
  • CloudCompare点云配准基本操作

    CloudCompare基本介绍 官方网站 https cloudcompare org 官方文档 https cloudcompare org doc qCC CloudCompare 20v2 6 1 20 20User 20manua
  • mmsegmentation实战一:ISBI2012数据实战

    文章目录 一 数据格式转换二 dataset class文件配置 xff1b 1 设置数据集文件2 修改mmseg datasets 目录下的 init py 三 在configs base datasets下面对数据加载进行定义四 在co