修改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
这样加上语法高亮
输出可以看见,第一个的时候符合条件,应该不写那个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
发现是在__init__里面内容和顺序影响最终的顺序,天啊,跟预想的不一样啊。
这是什么意思啊?
也就是在初始化和forward里面都加了这个判断语句:
if self.in_c != self.mid_c:
最后写成了这样:
不在init里面加上判断,ResidualUnit就会有expand_conv这个属性,实例化的时候就会把他添加进去,所以打印层的时候会打印出来。实际上也没啥影响(除了权重文件大了点),因为前向传播它不参与,它的参数也用不到。
谢谢解释,豁然开朗!
真是阳光之下没有灵异事!