在上一篇我们已经成功配置好了自己的数据集
但小伙伴们肯定会有疑问
搞了半天跑的是mmsegmentation里面的其他网络
我们需要跑的是SegNeXt网络呀!图文不符,退货,差评
好了好了
大家冷静
这一篇就是告诉大家我们上一篇配置好的数据集怎么拿到SegNeXt网络上来跑
首先大家先明确我们的SegNeXt网络跟我们的其他网络不在一起,其他网络都在configs/文件夹下
我们的SegNeXt在local_configs/文件夹下
里面的各个文件是啥意思 这里我就不赘述了
不清楚的小伙伴去看看我的系列教程(四)跟着去修改相关的文件
这里需要重点提一下
1、在local_configs/segnext/base/下新建一个danet_r50-d8_512x512_80k_mydata.py
在里面的内容 为:
_base_ = [
'../../_base_/models/danet_r50-d8.py', '../../_base_/datasets/mydata_repeat.py',
'../../_base_/default_runtime.py', '../../_base_/schedules/schedule_80k.py'
]
model = dict(
decode_head=dict(num_classes=2), auxiliary_head=dict(num_classes=2))
checkpoint_config = dict(by_epoch=False, interval=5000)
evaluation = dict(interval=10000, metric='mIoU')
2、修改local_configs/_base_/datasets/mydata_repeat.py
如果只是修改里面的部分内容,将路径放到我们数据集所在的位置
如下:
# dataset settings
dataset_type = 'MyRoadData'
#data_root = '/root/ADEChallengeData2016'
data_root = 'data/MyRoadData'
img_norm_cfg = dict(
mean=[0.5947, 0.5815, 0.5625], std=[0.1173, 0.1169, 0.1157], to_rgb=True)
crop_size = (512, 512)
train_pipeline = [
dict(type='LoadImageFromFile'),
dict(type='LoadAnnotations', reduce_zero_label=True),
dict(type='Resize', img_scale=(512,512), 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=(512, 512),
# 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='ResizeToMultiple', size_divisor=32),
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=2,
train=dict(
type='RepeatDataset',
times=50,
dataset=dict(
type=dataset_type,
data_root=data_root,
img_dir='images/training',
ann_dir='annotations/training',
pipeline=train_pipeline)),
val=dict(
type=dataset_type,
data_root=data_root,
img_dir='images/validation',
ann_dir='annotations/validation',
pipeline=test_pipeline),
test=dict(
type=dataset_type,
data_root=data_root,
img_dir='images/validation',
ann_dir='annotations/validation',
pipeline=test_pipeline))
跑出来道路IOU结果是0!!!
经过尝试正确的做法是
把我们在(四)里写的mydata.py文件里的内容复制过来
就可以正常运行啦
代码如下:
# dataset settings
dataset_type = 'MyRoadData'
data_root = 'data/MyRoadData'
img_norm_cfg = dict(
mean=[0.5947, 0.5815, 0.5625], std=[0.1173, 0.1169, 0.1157], 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_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=8,
workers_per_gpu=16,
train=dict(
type='RepeatDataset',
times=40000,
dataset=dict(
type=dataset_type,
data_root=data_root,
img_dir='images/training',
ann_dir='annotations/training',
pipeline=train_pipeline)),
val=dict(
type=dataset_type,
data_root=data_root,
img_dir='images/validation',
ann_dir='annotations/validation',
pipeline=test_pipeline),
test=dict(
type=dataset_type,
data_root=data_root,
img_dir='images/validation',
ann_dir='annotations/validation',
pipeline=test_pipeline))
下面贴一些我的运行结果
跑了一下
iou算的是训练iou
网络的预测结果:
1、danet网络
10000次:72.62
2023-11-07 19:22:36,886 - mmseg - INFO -
+------------+-------+-------+
| Class | IoU | Acc |
+------------+-------+-------+
| background | 94.34 | 97.58 |
| road | 72.62 | 81.91 |
+------------+-------+-------+
2023-11-07 19:22:36,886 - mmseg - INFO - Summary:
2023-11-07 19:22:36,886 - mmseg - INFO -
+-------+-------+-------+
| aAcc | mIoU | mAcc |
+-------+-------+-------+
| 95.08 | 83.48 | 89.74 |
+-------+-------+-------+
70000:75.21
+------------+-------+-------+
| Class | IoU | Acc |
+------------+-------+-------+
| background | 94.68 | 96.99 |
| road | 75.21 | 87.17 |
+------------+-------+-------+
2023-11-08 02:45:12,389 - mmseg - INFO - Summary:
2023-11-08 02:45:12,389 - mmseg - INFO -
+-------+-------+-------+
| aAcc | mIoU | mAcc |
+-------+-------+-------+
| 95.42 | 84.95 | 92.08 |
+-------+-------+-------+
260000: 80.81
2023-11-09 02:07:34,806 - mmseg - INFO -
+------------+-------+-------+
| Class | IoU | Acc |
+------------+-------+-------+
| background | 96.09 | 98.16 |
| road | 80.81 | 88.66 |
+------------+-------+-------+
2023-11-09 02:07:34,806 - mmseg - INFO - Summary:
2023-11-09 02:07:34,806 - mmseg - INFO -
+-------+-------+-------+
| aAcc | mIoU | mAcc |
+-------+-------+-------+
| 96.64 | 88.45 | 93.41 |
+-------+-------+-------+
320000:82.37
2023-11-09 09:25:21,676 - mmseg - INFO -
+------------+-------+-------+
| Class | IoU | Acc |
+------------+-------+-------+
| background | 96.52 | 98.75 |
| road | 82.37 | 87.81 |
+------------+-------+-------+
2023-11-09 09:25:21,676 - mmseg - INFO - Summary:
2023-11-09 09:25:21,677 - mmseg - INFO -
+------+-------+-------+
| aAcc | mIoU | mAcc |
+------+-------+-------+
| 97.0 | 89.44 | 93.28 |
+------+-------+-------+
2、SegNeXt网络
20000次:
road | 74.51
120000次:
road | 81.83
240000次:
road | 85.5
400000次:
road | 88.08
对训练日志 (training logs) 画图
tools/analyze_logs.py
会画出给定的训练日志文件的 loss/mIoU 曲线,首先需要 pip install seaborn
安装依赖包。
- 对 mIoU, mAcc, aAcc 指标画图
python tools/analyze_logs.py log.json --keys mIoU mAcc aAcc --legend mIoU mAcc aAcc
- 对 loss 指标画图
python tools/analyze_logs.py log.json --keys loss --legend loss
二分类预测想保存黑白灰度图
mmsegmentation默认将预测得到的mask覆盖在原始图片上进行显示或保存
如下
我们可以看到使用上面说的预测方式,预测生成的图片是有颜色的,他是加了一个蒙版让你可以看到下面的DOM影像的
因此我们这里需要修改一下代码
为了直接输出灰度图,需要对源码进行修改
使他预测出来的图片和我们的标签一样
地物是白色
背景是黑色
修改位置/home/xxx/SegNeXt-main/mmseg/models/segmentors/base.py
里面有个def show_result的函数
def show_result(self,
img,
result,
palette=None,
win_name='',
show=False,
wait_time=0,
out_file=None,
opacity=0.5):
"""Draw `result` over `img`.
Args:
img (str or Tensor): The image to be displayed.
result (Tensor): The semantic segmentation results to draw over
`img`.
palette (list[list[int]]] | np.ndarray | None): The palette of
segmentation map. If None is given, random palette will be
generated. Default: None
win_name (str): The window name.
wait_time (int): Value of waitKey param.
Default: 0.
show (bool): Whether to show the image.
Default: False.
out_file (str or None): The filename to write the image.
Default: None.
opacity(float): Opacity of painted segmentation map.
Default 0.5.
Must be in (0, 1] range.
Returns:
img (Tensor): Only if not `show` or `out_file`
"""
img = mmcv.imread(img)
img = img.copy()
seg = result[0]
if palette is None:
if self.PALETTE is None:
# Get random state before set seed,
# and restore random state later.
# It will prevent loss of randomness, as the palette
# may be different in each iteration if not specified.
# See: https://github.com/open-mmlab/mmdetection/issues/5844
state = np.random.get_state()
np.random.seed(42)
# random palette
palette = np.random.randint(
0, 255, size=(len(self.CLASSES), 3))
np.random.set_state(state)
else:
palette = self.PALETTE
palette = np.array(palette)
assert palette.shape[0] == len(self.CLASSES)
assert palette.shape[1] == 3
assert len(palette.shape) == 2
assert 0 < opacity <= 1.0
color_seg = np.zeros((seg.shape[0], seg.shape[1], 3), dtype=np.uint8)
for label, color in enumerate(palette):
color_seg[seg == label, :] = color
# convert to BGR
color_seg = color_seg[..., ::-1]
img = img * (1 - opacity) + color_seg * opacity
img = img.astype(np.uint8)
# if out_file specified, do not show image in window
if out_file is not None:
show = False
if show:
mmcv.imshow(img, win_name, wait_time)
if out_file is not None:
mmcv.imwrite(img, out_file)
if not (show or out_file):
warnings.warn('show==False and out_file is not specified, only '
'result image will be returned')
return img
查阅了相关资料,有个博主说可以通过下面的方式获得黑白样本图
但我尝试后失败了
以二分类为例,若想保存灰度图可修改为:
if out_file is not None:
seg = np.array(seg)
seg[seg>0]=255
mmcv.imwrite(seg,out_file)
以多分类为例,若想保存调色板调色之后的结果,在tools/test.py中将opacity设置为1即可
大家可以试一试我的方法
if out_file is not None:
mmcv.imwrite(color_seg , out_file)
这样就可以输出黑白样本图啦,是24位的,像素值是(0,0,0)和(255,255,255)
代码详细理解
能跑起来之后只是我们漫漫研究路上的第一步
更重要的是理解它 成为它 改变它
看懂便是第一步
这里给大家推荐一个博客
博主的注释超级详细,可以一行一行对着看
这里使用的就是我们之前跑过的pspnet
norm_cfg = dict(type='SyncBN', requires_grad=True) # 分割框架通常使用 SyncBN
model = dict(
type='EncoderDecoder', # 分割器(segmentor)的名字
pretrained='open-mmlab://resnet50_v1c', # 将被加载的 ImageNet 预训练主干网络
backbone=dict(
type='ResNetV1c', # 主干网络的类别。 可用选项请参考 mmseg/models/backbones/resnet.py
depth=50, # 主干网络的深度。通常为 50 和 101。
num_stages=4, # 主干网络状态(stages)的数目,这些状态产生的特征图作为后续的 head 的输入。
out_indices=(0, 1, 2, 3), # 每个状态产生的特征图输出的索引。
dilations=(1, 1, 2, 4), # 每一层(layer)的空心率(dilation rate)。
strides=(1, 2, 1, 1), # 每一层(layer)的步长(stride)。
norm_cfg=dict( # 归一化层(norm layer)的配置项。
type='SyncBN', # 归一化层的类别。通常是 SyncBN。
requires_grad=True), # 是否训练归一化里的 gamma 和 beta。
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=dict(type='SyncBN', requires_grad=True), # 归一化层的配置项。
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=dict(type='SyncBN', requires_grad=True), # 归一化层的配置项。
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' 和 'sliding'. 'whole': 整张图像全卷积(fully-convolutional)测试。 'sliding': 图像上做滑动裁剪窗口(sliding crop window)。
dataset_type = 'CityscapesDataset' # 数据集类型,这将被用来定义数据集。
data_root = 'data/cityscapes/' # 数据的根路径。
img_norm_cfg = dict( # 图像归一化配置,用来归一化输入的图像。
mean=[123.675, 116.28, 103.53], # 预训练里用于预训练主干网络模型的平均值。
std=[58.395, 57.12, 57.375], # 预训练里用于预训练主干网络模型的标准差。
to_rgb=True) # 预训练里用于预训练主干网络的图像的通道顺序。
crop_size = (512, 1024) # 训练时的裁剪大小
train_pipeline = [ #训练流程
dict(type='LoadImageFromFile'), # 第1个流程,从文件路径里加载图像。
dict(type='LoadAnnotations'), # 第2个流程,对于当前图像,加载它的注释信息。
dict(type='Resize', # 变化图像和其注释大小的数据增广的流程。
img_scale=(2048, 1024), # 图像的最大规模。
ratio_range=(0.5, 2.0)), # 数据增广的比例范围。
dict(type='RandomCrop', # 随机裁剪当前图像和其注释大小的数据增广的流程。
crop_size=(512, 1024), # 随机裁剪图像生成 patch 的大小。
cat_max_ratio=0.75), # 单个类别可以填充的最大区域的比例。
dict(
type='RandomFlip', # 翻转图像和其注释大小的数据增广的流程。
flip_ratio=0.5), # 翻转图像的概率
dict(type='PhotoMetricDistortion'), # 光学上使用一些方法扭曲当前图像和其注释的数据增广的流程。
dict(
type='Normalize', # 归一化当前图像的数据增广的流程。
mean=[123.675, 116.28, 103.53], # 这些键与 img_norm_cfg 一致,因为 img_norm_cfg 被
std=[58.395, 57.12, 57.375], # 用作参数。
to_rgb=True),
dict(type='Pad', # 填充当前图像到指定大小的数据增广的流程。
size=(512, 1024), # 填充的图像大小。
pad_val=0, # 图像的填充值。
seg_pad_val=255), # 'gt_semantic_seg'的填充值。
dict(type='DefaultFormatBundle'), # 流程里收集数据的默认格式捆。
dict(type='Collect', # 决定数据里哪些键被传递到分割器里的流程。
keys=['img', 'gt_semantic_seg'])
]
test_pipeline = [
dict(type='LoadImageFromFile'), # 第1个流程,从文件路径里加载图像。
dict(
type='MultiScaleFlipAug', # 封装测试时数据增广(test time augmentations)。
img_scale=(2048, 1024), # 决定测试时可改变图像的最大规模。用于改变图像大小的流程。
flip=False, # 测试时是否翻转图像。
transforms=[
dict(type='Resize', # 使用改变图像大小的数据增广。
keep_ratio=True), # 是否保持宽和高的比例,这里的图像比例设置将覆盖上面的图像规模大小的设置。
dict(type='RandomFlip'), # 考虑到 RandomFlip 已经被添加到流程里,当 flip=False 时它将不被使用。
dict(
type='Normalize', # 归一化配置项,值来自 img_norm_cfg。
mean=[123.675, 116.28, 103.53],
std=[58.395, 57.12, 57.375],
to_rgb=True),
dict(type='ImageToTensor', # 将图像转为张量
keys=['img']),
dict(type='Collect', # 收集测试时必须的键的收集流程。
keys=['img'])
])
]
data = dict(
samples_per_gpu=2, # 单个 GPU 的 Batch size
workers_per_gpu=2, # 单个 GPU 分配的数据加载线程数
train=dict( # 训练数据集配置
type='CityscapesDataset', # 数据集的类别, 细节参考自 mmseg/datasets/。
data_root='data/cityscapes/', # 数据集的根目录。
img_dir='leftImg8bit/train', # 数据集图像的文件夹。
ann_dir='gtFine/train', # 数据集注释的文件夹。
pipeline=[ # 流程, 由之前创建的 train_pipeline 传递进来。
dict(type='LoadImageFromFile'),
dict(type='LoadAnnotations'),
dict(
type='Resize', img_scale=(2048, 1024), ratio_range=(0.5, 2.0)),
dict(type='RandomCrop', crop_size=(512, 1024), cat_max_ratio=0.75),
dict(type='RandomFlip', flip_ratio=0.5),
dict(type='PhotoMetricDistortion'),
dict(
type='Normalize',
mean=[123.675, 116.28, 103.53],
std=[58.395, 57.12, 57.375],
to_rgb=True),
dict(type='Pad', size=(512, 1024), pad_val=0, seg_pad_val=255),
dict(type='DefaultFormatBundle'),
dict(type='Collect', keys=['img', 'gt_semantic_seg'])
]),
val=dict( # 验证数据集的配置
type='CityscapesDataset',
data_root='data/cityscapes/',
img_dir='leftImg8bit/val',
ann_dir='gtFine/val',
pipeline=[ # 由之前创建的 test_pipeline 传递的流程。
dict(type='LoadImageFromFile'),
dict(
type='MultiScaleFlipAug',
img_scale=(2048, 1024),
flip=False,
transforms=[
dict(type='Resize', keep_ratio=True),
dict(type='RandomFlip'),
dict(
type='Normalize',
mean=[123.675, 116.28, 103.53],
std=[58.395, 57.12, 57.375],
to_rgb=True),
dict(type='ImageToTensor', keys=['img']),
dict(type='Collect', keys=['img'])
])
]),
test=dict(
type='CityscapesDataset',
data_root='data/cityscapes/',
img_dir='leftImg8bit/val',
ann_dir='gtFine/val',
pipeline=[
dict(type='LoadImageFromFile'),
dict(
type='MultiScaleFlipAug',
img_scale=(2048, 1024),
flip=False,
transforms=[
dict(type='Resize', keep_ratio=True),
dict(type='RandomFlip'),
dict(
type='Normalize',
mean=[123.675, 116.28, 103.53],
std=[58.395, 57.12, 57.375],
to_rgb=True),
dict(type='ImageToTensor', keys=['img']),
dict(type='Collect', keys=['img'])
])
]))
log_config = dict( # 注册日志钩 (register logger hook) 的配置文件。
interval=50, # 打印日志的间隔
hooks=[
# dict(type='TensorboardLoggerHook') # 同样支持 Tensorboard 日志
dict(type='TextLoggerHook', by_epoch=False)
])
dist_params = dict(backend='nccl') # 用于设置分布式训练的参数,端口也同样可被设置。
log_level = 'INFO' # 日志的级别。
load_from = None # 从一个给定路径里加载模型作为预训练模型,它并不会消耗训练时间。
resume_from = None # 从给定路径里恢复检查点(checkpoints),训练模式将从检查点保存的轮次开始恢复训练。
workflow = [('train', 1)] # runner 的工作流程。 [('train', 1)] 意思是只有一个工作流程而且工作流程 'train' 仅执行一次。根据 `runner.max_iters` 工作流程训练模型的迭代轮数为40000次。
cudnn_benchmark = True # 是否是使用 cudnn_benchmark 去加速,它对于固定输入大小的可以提高训练速度。
optimizer = dict( # 用于构建优化器的配置文件。支持 PyTorch 中的所有优化器,同时它们的参数与PyTorch里的优化器参数一致。
type='SGD', # 优化器种类,更多细节可参考 https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/optimizer/default_constructor.py#L13。
lr=0.01, # 优化器的学习率,参数的使用细节请参照对应的 PyTorch 文档。
momentum=0.9, # 动量 (Momentum)
weight_decay=0.0005) # SGD 的衰减权重 (weight decay)。
optimizer_config = dict() # 用于构建优化器钩 (optimizer hook) 的配置文件,执行细节请参考 https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/optimizer.py#L8。
lr_config = dict(
policy='poly', # 调度流程的策略,同样支持 Step, CosineAnnealing, Cyclic 等. 请从 https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/lr_updater.py#L9 参考 LrUpdater 的细节。
power=0.9, # 多项式衰减 (polynomial decay) 的幂。
min_lr=0.0001, # 用来稳定训练的最小学习率。
by_epoch=False) # 是否按照每个 epoch 去算学习率。
runner = dict(
type='IterBasedRunner', # 将使用的 runner 的类别 (例如 IterBasedRunner 或 EpochBasedRunner)。
max_iters=40000) # 全部迭代轮数大小,对于 EpochBasedRunner 使用 `max_epochs` 。
checkpoint_config = dict( # 设置检查点钩子 (checkpoint hook) 的配置文件。执行时请参考 https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/checkpoint.py。
by_epoch=False, # 是否按照每个 epoch 去算 runner。
interval=4000) # 保存的间隔
evaluation = dict( # 构建评估钩 (evaluation hook) 的配置文件。细节请参考 mmseg/core/evaluation/eval_hook.py。
interval=4000, # 评估的间歇点
metric='mIoU') # 评估的指标
还有俩个网络的主干设置对比等细节
大家一定去学学
要比自己一个一个搜效率高得多