MobileNet V2中InvertedResidual实现

1、为了方便理解其本身结构,找到源码理解一下。

2、论文地址:http://arxiv.org/pdf/1801.04381.pdf

3、V2相比较V1增加了倒残差结构和线性瓶颈层。整个结构按照维度来看,类似一个中间宽,两边窄的结构。其中最后一层使用linear卷积(没有使用ReLU进行非线性激活,也就是线性了),主要是考虑到ReLU对于高维激活可以得到很好的非线性特征信息,但是低维采用非线性就行破坏特征信息(也称为数据坍塌,就是有一部分特征被毁掉了),虽然在高维经常使用ReLU,但是不像在低维造成很大的特征丢失情况(因为可能丢掉一部分不重要的特征,对最终结果没啥影响)。因此采用线性(就不加ReLU)。至于为什么叫倒残差,可能也是由于该结构的形状吧,便于与残差结构区分。毕竟原始残差结构是中间窄,两边宽。

class InvertedResidual(nn.Module):
    def __init__(self, inp, oup, stride, expand_ratio):
        super(InvertedResidual, self).__init__()
        assert stride in [1, 2]

        hidden_dim = round(inp * expand_ratio)
        self.identity = stride == 1 and inp == oup

        if expand_ratio == 1:
            self.conv = nn.Sequential(
                # dw
                nn.Conv2d(hidden_dim, hidden_dim, 3, stride, 1, groups=hidden_dim, bias=False),
                nn.BatchNorm2d(hidden_dim),
                nn.ReLU6(inplace=True),
                # pw-linear
                nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False),
                nn.BatchNorm2d(oup),
            )
        else:
            self.conv = nn.Sequential(
                # pw
                nn.Conv2d(inp, hidden_dim, 1, 1, 0, bias=False),
                nn.BatchNorm2d(hidden_dim),
                nn.ReLU6(inplace=True),
                # dw
                nn.Conv2d(hidden_dim, hidden_dim, 3, stride, 1, groups=hidden_dim, bias=False),
                nn.BatchNorm2d(hidden_dim),
                nn.ReLU6(inplace=True),
                # pw-linear
                nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False),
                nn.BatchNorm2d(oup),
            )

    def forward(self, x):
        if self.identity:
            return x + self.conv(x)
        else:
            return self.conv(x)

 

posted @ 2022-11-14 15:17  九叶草  阅读(170)  评论(0编辑  收藏  举报