使用预训练的Inceptionv3提取瓶颈特征 - Keras的实现和Native Tensorflow实现之间的差异

dum*_*urp 8 python keras tensorflow

(长篇道歉)

所有,

我想使用预训练的Inceptionv3模型的瓶颈功能来预测输入图像的分类.在训练模型和预测分类之前,我尝试了3种不同的方法来提取瓶颈功能.

我的3种方法产生了不同的瓶颈特征(不仅仅是数值,甚至大小也不同).

  1. 方法1和2的瓶颈特征:(输入图像数量)x 3 x 3 x 2048

    我的瓶颈大小来自方法3 :(输入图像的数量)x 2048

    为什么基于Keras的Inceptionv3模型和原生Tensorflow模型之间的大小不同?我的猜测是,当我在Keras中说include_top = False时,我没有提取'pool_3/_reshape:0'层.它是否正确?如果是,我如何在Keras中提取'pool_3/_reshape:0'图层?如果我的猜测不正确,我错过了什么?

  2. 我比较了方法1和方法2中的瓶颈特征值,它们有显着差异.我想我正在为它输入相同的输入图像,因为我在将其作为我的脚本的输入读取之前调整大小并重新调整我的图像.我在方法1中没有选择ImageDataGenerator,根据该函数的文档,所有默认值都不会改变我的输入图像.我已将shuffle设置为false,因此我假设predict_generator和predict是以相同的顺序读取图像.我错过了什么?


请注意:

我的输入图像是RGB格式(因此通道数= 3),我将它们全部调整为150x150.我使用了inceptionv3.py中的preprocess_input函数来预处理我的所有图像.

def preprocess_input(image):
    image /= 255.
    image -= 0.5
    image *= 2.
    return image
Run Code Online (Sandbox Code Playgroud)

方法1:使用带有tensorflow作为后端的Keras,用于读取我的数据的ImageDataGenerator和用于计算瓶颈功能的model.predict_generator

我按照Keras的博客中的示例(使用预先训练的网络的瓶颈功能:一分钟内90%的准确度).我没有列出那里列出的VGG模型,而是使用了Inceptionv3.下面是我使用的代码片段

(这里没有显示代码,但是我在下面的代码之前做了什么):读取所有输入图像,调整大小为150x150x3,根据上面提到的preprocessing_input函数重新缩放,保存调整大小和重新缩放的图像

train_datagen = ImageDataGenerator() 
train_generator = train_datagen.flow_from_directory(my_input_dir, target_size=(150,150),shuffle=False, batch_size=16)

# get bottleneck features
# use pre-trained model and exclude top layer - which is used for classification
pretrained_model = InceptionV3(include_top=False, weights='imagenet', input_shape=(150,150,3))
bottleneck_features_train_v1 = pretrained_model.predict_generator(train_generator,len(train_generator.filenames)//16)
Run Code Online (Sandbox Code Playgroud)

方法2:使用带有tensorflow作为后端的Keras,我自己的reader和model.predict来计算瓶颈特征

这种方法与早期方法之间的区别仅在于我使用自己的阅读器来读取输入图像.(这里没有显示代码,但是我在下面的代码之前做了什么):读取所有输入图像,调整大小为150x150x3,根据上面提到的preprocessing_input函数重新缩放,保存调整大小和重新缩放的图像

# inputImages is a numpy array of size <number of input images x 150 x 150 x 3>
inputImages = readAllJPEGsInFolderAndMergeAsRGB(my_input_dir)

# get bottleneck features
# use pre-trained model and exclude top layer - which is used for classification
pretrained_model = InceptionV3(include_top=False, weights='imagenet', input_shape=(img_width, img_height, 3))
bottleneck_features_train_v2 = pretrained_model.predict(trainData.images,batch_size=16)
Run Code Online (Sandbox Code Playgroud)

方法3:使用张量流(NO KERAS)计算瓶颈特征

我跟着retrain.py来提取输入图像的瓶颈功能.请注意,该脚本的权重可以从(http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz)获得.

如该示例中所述,我使用了bottleneck_tensor_name ='pool_3/_reshape:0'作为提取和计算瓶颈功能的图层.与前两种方法类似,我使用调整大小和重新缩放的图像作为脚本的输入,我称之为功能列表bottleneck_features_train_v3

非常感谢

Dan*_*ler 4

1 和 2 之间的不同结果

由于您没有显示您的代码,我(可能是错误的)建议问题是您preprocess_input在声明时可能没有使用ImageDataGenerator?

from keras.applications.inception_v3 import preprocess_input

train_datagen = ImageDataGenerator(preprocessing_function=preprocess_input) 
Run Code Online (Sandbox Code Playgroud)

不过,请确保您保存的图像文件的范围是从 0 到 255。(位深度 24)。

1和3之间的不同形状

在这种情况下,存在三种可能的模型类型:

  • include_top = True-> 这将返回类
  • include_top = False(仅)-> 这意味着pooling = None(没有最终池化层)
  • include_top = False, pooling='avg'或者='max'-> 有一个池化层

因此,您声明的没有显式的模型pooling=something在 keras 中没有最终的池化层。那么输出仍然具有空间维度。

只需在最后添加一个池化即可解决该问题。其中之一:

pretrained_model = InceptionV3(include_top=False, pooling = 'avg', weights='imagenet', input_shape=(img_width, img_height, 3))
pretrained_model = InceptionV3(include_top=False, pooling = 'max', weights='imagenet', input_shape=(img_width, img_height, 3))
Run Code Online (Sandbox Code Playgroud)

不确定tgz文件中的模型使用的是哪一种。

作为替代方案,您还可以从 Tensorflow 模型中获取另一层,即之前的一层'pool_3'