mmsegmentation/tests/test_models/test_backbones/test_blocks.py

170 lines
6.4 KiB
Python
Raw Normal View History

import mmcv
Fast-SCNN implemented (#58) * init commit: fast_scnn * 247917iters * 4x8_80k * configs placed in configs_unify. 4x8_80k exp.running. * mmseg/utils/collect_env.py modified to support Windows * study on lr * bug in configs_unify/***/cityscapes.py fixed. * lr0.08_100k * lr_power changed to 1.2 * log_config by_epoch set to False. * lr1.2 * doc strings added * add fast_scnn backbone test * 80k 0.08,0.12 * add 450k * fast_scnn test: fix BN bug. * Add different config files into configs/ * .gitignore recovered. * configs_unify del * .gitignore recovered. * delete sub-optimal config files of fast-scnn * Code style improved. * add docstrings to component modules of fast-scnn * relevant files modified according to Jerry's instructions * relevant files modified according to Jerry's instructions * lint problems fixed. * fast_scnn config extremely simplified. * InvertedResidual * fixed padding problems * add unit test for inverted_residual * add unit test for inverted_residual: debug 0 * add unit test for inverted_residual: debug 1 * add unit test for inverted_residual: debug 2 * add unit test for inverted_residual: debug 3 * add unit test for sep_fcn_head: debug 0 * add unit test for sep_fcn_head: debug 1 * add unit test for sep_fcn_head: debug 2 * add unit test for sep_fcn_head: debug 3 * add unit test for sep_fcn_head: debug 4 * add unit test for sep_fcn_head: debug 5 * FastSCNN type(dwchannels) changed to tuple. * t changed to expand_ratio. * Spaces fixed. * Update mmseg/models/backbones/fast_scnn.py Co-authored-by: Jerry Jiarui XU <xvjiarui0826@gmail.com> * Update mmseg/models/decode_heads/sep_fcn_head.py Co-authored-by: Jerry Jiarui XU <xvjiarui0826@gmail.com> * Update mmseg/models/decode_heads/sep_fcn_head.py Co-authored-by: Jerry Jiarui XU <xvjiarui0826@gmail.com> * Docstrings fixed. * Docstrings fixed. * Inverted Residual kept coherent with mmcl. * Inverted Residual kept coherent with mmcl. Debug 0 * _make_layer parameters renamed. * final commit * Arg scale_factor deleted. * Expand_ratio docstrings updated. * final commit * Readme for Fast-SCNN added. * model-zoo.md modified. * fast_scnn README updated. * Move InvertedResidual module into mmseg/utils. * test_inverted_residual module corrected. * test_inverted_residual.py moved. * encoder_decoder modified to avoid bugs when running PSPNet. getting_started.md bug fixed. * Revert "encoder_decoder modified to avoid bugs when running PSPNet. " This reverts commit dd0aadfb Co-authored-by: Jerry Jiarui XU <xvjiarui0826@gmail.com>
2020-08-18 23:33:05 +08:00
import pytest
import torch
from mmseg.models.utils import (InvertedResidual, InvertedResidualV3, SELayer,
make_divisible)
def test_make_divisible():
# test with min_value = None
assert make_divisible(10, 4) == 12
assert make_divisible(9, 4) == 12
assert make_divisible(1, 4) == 4
# test with min_value = 8
assert make_divisible(10, 4, 8) == 12
assert make_divisible(9, 4, 8) == 12
assert make_divisible(1, 4, 8) == 8
Fast-SCNN implemented (#58) * init commit: fast_scnn * 247917iters * 4x8_80k * configs placed in configs_unify. 4x8_80k exp.running. * mmseg/utils/collect_env.py modified to support Windows * study on lr * bug in configs_unify/***/cityscapes.py fixed. * lr0.08_100k * lr_power changed to 1.2 * log_config by_epoch set to False. * lr1.2 * doc strings added * add fast_scnn backbone test * 80k 0.08,0.12 * add 450k * fast_scnn test: fix BN bug. * Add different config files into configs/ * .gitignore recovered. * configs_unify del * .gitignore recovered. * delete sub-optimal config files of fast-scnn * Code style improved. * add docstrings to component modules of fast-scnn * relevant files modified according to Jerry's instructions * relevant files modified according to Jerry's instructions * lint problems fixed. * fast_scnn config extremely simplified. * InvertedResidual * fixed padding problems * add unit test for inverted_residual * add unit test for inverted_residual: debug 0 * add unit test for inverted_residual: debug 1 * add unit test for inverted_residual: debug 2 * add unit test for inverted_residual: debug 3 * add unit test for sep_fcn_head: debug 0 * add unit test for sep_fcn_head: debug 1 * add unit test for sep_fcn_head: debug 2 * add unit test for sep_fcn_head: debug 3 * add unit test for sep_fcn_head: debug 4 * add unit test for sep_fcn_head: debug 5 * FastSCNN type(dwchannels) changed to tuple. * t changed to expand_ratio. * Spaces fixed. * Update mmseg/models/backbones/fast_scnn.py Co-authored-by: Jerry Jiarui XU <xvjiarui0826@gmail.com> * Update mmseg/models/decode_heads/sep_fcn_head.py Co-authored-by: Jerry Jiarui XU <xvjiarui0826@gmail.com> * Update mmseg/models/decode_heads/sep_fcn_head.py Co-authored-by: Jerry Jiarui XU <xvjiarui0826@gmail.com> * Docstrings fixed. * Docstrings fixed. * Inverted Residual kept coherent with mmcl. * Inverted Residual kept coherent with mmcl. Debug 0 * _make_layer parameters renamed. * final commit * Arg scale_factor deleted. * Expand_ratio docstrings updated. * final commit * Readme for Fast-SCNN added. * model-zoo.md modified. * fast_scnn README updated. * Move InvertedResidual module into mmseg/utils. * test_inverted_residual module corrected. * test_inverted_residual.py moved. * encoder_decoder modified to avoid bugs when running PSPNet. getting_started.md bug fixed. * Revert "encoder_decoder modified to avoid bugs when running PSPNet. " This reverts commit dd0aadfb Co-authored-by: Jerry Jiarui XU <xvjiarui0826@gmail.com>
2020-08-18 23:33:05 +08:00
def test_inv_residual():
with pytest.raises(AssertionError):
# test stride assertion.
InvertedResidual(32, 32, 3, 4)
# test default config with res connection.
# set expand_ratio = 4, stride = 1 and inp=oup.
inv_module = InvertedResidual(32, 32, 1, 4)
assert inv_module.use_res_connect
assert inv_module.conv[0].kernel_size == (1, 1)
assert inv_module.conv[0].padding == 0
assert inv_module.conv[1].kernel_size == (3, 3)
assert inv_module.conv[1].padding == 1
assert inv_module.conv[0].with_norm
assert inv_module.conv[1].with_norm
x = torch.rand(1, 32, 64, 64)
output = inv_module(x)
assert output.shape == (1, 32, 64, 64)
# test inv_residual module without res connection.
# set expand_ratio = 4, stride = 2.
inv_module = InvertedResidual(32, 32, 2, 4)
assert not inv_module.use_res_connect
assert inv_module.conv[0].kernel_size == (1, 1)
x = torch.rand(1, 32, 64, 64)
output = inv_module(x)
assert output.shape == (1, 32, 32, 32)
# test expand_ratio == 1
inv_module = InvertedResidual(32, 32, 1, 1)
assert inv_module.conv[0].kernel_size == (3, 3)
x = torch.rand(1, 32, 64, 64)
output = inv_module(x)
assert output.shape == (1, 32, 64, 64)
# test with checkpoint forward
inv_module = InvertedResidual(32, 32, 1, 1, with_cp=True)
assert inv_module.with_cp
x = torch.rand(1, 32, 64, 64, requires_grad=True)
output = inv_module(x)
assert output.shape == (1, 32, 64, 64)
def test_inv_residualv3():
with pytest.raises(AssertionError):
# test stride assertion.
InvertedResidualV3(32, 32, 16, stride=3)
with pytest.raises(AssertionError):
# test assertion.
InvertedResidualV3(32, 32, 16, with_expand_conv=False)
# test with se_cfg=None, with_expand_conv=False
inv_module = InvertedResidualV3(32, 32, 32, with_expand_conv=False)
assert inv_module.with_res_shortcut is True
assert inv_module.with_se is False
assert inv_module.with_expand_conv is False
assert not hasattr(inv_module, 'expand_conv')
assert isinstance(inv_module.depthwise_conv.conv, torch.nn.Conv2d)
assert inv_module.depthwise_conv.conv.kernel_size == (3, 3)
assert inv_module.depthwise_conv.conv.stride == (1, 1)
assert inv_module.depthwise_conv.conv.padding == (1, 1)
assert isinstance(inv_module.depthwise_conv.bn, torch.nn.BatchNorm2d)
assert isinstance(inv_module.depthwise_conv.activate, torch.nn.ReLU)
assert inv_module.linear_conv.conv.kernel_size == (1, 1)
assert inv_module.linear_conv.conv.stride == (1, 1)
assert inv_module.linear_conv.conv.padding == (0, 0)
assert isinstance(inv_module.linear_conv.bn, torch.nn.BatchNorm2d)
x = torch.rand(1, 32, 64, 64)
output = inv_module(x)
assert output.shape == (1, 32, 64, 64)
# test with se_cfg and with_expand_conv
se_cfg = dict(
channels=16,
ratio=4,
act_cfg=(dict(type='ReLU'),
dict(type='HSigmoid', bias=3.0, divisor=6.0)))
act_cfg = dict(type='HSwish')
inv_module = InvertedResidualV3(
32, 40, 16, 3, 2, se_cfg=se_cfg, act_cfg=act_cfg)
assert inv_module.with_res_shortcut is False
assert inv_module.with_se is True
assert inv_module.with_expand_conv is True
assert inv_module.expand_conv.conv.kernel_size == (1, 1)
assert inv_module.expand_conv.conv.stride == (1, 1)
assert inv_module.expand_conv.conv.padding == (0, 0)
assert isinstance(inv_module.expand_conv.activate, mmcv.cnn.HSwish)
assert isinstance(inv_module.depthwise_conv.conv,
mmcv.cnn.bricks.Conv2dAdaptivePadding)
assert inv_module.depthwise_conv.conv.kernel_size == (3, 3)
assert inv_module.depthwise_conv.conv.stride == (2, 2)
assert inv_module.depthwise_conv.conv.padding == (0, 0)
assert isinstance(inv_module.depthwise_conv.bn, torch.nn.BatchNorm2d)
assert isinstance(inv_module.depthwise_conv.activate, mmcv.cnn.HSwish)
assert inv_module.linear_conv.conv.kernel_size == (1, 1)
assert inv_module.linear_conv.conv.stride == (1, 1)
assert inv_module.linear_conv.conv.padding == (0, 0)
assert isinstance(inv_module.linear_conv.bn, torch.nn.BatchNorm2d)
x = torch.rand(1, 32, 64, 64)
output = inv_module(x)
assert output.shape == (1, 40, 32, 32)
# test with checkpoint forward
inv_module = InvertedResidualV3(
32, 40, 16, 3, 2, se_cfg=se_cfg, act_cfg=act_cfg, with_cp=True)
assert inv_module.with_cp
x = torch.randn(2, 32, 64, 64, requires_grad=True)
output = inv_module(x)
assert output.shape == (2, 40, 32, 32)
def test_se_layer():
with pytest.raises(AssertionError):
# test act_cfg assertion.
SELayer(32, act_cfg=(dict(type='ReLU'), ))
# test config with channels = 16.
se_layer = SELayer(16)
assert se_layer.conv1.conv.kernel_size == (1, 1)
assert se_layer.conv1.conv.stride == (1, 1)
assert se_layer.conv1.conv.padding == (0, 0)
assert isinstance(se_layer.conv1.activate, torch.nn.ReLU)
assert se_layer.conv2.conv.kernel_size == (1, 1)
assert se_layer.conv2.conv.stride == (1, 1)
assert se_layer.conv2.conv.padding == (0, 0)
assert isinstance(se_layer.conv2.activate, mmcv.cnn.HSigmoid)
x = torch.rand(1, 16, 64, 64)
output = se_layer(x)
assert output.shape == (1, 16, 64, 64)
# test config with channels = 16, act_cfg = dict(type='ReLU').
se_layer = SELayer(16, act_cfg=dict(type='ReLU'))
assert se_layer.conv1.conv.kernel_size == (1, 1)
assert se_layer.conv1.conv.stride == (1, 1)
assert se_layer.conv1.conv.padding == (0, 0)
assert isinstance(se_layer.conv1.activate, torch.nn.ReLU)
assert se_layer.conv2.conv.kernel_size == (1, 1)
assert se_layer.conv2.conv.stride == (1, 1)
assert se_layer.conv2.conv.padding == (0, 0)
assert isinstance(se_layer.conv2.activate, torch.nn.ReLU)
x = torch.rand(1, 16, 64, 64)
output = se_layer(x)
assert output.shape == (1, 16, 64, 64)