首页 Paddle框架 帖子详情
灵异事件,MobileNetV3模型修改去掉一层结果去不掉 已解决
收藏
快速回复
Paddle框架 问答模型训练 383 7
灵异事件,MobileNetV3模型修改去掉一层结果去不掉 已解决
收藏
快速回复
Paddle框架 问答模型训练 383 7

修改PaddleClas里面的MobileNetV3 模型代码,为了跟torch对上,需要去掉一层expand_conv,我找到代码,在需要去掉的地方使用if语句,打印输出发现if语句也生效了,但是看模型结构,那层结构还在,感觉真是碰到了灵异事件。

 

```

class ResidualUnit(TheseusLayer):
    def __init__(self,
                 in_c,
                 mid_c,
                 out_c,
                 filter_size,
                 stride,
                 use_se,
                 act=None):
        super().__init__()
        self.if_shortcut = stride == 1 and in_c == out_c
        self.if_se = use_se
        # add for drop 1*1 conv
        self.in_c = in_c
        self.mid_c = mid_c
        


        self.expand_conv = ConvBNLayer(
            in_c=in_c,
            out_c=mid_c,
            filter_size=1,
            stride=1,
            padding=0,
            if_act=True,
            act=act)
        self.bottleneck_conv = ConvBNLayer(
            in_c=mid_c,
            out_c=mid_c,
            filter_size=filter_size,
            stride=stride,
            padding=int((filter_size - 1) // 2),
            num_groups=mid_c,
            if_act=True,
            act=act)
        if self.if_se:
            self.mid_se = SEModule(mid_c)
        self.linear_conv = ConvBNLayer(
            in_c=mid_c,
            out_c=out_c,
            filter_size=1,
            stride=1,
            padding=0,
            if_act=False,
            act=None)

    def forward(self, x):
        identity = x

        
        print("判断self.in_c {self.in_c}和self.mid_c {elf.mid_c}是否相等。")
        if self.in_c != self.mid_c:
            print("加入一个expand_conv")
            x = self.expand_conv(x) # 就是这部分,怎么也去不掉
        else :
            print("不增加expand_conv")

        x = self.bottleneck_conv(x)
        if self.if_se:
            x = self.mid_se(x)
        x = self.linear_conv(x)
        if self.if_shortcut:
            x = paddle.add(identity, x)
        return x

```

 

输出:

```

(conv): ConvBNLayer(
(conv): Conv2D(3, 16, kernel_size=[3, 3], stride=[2, 2], padding=1, data_format=NCHW)
(bn): BatchNorm()
(act): Hardswish()
)
(blocks): Sequential(
(0): ResidualUnit(
(expand_conv): ConvBNLayer(
(conv): Conv2D(16, 16, kernel_size=[1, 1], data_format=NCHW)
(bn): BatchNorm()
(act): ReLU()
)
(bottleneck_conv): ConvBNLayer(
(conv): Conv2D(16, 16, kernel_size=[3, 3], padding=1, groups=16, data_format=NCHW)
(bn): BatchNorm()
(act): ReLU()
)
(linear_conv): ConvBNLayer(
(conv): Conv2D(16, 16, kernel_size=[1, 1], data_format=NCHW)
(bn): BatchNorm()
)
)
(1): ResidualUnit(
(expand_conv): ConvBNLayer(
(conv): Conv2D(16, 64, kernel_size=[1, 1], data_format=NCHW)
(bn): BatchNorm()
(act): ReLU()
)
(bottleneck_conv): ConvBNLayer(
(conv): Conv2D(64, 64, kernel_size=[3, 3], stride=[2, 2], padding=1, groups=64, data_format=NCHW)
(bn): BatchNorm()
(act): ReLU()
)
(linear_conv): ConvBNLayer(
(conv): Conv2D(64, 24, kernel_size=[1, 1], data_format=NCHW)
(bn): BatchNorm()
)
)
(2): ResidualUnit(

```

按照代码应该去掉是这一层:

