从 Vgg16 网络导入后如何更改瓶颈特征的输入形状

Posted

技术标签:

【中文标题】从 Vgg16 网络导入后如何更改瓶颈特征的输入形状【英文标题】:how to change the input shape of bottleneck features after importing from Vgg16 net 【发布时间】:2018-12-20 04:04:09 【问题描述】:

我正在尝试使用 VGG16 Net 训练模型进行图像分类,并希望使用此代码将没有密集层的权重转移到我的图像集。

model1 = applications.VGG16(include_top=False, weights='imagenet', input_shape=(img_width,img_height,3))

在学习了瓶颈特征后,模型的最后几层是:

block5_conv2 (Conv2D)        (None, 6, 6, 512)         2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 6, 6, 512)         2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 3, 3, 512)         0         
=================================================================

最后一层维度是(None,3,3,512)。这将是我的 Dense 层的输入。

model1 = Sequential()
model1.add(Flatten(input_shape=train_data.shape[1:]))

所以模型的输入形状是(3,3,512)。 我的问题是,当我尝试预测图像时,输入图像的大小为(224,224,3)。那么如何将输入图像的形状转换为模型的输入形状呢?

当我尝试预测它时,这是我收到的错误:

ValueError: Error when checking input: expected flatten_1_input to have a shape (3, 3, 512) but got array with shape (224, 224, 3)

如何更改模型的输入形状或我必须预测的输入图像的输入形状?

【问题讨论】:

【参考方案1】:

Flatten 层的输入是 VGG16 模型的输出(实际上是它的卷积基,因为您要移除顶部的密集分类器)而不是您的图像。而且 VGG16 模型已经有一个输入层,所以不需要再创建一个。因此,您可以这样做:

vgg_base = applications.VGG16(include_top=False, weights='imagenet', input_shape=(img_width,img_height,3))

model = Sequentail(vgg_base)
model.add(Flatten())
# the rest of the layers you want to add

VGG16 是一个顺序模型,因此上述方法有效。但是,对于没有顺序架构的其他模型,您需要使用Keras Functional API。


我无法从您的帖子中了解到您正在同时执行特征提取 + 分类,或者您已经提取了特征,现在您想使用它们对图像进行分类。上述方法适用于前一种情况。但是对于后一种情况,正如我之前提到的,Flatten 层的输入是提取的特征(即 VGG16 基础的输出)而不是图像。因此您必须正确设置input_shape 参数:

model = Sequentail()
model.add(Flatten(input_shape=(3,3,512))
# the rest of the layers

【讨论】:

以上是关于从 Vgg16 网络导入后如何更改瓶颈特征的输入形状的主要内容,如果未能解决你的问题,请参考以下文章

任务四: 创建总的网络模型

当用作预训练特征提取器时,VGG16 应该提取多少特征?

VGG

对保存的vgg16.ckpt模型实现特征图可视化

对保存的vgg16.ckpt模型实现特征图可视化

VGG-16网络简介-2020-05-06