mmseg学习day01

openmmlab:mmsegmentation项目官方教程地址

1. 环境配置完成

在这里插入图片描述
在这里插入图片描述

2. 了解配置文件

  • 配置文件结构:
    1)可以运行 python tools/misc/print_config.py /PATH/TO/CONFIG来查看完整的配置文件,也可以通过传递参数 --cfg-options xxx.yyy=zzz 来查看更新的配置信息。
    2)在 config/base 文件夹下面有4种基本组件类型: 数据集(dataset),模型(model),训练策略(schedule)和运行时的默认设置(default runtime)。许多模型都可以很容易地通过组合这些组件进行实现,比如 DeepLabV3,PSPNet。使用 base 下的组件构建的配置信息叫做原始配置 (primitive)。
    3)命名格式
{algorithm name}_{model component names [component1]_[component2]_[...]}_{training settings}_{training dataset information}_{testing dataset information}

4)PSPNET举例

_base_ = [
    '../_base_/models/pspnet_r50-d8.py', '../_base_/datasets/cityscapes.py',
    '../_base_/default_runtime.py', '../_base_/schedules/schedule_40k.py'
] # 我们可以在基本配置文件的基础上 构建新的配置文件
crop_size = (512, 1024)
data_preprocessor = dict(size=crop_size)
model = dict(data_preprocessor=data_preprocessor)
# _base_/models/pspnet_r50-d8.py是使用ResNet50V1c作为主干网络的PSPNet的基本模型配置文件。
# 模型设置
norm_cfg = dict(type='SyncBN', requires_grad=True)  # 分割框架通常使用 SyncBN
data_preprocessor = dict(  # 数据预处理的配置项,通常包括图像的归一化和增强
    type='SegDataPreProcessor',  # 数据预处理的类型
    mean=[123.675, 116.28, 103.53],  # 用于归一化输入图像的平均值
    std=[58.395, 57.12, 57.375],  # 用于归一化输入图像的标准差
    bgr_to_rgb=True,  # 是否将图像从 BGR 转为 RGB
    pad_val=0,  # 图像的填充值
    seg_pad_val=255)  # 'gt_seg_map'的填充值
model = dict(
    type='EncoderDecoder',  # 分割器(segmentor)的名字
    data_preprocessor=data_preprocessor,
    pretrained='open-mmlab://resnet50_v1c',  # 加载使用 ImageNet 预训练的主干网络
    backbone=dict(
        type='ResNetV1c',  # 主干网络的类别,更多细节请参考 mmseg/models/backbones/resnet.py
        depth=50,  # 主干网络的深度,通常为 50 和 101
        num_stages=4,  # 主干网络状态(stages)的数目
        out_indices=(0, 1, 2, 3),  # 每个状态(stage)产生的特征图输出的索引
        dilations=(1, 1, 2, 4),  # 每一层(layer)的空心率(dilation rate)
        strides=(1, 2, 1, 1),  # 每一层(layer)的步长(stride)
        norm_cfg=norm_cfg,  # 归一化层(norm layer)的配置项
        norm_eval=False,  # 是否冻结 BN 里的统计项
        style='pytorch',  # 主干网络的风格,'pytorch' 意思是步长为2的层为 3x3 卷积, 'caffe' 意思是步长为2的层为 1x1 卷积
        contract_dilation=True),  # 当空洞率 > 1, 是否压缩第一个空洞层
    decode_head=dict(
        type='PSPHead',  # 解码头(decode head)的类别。可用选项请参 mmseg/models/decode_heads
        in_channels=2048,  # 解码头的输入通道数
        in_index=3,  # 被选择特征图(feature map)的索引
        channels=512,  # 解码头中间态(intermediate)的通道数
        pool_scales=(1, 2, 3, 6),  # PSPHead 平均池化(avg pooling)的规模(scales)。 细节请参考文章内容
        dropout_ratio=0.1,  # 进入最后分类层(classification layer)之前的 dropout 比例
        num_classes=19,  # 分割前景的种类数目。 通常情况下,cityscapes 为19,VOC为21,ADE20k 为150
        norm_cfg=norm_cfg,  # 归一化层的配置项
        align_corners=False,  # 解码过程中调整大小(resize)的 align_corners 参数
        loss_decode=dict(  # 解码头(decode_head)里的损失函数的配置项
            type='CrossEntropyLoss',  # 分割时使用的损失函数的类别
            use_sigmoid=False,  # 分割时是否使用 sigmoid 激活
            loss_weight=1.0)),  # 解码头的损失权重
    auxiliary_head=dict(
        type='FCNHead',  # 辅助头(auxiliary head)的种类。可用选项请参考 mmseg/models/decode_heads
        in_channels=1024,  # 辅助头的输入通道数
        in_index=2,  # 被选择的特征图(feature map)的索引
        channels=256,  # 辅助头中间态(intermediate)的通道数
        num_convs=1,  # FCNHead 里卷积(convs)的数目,辅助头中通常为1
        concat_input=False,  # 在分类层(classification layer)之前是否连接(concat)输入和卷积的输出
        dropout_ratio=0.1,  # 进入最后分类层(classification layer)之前的 dropout 比例
        num_classes=19,  # 分割前景的种类数目。 通常情况下,cityscapes 为19,VOC为21,ADE20k 为150
        norm_cfg=norm_cfg,  # 归一化层的配置项
        align_corners=False,  # 解码过程中调整大小(resize)的 align_corners 参数
        loss_decode=dict(  # 辅助头(auxiliary head)里的损失函数的配置项
            type='CrossEntropyLoss',  # 分割时使用的损失函数的类别
            use_sigmoid=False,  # 分割时是否使用 sigmoid 激活
            loss_weight=0.4)),  # 辅助头损失的权重,默认设置为0.4
    # 模型训练和测试设置项
    train_cfg=dict(),  # train_cfg 当前仅是一个占位符
    test_cfg=dict(mode='whole'))  # 测试模式,可选参数为 'whole' 和 'slide'. 'whole': 在整张图像上全卷积(fully-convolutional)测试。 'slide': 在输入图像上做滑窗预测

