删除Keras中预先训练的VGG16模型中的中间层
各位, 我有一个关于如何修改Keras中预先培训的VGG16网络的问题。我尝试删除最后三个卷积层末尾的最大池层,并在每个卷积层末尾添加批处理规范化层。同时,我想保留参数。这意味着整个修改过程不仅包括删除一些中间层、添加一些新层,还包括将修改后的层与其余层连接起来 我在凯拉斯还是个新手。我能找到的唯一方法如中所示 因此,我编辑的代码如下所示:删除Keras中预先训练的VGG16模型中的中间层,keras,Keras,各位, 我有一个关于如何修改Keras中预先培训的VGG16网络的问题。我尝试删除最后三个卷积层末尾的最大池层,并在每个卷积层末尾添加批处理规范化层。同时,我想保留参数。这意味着整个修改过程不仅包括删除一些中间层、添加一些新层,还包括将修改后的层与其余层连接起来 我在凯拉斯还是个新手。我能找到的唯一方法如中所示 因此,我编辑的代码如下所示: from keras import applications from keras.models import Model from keras.laye
from keras import applications
from keras.models import Model
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers.normalization import BatchNormalization
vgg_model = applications.VGG16(weights='imagenet',
include_top=False,
input_shape=(160, 80, 3))
# Disassemble layers
layers = [l for l in vgg_model.layers]
# Defining new convolutional layer.
# Important: the number of filters should be the same!
# Note: the receiptive field of two 3x3 convolutions is 5x5.
layer_dict = dict([(layer.name, layer) for layer in vgg_model.layers])
x = layer_dict['block3_conv3'].output
for i in range(11, len(layers)-5):
# layers[i].trainable = False
x = layers[i](x)
for j in range(15, len(layers)-1):
# layers[j].trainable = False
x = layers[j](x)
x = Conv2D(filters=128, kernel_size=(1, 1))(x)
x = BatchNormalization()(x)
x = Conv2D(filters=128, kernel_size=(1, 1))(x)
x = BatchNormalization()(x)
x = Conv2D(filters=128, kernel_size=(1, 1))(x)
x = BatchNormalization()(x)
x = Flatten()(x)
x = Dense(50, activation='softmax')(x)
custom_model = Model(inputs=vgg_model.input, outputs=x)
for layer in custom_model.layers[:16]:
layer.trainable = False
custom_model.summary()
然而,块4和块5中卷积层的输出形状是多重的。我试图通过添加一个图层MaxPool2D(batch_size=(1,1),stride=none)来纠正它,但输出形状仍然是多个。就这样,
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 160, 80, 3) 0
_________________________________________________________________
block1_conv1 (Conv2D) (None, 160, 80, 64) 1792
_________________________________________________________________
block1_conv2 (Conv2D) (None, 160, 80, 64) 36928
_________________________________________________________________
block1_pool (MaxPooling2D) (None, 80, 40, 64) 0
_________________________________________________________________
block2_conv1 (Conv2D) (None, 80, 40, 128) 73856
_________________________________________________________________
block2_conv2 (Conv2D) (None, 80, 40, 128) 147584
_________________________________________________________________
block2_pool (MaxPooling2D) (None, 40, 20, 128) 0
_________________________________________________________________
block3_conv1 (Conv2D) (None, 40, 20, 256) 295168
_________________________________________________________________
block3_conv2 (Conv2D) (None, 40, 20, 256) 590080
_________________________________________________________________
block3_conv3 (Conv2D) (None, 40, 20, 256) 590080
_________________________________________________________________
block4_conv1 (Conv2D) multiple 1180160
_________________________________________________________________
block4_conv2 (Conv2D) multiple 2359808
_________________________________________________________________
block4_conv3 (Conv2D) multiple 2359808
_________________________________________________________________
block5_conv1 (Conv2D) multiple 2359808
_________________________________________________________________
block5_conv2 (Conv2D) multiple 2359808
_________________________________________________________________
block5_conv3 (Conv2D) multiple 2359808
_________________________________________________________________
conv2d_1 (Conv2D) (None, 40, 20, 128) 65664
_________________________________________________________________
batch_normalization_1 (Batch (None, 40, 20, 128) 512
_________________________________________________________________
conv2d_2 (Conv2D) (None, 40, 20, 128) 16512
_________________________________________________________________
batch_normalization_2 (Batch (None, 40, 20, 128) 512
_________________________________________________________________
conv2d_3 (Conv2D) (None, 40, 20, 128) 16512
_________________________________________________________________
batch_normalization_3 (Batch (None, 40, 20, 128) 512
_________________________________________________________________
flatten_1 (Flatten) (None, 102400) 0
_________________________________________________________________
dense_1 (Dense) (None, 50) 5120050
=================================================================
Total params: 19,934,962
Trainable params: 5,219,506
Non-trainable params: 14,715,456
_________________________________________________________________
有人能提供一些关于如何实现我的目标的建议吗
非常感谢。有多个输出形状,因为这些层被调用了两次,所以它们有两个输出形状。 您可以看到,如果调用
layer.output\u shape
引发AttributeError,则打印的输出形状将是“多个”
如果调用custom\u model.layers[10]。output\u shape
,则会出现以下错误:AttributeError:层“block4\u conv1”有多个入站节点,具有不同的输出形状。因此,该层的“输出形状”概念定义不正确。请改用`get\u output\u shape\u at(node\u index)`来代替。
然后,如果调用自定义模型.layers[10]。在(0)
处获取输出形状,您将获得与初始网络对应的输出形状,对于自定义模型.layers[10]。在(1)
处获取输出形状,您将获得所需的输出形状
让我来说明一下,我怀疑您的修改意图:如果您删除了最大池层,并且将下一层(编号11)应用于最大池层之前的输出,那么学习到的过滤器“期望”的图像分辨率将降低两倍,因此它们可能无法工作
让我们假设一个过滤器正在“寻找”眼睛,而眼睛通常是10像素宽,您需要一个20像素宽的眼睛来触发层中的相同激活。我的例子显然过于简单化和不精确,但它只是显示出原来的想法是错误的,你应该重新训练模型的顶部/保持最大池层/定义一个全新的模型在顶层Bux3Vang3。ew模型和导入预训练权重?@kosnik,我已经重新编辑了我的问题,希望这对你来说是清楚的。@mpariente,我正在考虑……谢谢。嗨,@mpariente,谢谢你的回答,但是我对你关于我为什么称这些层的解释有点困惑。我如何从我构建的模型中找到它?我试图添加cod在代码“custom\u model=model(inputs=vgg\u model.input,outputs=x)”之后,直接使用“custom\u model.layers[10]。获取(1)的\u output\u shape\u(1)”(不确定是否正确),然后我获得了这个值错误:ValueError:要求在节点1获取输出形状,但该层只有1个入站节点。然后我将其更改为“custom\u model.layers[10].get_output_shape_at(1)”,没有错误,但仍有相同的“倍数””“在那儿。你能给我多解释一下吗?至于这个网络的意图,它来自于一篇发表论文中的一种方法。由于没有可用的代码,我尝试重建它,以将其性能与其他方法进行比较。作者删除了最大池层以增加输出的大小,以便更准确地定位目标,因为他们使用的图像非常小。我不确定这一步骤是否真的能为最终结果带来好处,我必须实施它以确认其性能。再次感谢:)关于我的第一条评论的一些更正:1。我对您的解释有点困惑,为什么我两次调用这些层2。将其更改为“custom_model.layers[10]。在(0)处获取_output_shape_”