我们在这里列出了使用时的一些常见问题及其相应的解决方案。 如果您发现有一些问题被遗漏,请随时提 PR 丰富这个列表。 如果您无法在此获得帮助,请使用 issue模板创建问题,但是请在模板中填写所有必填信息,这有助于我们更快定位问题。
兼容的MMSegmentation和MMCV版本如下。请安装正确版本的MMCV以避免安装问题。
MMSegmentation version | MMCV version | MMClassification version |
---|---|---|
master | mmcv-full>=1.5.0, <1.8.0 | mmcls>=0.20.1, <=1.0.0 |
0.30.0 | mmcv-full>=1.5.0, <1.8.0 | mmcls>=0.20.1, <=1.0.0 |
0.29.1 | mmcv-full>=1.5.0, <1.8.0 | mmcls>=0.20.1, <=1.0.0 |
0.29.0 | mmcv-full>=1.5.0, <1.7.0 | mmcls>=0.20.1, <=1.0.0 |
0.28.0 | mmcv-full>=1.5.0, <1.7.0 | mmcls>=0.20.1, <=1.0.0 |
0.27.0 | mmcv-full>=1.5.0, <1.7.0 | mmcls>=0.20.1, <=1.0.0 |
0.26.0 | mmcv-full>=1.5.0, <=1.6.0 | mmcls>=0.20.1, <=1.0.0 |
0.25.0 | mmcv-full>=1.5.0, <=1.6.0 | mmcls>=0.20.1, <=1.0.0 |
0.24.1 | mmcv-full>=1.4.4, <=1.6.0 | mmcls>=0.20.1, <=1.0.0 |
0.23.0 | mmcv-full>=1.4.4, <=1.6.0 | mmcls>=0.20.1, <=1.0.0 |
0.22.0 | mmcv-full>=1.4.4, <=1.6.0 | mmcls>=0.20.1, <=1.0.0 |
0.21.1 | mmcv-full>=1.4.4, <=1.6.0 | Not required |
0.20.2 | mmcv-full>=1.3.13, <=1.6.0 | Not required |
0.19.0 | mmcv-full>=1.3.13, <1.3.17 | Not required |
0.18.0 | mmcv-full>=1.3.13, <1.3.17 | Not required |
0.17.0 | mmcv-full>=1.3.7, <1.3.17 | Not required |
0.16.0 | mmcv-full>=1.3.7, <1.3.17 | Not required |
0.15.0 | mmcv-full>=1.3.7, <1.3.17 | Not required |
0.14.1 | mmcv-full>=1.3.7, <1.3.17 | Not required |
0.14.0 | mmcv-full>=1.3.1, <1.3.2 | Not required |
0.13.0 | mmcv-full>=1.3.1, <1.3.2 | Not required |
0.12.0 | mmcv-full>=1.1.4, <1.3.2 | Not required |
0.11.0 | mmcv-full>=1.1.4, <1.3.0 | Not required |
0.10.0 | mmcv-full>=1.1.4, <1.3.0 | Not required |
0.9.0 | mmcv-full>=1.1.4, <1.3.0 | Not required |
0.8.0 | mmcv-full>=1.1.4, <1.2.0 | Not required |
0.7.0 | mmcv-full>=1.1.2, <1.2.0 | Not required |
0.6.0 | mmcv-full>=1.1.2, <1.2.0 | Not required |
如果你安装了mmcv,你需要先运行pip uninstall mmcv
。
如果mmcv和mmcv-full都安装了,会出现 "ModuleNotFoundError"。
- "No module named 'mmcv.ops'"; "No module named 'mmcv._ext'".
- 使用
pip uninstall mmcv
卸载环境中现有的mmcv。 - 按照安装说明安装mmcv-full。
- 使用
- 看模型的config文件的命名。可以参考学习配置文件中的
配置文件命名风格
部分。比如,对于名字为segformer_mit-b0_8x1_1024x1024_160k_cityscapes.py
的config文件,8x1
代表训练其对应的模型需要的卡数为8,每张卡中的batch size为1。 - 看模型的log文件。点开该模型的log文件,并在其中搜索
nGPU
,在nGPU
后的数字个数即训练时所需的卡数。比如,在log文件中搜索nGPU
得到nGPU 0,1,2,3,4,5,6,7
的记录,则说明训练该模型需要使用八张卡。
简单来说,这是一个提高准确率的深度监督技术。在训练阶段,decode_head
用于输出语义分割的结果,auxiliary_head
只是增加了一个辅助损失,其产生的分割结果对你的模型结果没有影响,仅在在训练中起作用。你可以阅读这篇论文了解更多信息。
在训练脚本中,我们在第167行调用 get_root_logger
方法,然后 mmseg 的 get_root_logger
方法调用 mmcv 的 get_logger
,mmcv 将返回在 'mmsegmentation/tools/train.py' 中使用参数 log_file
初始化的同一个 logger。在训练期间只存在一个用 log_file
初始化的 logger。
如果你发现日志文件没有被创建,可以检查 mmcv.utils.get_logger
是否在其他地方被调用。
在测试脚本中,我们提供了show-dir
参数来控制是否输出绘制的图像。用户可以运行以下命令:
python tools/test.py {config} {checkpoint} --show-dir {/path/to/save/image} --opacity 1
MMSegmentation 使用 num_classes
和 out_channels
来控制模型最后一层 self.conv_seg
的输出. 更多细节可以参考 这里.
num_classes
应该和数据集本身类别个数一致,当是二值分割时,数据集只有前景和背景两类, 所以 num_classes
为 2. out_channels
控制模型最后一层的输出的通道数,通常和 num_classes
相等, 但当二值分割时候, 可以有两种处理方法, 分别是:
-
设置
out_channels=2
, 在训练时以 Cross Entropy Loss 作为损失函数, 在推理时使用F.softmax()
归一化 logits 值, 然后通过argmax()
得到每个像素的预测结果. -
设置
out_channels=1
, 在训练时以 Binary Cross Entropy Loss 作为损失函数, 在推理时使用F.sigmoid()
和threshold
得到预测结果,threshold
默认为 0.3.
对于实现上述两种计算二值分割的方法, 需要在 decode_head
和 auxiliary_head
的配置里修改. 下面是对样例 pspnet_unet_s5-d16.py 做出的对应修改.
- (1)
num_classes=2
,out_channels=2
并在CrossEntropyLoss
里面设置use_sigmoid=False
.
decode_head=dict(
type='PSPHead',
in_channels=64,
in_index=4,
num_classes=2,
out_channels=2,
loss_decode=dict(
type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)),
auxiliary_head=dict(
type='FCNHead',
in_channels=128,
in_index=3,
num_classes=2,
out_channels=2,
loss_decode=dict(
type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)),
- (2)
num_classes=2
,out_channels=1
并在CrossEntropyLoss
里面设置use_sigmoid=True
.
decode_head=dict(
type='PSPHead',
in_channels=64,
in_index=4,
num_classes=2,
out_channels=1,
loss_decode=dict(
type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0)),
auxiliary_head=dict(
type='FCNHead',
in_channels=128,
in_index=3,
num_classes=2,
out_channels=1,
loss_decode=dict(
type='CrossEntropyLoss', use_sigmoid=True, loss_weight=0.4)),
数据集中 reduce_zero_label
参数类型为布尔类型, 默认为 False, 它的功能是为了忽略数据集 label 0. 具体做法是将 label 0 改为 255, 其余 label 相应编号减 1, 同时 decode head 里将 255 设为 ignore index, 即不参与 loss 计算.
以下是 reduce_zero_label
具体实现逻辑:
if self.reduce_zero_label:
# avoid using underflow conversion
gt_semantic_seg[gt_semantic_seg == 0] = 255
gt_semantic_seg = gt_semantic_seg - 1
gt_semantic_seg[gt_semantic_seg == 254] = 255
注意: 使用 reduce_zero_label
请确认数据集原始类别个数, 如果只有两类, 需要关闭 reduce_zero_label
即设置 reduce_zero_label=False
.