_base_/datasets/cityscapes.py是数据集的基本配置文件。

# 数据集设置
dataset_type = 'CityscapesDataset'  # 数据集类型,这将被用来定义数据集
data_root = 'data/cityscapes/'  # 数据的根路径
crop_size = (512, 1024)  # 训练时的裁剪大小
train_pipeline = [  # 训练流程
    dict(type='LoadImageFromFile'),  # 第1个流程,从文件路径里加载图像
    dict(type='LoadAnnotations'),  # 第2个流程,对于当前图像,加载它的标注图像
    dict(type='RandomResize',  # 调整输入图像大小(resize)和其标注图像的数据增广流程
        scale=(2048, 1024),  # 图像裁剪的大小
        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'),  # 第1个流程,从文件路径里加载图像
    dict(type='Resize',  # 使用调整图像大小(resize)增强
        scale=(2048, 1024),  # 图像缩放的大小
        keep_ratio=True),  # 在调整图像大小时是否保留长宽比
    # 在' Resize '之后添加标注图像
    # 不需要做调整图像大小(resize)的数据变换
    dict(type='LoadAnnotations'),  # 加载数据集提供的语义分割标注
    dict(type='PackSegInputs')  # 打包用于语义分割的输入数据
]
train_dataloader = dict(  # 训练数据加载器(dataloader)的配置
    batch_size=2,  # 每一个GPU的batch size大小
    num_workers=2,  # 为每一个GPU预读取数据的进程个数
    persistent_workers=True,  # 在一个epoch结束后关闭worker进程,可以加快训练速度
    sampler=dict(type='InfiniteSampler', shuffle=True),  # 训练时进行随机洗牌(shuffle)
    dataset=dict(  # 训练数据集配置
        type=dataset_type,  # 数据集类型,详见mmseg/datassets/
        data_root=data_root,  # 数据集的根目录
        data_prefix=dict(
            img_path='leftImg8bit/train', seg_map_path='gtFine/train'),  # 训练数据的前缀
        pipeline=train_pipeline)) # 数据处理流程,它通过之前创建的train_pipeline传递。
val_dataloader = dict(
    batch_size=1,  # 每一个GPU的batch size大小
    num_workers=4,  # 为每一个GPU预读取数据的进程个数
    persistent_workers=True,  # 在一个epoch结束后关闭worker进程,可以加快训练速度
    sampler=dict(type='DefaultSampler', shuffle=False),  # 训练时不进行随机洗牌(shuffle)
    dataset=dict(  # 测试数据集配置
        type=dataset_type,  # 数据集类型,详见mmseg/datassets/
        data_root=data_root,  # 数据集的根目录
        data_prefix=dict(
            img_path='leftImg8bit/val', seg_map_path='gtFine/val'),  # 测试数据的前缀
        pipeline=test_pipeline))  # 数据处理流程,它通过之前创建的test_pipeline传递。
test_dataloader = val_dataloader
# 精度评估方法,我们在这里使用 IoUMetric 进行评估
val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU'])
test_evaluator = val_evaluator

_base_/schedules/schedule_40k.py

# optimizer
optimizer = dict(type='SGD', # 优化器种类,更多细节可参考 https://github.com/open-mmlab/mmengine/blob/main/mmengine/optim/optimizer/default_constructor.py
                lr=0.01,  # 优化器的学习率,参数的使用细节请参照对应的 PyTorch 文档
                momentum=0.9,  # 动量大小 (Momentum)
                weight_decay=0.0005)  # SGD 的权重衰减 (weight decay)
optim_wrapper = dict(type='OptimWrapper',  # 优化器包装器(Optimizer wrapper)为更新参数提供了一个公共接口
                    optimizer=optimizer,  # 用于更新模型参数的优化器(Optimizer)
                    clip_grad=None)  # 如果 'clip_grad' 不是None,它将是 ' torch.nn.utils.clip_grad' 的参数。
# 学习策略
param_scheduler = [
    dict(
        type='PolyLR',  # 调度流程的策略,同样支持 Step, CosineAnnealing, Cyclic 等. 请从 https://github.com/open-mmlab/mmengine/blob/main/mmengine/optim/scheduler/lr_scheduler.py 参考 LrUpdater 的细节
        eta_min=1e-4,  # 训练结束时的最小学习率
        power=0.9,  # 多项式衰减 (polynomial decay) 的幂
        begin=0,  # 开始更新参数的时间步(step)
        end=40000,  # 停止更新参数的时间步(step)
        by_epoch=False)  # 是否按照 epoch 计算训练时间
]
# 40k iteration 的训练计划
train_cfg = dict(type='IterBasedTrainLoop', max_iters=40000, val_interval=4000)
val_cfg = dict(type='ValLoop')
test_cfg = dict(type='TestLoop')
# 默认钩子(hook)配置
default_hooks = dict(
    timer=dict(type='IterTimerHook'),  # 记录迭代过程中花费的时间
    logger=dict(type='LoggerHook', interval=50, log_metric_by_epoch=False),  # 从'Runner'的不同组件收集和写入日志
    param_scheduler=dict(type='ParamSchedulerHook'),  # 更新优化器中的一些超参数,例如学习率
    checkpoint=dict(type='CheckpointHook', by_epoch=False, interval=4000),  # 定期保存检查点(checkpoint)
    sampler_seed=dict(type='DistSamplerSeedHook'))  # 用于分布式训练的数据加载采样器

_base_/default_runtime.py

# 将注册表的默认范围设置为mmseg
default_scope = 'mmseg'
# environment
env_cfg = dict(
    cudnn_benchmark=True,
    mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),
    dist_cfg=dict(backend='nccl'),
)
log_level = 'INFO'
log_processor = dict(by_epoch=False)
load_from = None  # 从文件中加载检查点(checkpoint)
resume = False  # 是否从已有的模型恢复

