【问题标题】:Keras model prediction changes when using tensor input使用张量输入时 Keras 模型预测发生变化
【发布时间】:2017-11-21 11:35:53
【问题描述】:

我想使用来自 Keras 的预训练 Inception-V3 模型,与来自 Tensorflow 的输入管道配对(即通过张量提供网络的输入输入)。 这是我的代码:

import tensorflow as tf
from keras.preprocessing.image import load_img, img_to_array
from keras.applications.inception_v3 import InceptionV3, decode_predictions, preprocess_input
import numpy as np

img_sample_filename = 'my_image.jpg'
img = img_to_array(load_img(img_sample_filename, target_size=(299,299)))
img = preprocess_input(img)
img_tensor = tf.constant(img[None,:])

# WITH KERAS:
model = InceptionV3()
pred = model.predict(img[None,:])
pred = decode_predictions(np.asarray(pred)) #<------ correct prediction!
print(pred)

# WITH TF:
model = InceptionV3(input_tensor=img_tensor)
init = tf.global_variables_initializer()

with tf.Session() as sess:
  from keras import backend as K
  K.set_session(sess)

  sess.run(init)
  pred = sess.run([model.output], feed_dict={K.learning_phase(): 0})

pred = decode_predictions(np.asarray(pred)[0])
print(pred)                               #<------ wrong prediction!

my_image.jpg 是我想要分类的任何图像。

如果我使用 keras 的 predict 函数来计算预测,结果是正确的。但是,如果我从图像数组中创建一个张量并通过input_tensor=... 将该张量提供给模型,然后通过sess.run([model.output], ...) 计算预测,则结果非常错误。

不同行为的原因是什么?不能这样使用 Keras 网络吗?

【问题讨论】:

    标签: python tensorflow keras


    【解决方案1】:

    最后,通过InceptionV3 代码挖掘,我发现了问题:sess.run(init) 覆盖了在InceptionV3 的构造函数中加载的权重。 我发现这个问题的-dirty-修复是在sess.run(init)之后重新加载权重。

    from keras.applications.inception_v3 import get_file, WEIGHTS_PATH
    
    with tf.Session() as sess:
      from keras import backend as K
      K.set_session(sess)
    
      sess.run(init)
      weights_path = get_file(
                    'inception_v3_weights_tf_dim_ordering_tf_kernels.h5',
                    WEIGHTS_PATH,
                    cache_subdir='models',
                    md5_hash='9a0d58056eeedaa3f26cb7ebd46da564')
      model.load_weights(weights_path)
      pred = sess.run([model.output], feed_dict={K.learning_phase(): 0})
    

    注意get_file() 的参数直接取自InceptionV3 的构造函数,在我的示例中,专门用于使用image_data_format='channels_last' 恢复整个网络的权重。 我在this Github issue 中询问是否有更好的解决方法。如果我应该获得更多信息,我会更新这个答案。

    【讨论】:

    • 您始终可以初始化变量子集,而不是初始化每个变量(包括模型预训练的权重)。
    猜你喜欢
    • 2019-07-27
    • 1970-01-01
    • 2023-03-15
    • 2021-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-22
    相关资源
    最近更新 更多