修改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这个属性,实例化的时候就会把他添加进去,所以打印层的时候会打印出来。实际上也没啥影响(除了权重文件大了点),因为前向传播它不参与,它的参数也用不到。
谢谢解释,豁然开朗!
真是阳光之下没有灵异事!