数据集下载

使用预训练模型就行推理

推理器
在 MMSegmentation 中,提供了最方便的方式 MMSegInferencer 来使用模型。只需 3 行代码就可以获得图像的分割掩膜。

基本使用
以下示例展示了如何使用 MMSegInferencer 对单个图像执行推理。

>>> from mmseg.apis import MMSegInferencer
>>> # 将模型加载到内存中
>>> inferencer = MMSegInferencer(model='deeplabv3plus_r18-d8_4xb2-80k_cityscapes-512x1024')
>>> # 推理
>>> inferencer('demo/demo.png', show=True)

在这里插入图片描述
此外,可以使用 MMSegInferencer 来处理一个包含多张图片的 list:

# 输入一个图片 list
>>> images = [image1, image2, ...] # image1 可以是文件路径或 np.ndarray
>>> inferencer(images, show=True, wait_time=0.5) # wait_time 是延迟时间,0 表示无限

# 或输入图像目录
>>> images = $IMAGESDIR
>>> inferencer(images, show=True, wait_time=0.5)

# 保存可视化渲染彩色分割图和预测结果
# out_dir 是保存输出结果的目录,img_out_dir 和 pred_out_dir 为 out_dir 的子目录
# 以保存可视化渲染彩色分割图和预测结果
>>> inferencer(images, out_dir='outputs', img_out_dir='vis', pred_out_dir='pred')
训练与测试

未完。。。继续学习中。。。。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值