def block(x,filters,strides=1,groups=32,conv_shortcut=True):
if conv_shortcut:
shortcut=Conv2D(filters * 2, kernel_size = (1,1),strides=strides,
padding='same')
shortcut = BatchNormalization(epsilon=1.001e-5)(shortcut)
else:
shortcut=x
x=Conv2D(filters=filters,kernel_size=(1,1),strides=1,padding='same',use_bias=False)
x=BatchNormalization(epsilon=1.001e-5)(x)
x=ReLU()(x)
g_channels=int(filters/groups)
x=grouped_convolution_block(x,strides,groups,g_channels)
x=Conv2D(filters=filters*2,kernel_size=(1,1),strides=1,padding='same')
x=BatchNormalization(epsilon=1.001e-5)(x)
x=Add()([x,shortcutu])
x=ReLU()(x)
return x
def grouped_convolution_block(init_x,strides,groups,g_channels):
group_list = []
for c in range(groups):
x = Lambda(lamba x: x[:,:,:,c*g_channels:(c+1) * g_channels])(init_x)
x =Conv2D(filters=g_channels,kernel_size=(3,3),stride=strides,padding='same',use_bias=False)
group_list.append(x)
group_merage=concatenate(group_list,axis=3)
x=BatchNormalization(epsilon=1.001e-5)(group_merage)
x=ReLU()(x)
return x
def stack(x,filters,blocks,strides,groups=32):
x=block(x,filters,strides=strides,groups=groups)
for i in range(blocks):
x=block(x,filters,groups=groups,conv_shortcut=False)
return x
def ResNext50(input_shape,num_classes):
inputs=Input(shape=input_shape)
x=ZeroPadding2D((3,3))(inputs)
x=Conv2D(filters=64,kernel_size=(7,7),strides=2,padding='valid')(x) #通道数64
x=BatchNormalization(epsilon=1.001e-5)(x)
x=ReLU()(x)
x=ZeroPadding2D((1,1))(x)
x=MaxPool2D(pool_size=(3,3),strides=2,padding='valid')(x)
x=stack(x,filters=128,blocks=2,strides=1) #输出通道数为
x=stack(x,filters=256,blocks=3,strides=2)
x=stack(x,filters=512,blocks=5,strides=2)
x=stack(x,filters=1024,blocks=2,strides=2)
x=GlobalAvgPool2D()(x)
x=Dense(num_classes,activation='softmax')(x)
model=Model(inputs=inputs,outputs=x)
return model
问题:如果conv_shortcut=False,那么在执行x=Add()"语句时,通道数不一致的,为什么不会报错?
回答:这个代码没有错。因为在ResNext50整个模型中,stack模块中,每个stack的第一个block的conv_shortcut=True,此时输出的通道数为filters的两倍,之后再将conv_shortcut=False,通道数就是匹配的了