如何从顶部和底部拆分 resnet50 模型?

How to split resnet50 model from top as well as from bottom?

我正在使用 keras 带有 include_top=False 的预训练模型,但我也想从 top 中删除一个 resblock,并从 bottom 中删除一个。对于 vgg net,它很简单,因为在层中直接链接,但在 resnet 中,由于跳过连接,架构很复杂,所以直接方法不太适合。

有人可以推荐任何资源或脚本吗?

renet = tf.keras.applications.resnet50.ResNet50(include_top=False, weights='imagenet')

如果理解不正确,要消除第一块和最后一块。

我的建议是使用resnet.summary()能够可视化模型的所有名称。如果你有张量板可以清楚地看到这些关系,那就更好了。

虽然你可以知道在残差网络中一个块的完成是一个总和并且紧接着一个激活。激活将是你想要获得的图层。

块的名称类似于res2a ...数字2表示块,字母"subblock"。

基于Resnet50架构:

如果我要删除第一个残差块,我必须寻找 res2c 的结尾。在这种情况下,我发现了这个:

activation_57 (Activation) (None, 56, 56, 64) 0 bn2c_branch2a [0] [0]
__________________________________________________________________________________________________
res2c_branch2b (Conv2D) (None, 56, 56, 64) 36928 activation_57 [0] [0]
__________________________________________________________________________________________________
bn2c_branch2b (BatchNormalizati (None, 56, 56, 64) 256 res2c_branch2b [0] [0]
__________________________________________________________________________________________________
activation_58 (Activation) (None, 56, 56, 64) 0 bn2c_branch2b [0] [0]
__________________________________________________________________________________________________
res2c_branch2c (Conv2D) (None, 56, 56, 256) 16640 activation_58 [0] [0]
__________________________________________________________________________________________________
bn2c_branch2c (BatchNormalizati (None, 56, 56, 256) 1024 res2c_branch2c [0] [0]
__________________________________________________________________________________________________
add_19 (Add) (None, 56, 56, 256) 0 bn2c_branch2c [0] [0]
                                                                 activation_56 [0] [0]
__________________________________________________________________________________________________
activation_59 (Activation) (None, 56, 56, 256) 0 add_19 [0] [0]
__________________________________________________________________________________________________
res3a_branch2a (Conv2D) (None, 28, 28, 128) 32896 activation_59 [0] [0]

输入层是res3a_branch2a。这个形式我跳第一块残差

activation_87 (Activation)      (None, 14, 14, 256)  0           bn4f_branch2a[0][0]              
__________________________________________________________________________________________________
res4f_branch2b (Conv2D)         (None, 14, 14, 256)  590080      activation_87[0][0]              
__________________________________________________________________________________________________
bn4f_branch2b (BatchNormalizati (None, 14, 14, 256)  1024        res4f_branch2b[0][0]             
__________________________________________________________________________________________________
activation_88 (Activation)      (None, 14, 14, 256)  0           bn4f_branch2b[0][0]              
__________________________________________________________________________________________________
res4f_branch2c (Conv2D)         (None, 14, 14, 1024) 263168      activation_88[0][0]              
__________________________________________________________________________________________________
bn4f_branch2c (BatchNormalizati (None, 14, 14, 1024) 4096        res4f_branch2c[0][0]             
__________________________________________________________________________________________________
add_29 (Add)                    (None, 14, 14, 1024) 0           bn4f_branch2c[0][0]              
                                                                 activation_86[0][0]              
__________________________________________________________________________________________________
activation_89 (Activation)      (None, 14, 14, 1024) 0           add_29[0][0]   

如果我要删除最后一块残差,我应该寻找 res4 的结尾。那是 activation_89.

进行这些裁剪,我们将得到这个模型:

resnet_cut = Model(inputs=resnet.get_layer('res3a_branch2a'), outputs=resnet.get_layer('activation_89'))