首页 文章

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

提问于
浏览
4

(长篇道歉)

所有,

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

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

  • 方法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'图层?如果我的猜测不正确,我错过了什么?

  • 我比较了方法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

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

我跟随了Keras博客的example(章节使用预训练网络的瓶颈功能:一分钟内准确度达到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)

方法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)

方法3:使用tensorflow(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

非常感谢

2 回答

  • 2

    你可以在这里查看inceptionv3的Keras实现:https://github.com/keras-team/keras/blob/master/keras/applications/inception_v3.py

    所以,默认参数是:

    def InceptionV3(include_top=True,
                    weights='imagenet',
                    input_tensor=None,
                    input_shape=None,
                    pooling=None,
                    classes=1000):
    

    请注意,pooling = None的默认值,然后在构建模型时,代码为:

    if include_top:
        # Classification block
        x = GlobalAveragePooling2D(name='avg_pool')(x)
        x = Dense(classes, activation='softmax', name='predictions')(x)
    else:
        if pooling == 'avg':
            x = GlobalAveragePooling2D()(x)
        elif pooling == 'max':
            x = GlobalMaxPooling2D()(x)
    
    # Ensure that the model takes into account
    # any potential predecessors of `input_tensor`.
    if input_tensor is not None:
        inputs = get_source_inputs(input_tensor)
    else:
        inputs = img_input
    # Create model.
    model = Model(inputs, x, name='inception_v3')
    

    因此,如果您未指定池,则在不进行任何池化的情况下提取瓶颈功能,您需要指定是否要在这些功能之上获得平均池或最大池 .

  • 1

    介于1和2之间的不同结果

    既然你没有显示你的代码,我(可能是错误地)提出问题是你在声明 ImageDataGenerator 时可能没有使用 preprocess_input

    from keras.applications.inception_v3 import preprocess_input
    
    train_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)
    

    但请确保保存的图像文件范围为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))
    

    不确定 tgz 文件中的哪个模型正在使用 .

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

相关问题