python-3.x 在新影像数据集上重新训练预训练模型后,如何访问该模型中的中间图层

mkshixfv  于 2023-02-10  发布在  Python
关注(0)|答案(1)|浏览(139)

我使用categorical crossentropy在一个带标签的图像数据集上训练了一个VGG16模型。我删除了完全连接的层,并将其替换为新层,如下所示:

vgg16_model = VGG16(weights="imagenet", include_top=False, input_shape=(224, 224, 3))
model = Sequential()
model.add(vgg16_model)
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(70, activation='softmax'))

然后我在数据集上训练了完整的模型,现在我想使用它作为特征提取模型,通过使用属于vgg16_model的任何中间层提取图像特征。
训练并保存模型后,我只能访问我添加的DenseDropout层,使用pop()函数删除它们,只保留训练过的特征提取器模型(vgg16)。

i = 0
while i < 4: 
    model.pop()

这只保留VGG16模型。但是,里面的层是不可访问的,我尝试:

new_model = Model(model.input,model.layers[-1].output)

但我得到这个错误:
值错误:图形已断开连接:无法获取图层"block1_conv1"处的TensorKerasTensor(类型规范= TensorSpec(形状=(None,224,224,3),数据类型= tf.float32,名称='input_9'),名称='input_9',描述="由图层'input_9'创建")的值。访问以下先前图层时未出现问题:[]
如何修改模型以考虑给定时间的前k层,然后使用模型进行预测?

brqmpdu1

brqmpdu11#

用你的方式定义keras模型,不幸的是当我们尝试从中间层定义特性时,会有很多复杂的问题。我已经开了一张罚单,请参见here
如果要使用属于vgg16_model的任何中间层提取图像特征,可以尝试以下方法。

# [good practice]: check first to know name and shape
# for layer in model.layers:
#     print(layer.name, layer.output_shape)

# vgg16 (None, 7, 7, 512)
# flatten (None, 25088)
# dense (None, 256)
# dropout (None, 256)
# dense_1 (None, 70)
# get the trained model first
trained_vgg16 = keras.Model(
    inputs=model.get_layer(name="vgg16").inputs,
    outputs=model.get_layer(name="vgg16").outputs,
)

x = tf.ones((1, 224, 224, 3))
y = trained_vgg16(x)
y.shape
TensorShape([1, 7, 7, 512])

接下来,使用这个trained_vgg16模型来构建目标模型。

# extract only 1 intermediate layer
feature_extractor_block3_pool = keras.Model(
    inputs=trained_vgg16.inputs,
    outputs=trained_vgg16.get_layer(name="block3_pool").output,
)

# or, 2 based on purpose.
feature_extractor_block3_pool_block4_conv3 = keras.Model(
    inputs=trained_vgg16.inputs,
    outputs=[
        trained_vgg16.get_layer(name="block3_pool").output,
        trained_vgg16.get_layer(name="block4_conv3").output,
    ],
)

# or, all
feature_extractor = keras.Model(
    inputs=trained_vgg16.inputs,
    outputs=[layer.output for layer in trained_vgg16.layers],
)

相关问题