(0): ResidualUnit(
(expand_conv): ConvBNLayer(
(conv): Conv2D(16, 16, kernel_size=[1, 1], data_format=NCHW)
(bn): BatchNorm()
(act): ReLU()
)

 

项目链接在这里:https://aistudio.baidu.com/aistudio/projectdetail/292075

嘟嘟
已解决
7# 回复于2022-03
不在init里面加上判断,ResidualUnit就会有expand_conv这个属性,实例化的时候就会把他添加进去,所以打印层的时候会打印出来。实际上也没啥影响(除了权重文件大了点),因为前向传播它不参与,它的参数也用不到。
展开
0
收藏
回复
全部评论(7)
时间顺序
skywalk163
#2 回复于2022-03

这样加上语法高亮

class ResidualUnit(TheseusLayer):
    def __init__(self,
                 in_c,
                 mid_c,
                 out_c,
                 filter_size,
                 stride,
                 use_se,
                 act=None):
        super().__init__()
        self.if_shortcut = stride == 1 and in_c == out_c
        self.if_se = use_se
        # add for drop 1*1 conv
        self.in_c = in_c
        self.mid_c = mid_c
        


        self.expand_conv = ConvBNLayer(
            in_c=in_c,
            out_c=mid_c,
            filter_size=1,
            stride=1,
            padding=0,
            if_act=True,
            act=act)
        self.bottleneck_conv = ConvBNLayer(
            in_c=mid_c,
            out_c=mid_c,
            filter_size=filter_size,
            stride=stride,
            padding=int((filter_size - 1) // 2),
            num_groups=mid_c,
            if_act=True,
            act=act)
        if self.if_se:
            self.mid_se = SEModule(mid_c)
        self.linear_conv = ConvBNLayer(
            in_c=mid_c,
            out_c=out_c,
            filter_size=1,
            stride=1,
            padding=0,
            if_act=False,
            act=None)

    def forward(self, x):
        identity = x

        
        print("判断self.in_c {self.in_c}和self.mid_c {elf.mid_c}是否相等。")
        if self.in_c != self.mid_c:
            print("加入一个expand_conv")
            x = self.expand_conv(x) # 就是这部分,怎么也去不掉
        else :
            print("不增加expand_conv")

        x = self.bottleneck_conv(x)
        if self.if_se:
            x = self.mid_se(x)
        x = self.linear_conv(x)
        if self.if_shortcut:
            x = paddle.add(identity, x)
        return x
0
回复
skywalk163
#3 回复于2022-03

输出可以看见,第一个的时候符合条件,应该不写那个expand_conv的

判断self.in_c {self.in_c}和self.mid_c {elf.mid_c}是否相等。
不增加conv
判断self.in_c {self.in_c}和self.mid_c {elf.mid_c}是否相等。
加入一个conv
判断self.in_c {self.in_c}和self.mid_c {elf.mid_c}是否相等。
加入一个conv

0
回复
skywalk163
#4 回复于2022-03

发现是在__init__里面内容和顺序影响最终的顺序,天啊,跟预想的不一样啊。

0
回复
十进制到二进制
#5 回复于2022-03
发现是在__init__里面内容和顺序影响最终的顺序,天啊,跟预想的不一样啊。

这是什么意思啊?

0
回复
skywalk163
#6 回复于2022-03

也就是在初始化和forward里面都加了这个判断语句:

if self.in_c != self.mid_c:

最后写成了这样:

class ResidualUnit(TheseusLayer):
    def __init__(self,
                 in_c,
                 mid_c,
                 out_c,
                 filter_size,
                 stride,
                 use_se,
                 act=None):
        super().__init__()
        self.if_shortcut = stride == 1 and in_c == out_c
        self.if_se = use_se
        self.if_conv = in_c == mid_c
        self.in_c = in_c
        self.mid_c = mid_c

        
        if self.in_c != self.mid_c:

            self.expand_conv = ConvBNLayer(
                in_c=in_c,
                out_c=mid_c,
                filter_size=1,
                stride=1,
                padding=0,
                if_act=True,
                act=act)
        self.bottleneck_conv = ConvBNLayer(
            in_c=mid_c,
            out_c=mid_c,
            filter_size=filter_size,
            stride=stride,
            padding=int((filter_size - 1) // 2),
            num_groups=mid_c,
            if_act=True,
            act=act)
        if self.if_se:
            self.mid_se = SEModule(mid_c)
        self.linear_conv = ConvBNLayer(
            in_c=mid_c,
            out_c=out_c,
            filter_size=1,
            stride=1,
            padding=0,
            if_act=False,
            act=None)
    def forward(self, x):
        identity = x
        
        if self.in_c != self.mid_c:
#             print("加入一个conv")
            x = self.expand_conv(x)
        else :
            pass
        x = self.bottleneck_conv(x)
        if self.if_se:
            x = self.mid_se(x)
        x = self.linear_conv(x)
        if self.if_shortcut:
            x = paddle.add(identity, x)
        return x
0
回复
嘟嘟
#7 回复于2022-03

不在init里面加上判断,ResidualUnit就会有expand_conv这个属性,实例化的时候就会把他添加进去,所以打印层的时候会打印出来。实际上也没啥影响(除了权重文件大了点),因为前向传播它不参与,它的参数也用不到。

0
回复
skywalk163
#8 回复于2022-03

谢谢解释,豁然开朗! 

真是阳光之下没有灵异事!

0
回复
需求/bug反馈?一键提issue告诉我们
发现bug?如果您知道修复办法,欢迎提pr直接参与建设飞桨~
在@后输入用户全名并按空格结束,可艾特全站任一用户