使用张量输入时Keras模型预测会发生变化

时间:2017-06-19 09:55:37

标签: python tensorflow keras

我想使用来自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&#39; predict函数用于计算预测,结果是正确的。但是,如果我从图像数组中取出张量并通过input_tensor=...将该张量提供给模型,然后通过sess.run([model.output], ...)计算预测,则结果非常错误。

不同行为的原因是什么?我不能以这种方式使用Keras网络吗?

1 个答案:

答案 0 :(得分:1)

最后,通过挖掘InceptionV3代码,我发现了问题:sess.run(init)覆盖InceptionV3构造函数中加载的weigts。 我发现这个问题的重要修复是在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的构造函数,在我的示例中,特定于使用{{1恢复整个网络的权重}}。 我在this Github issue询问是否有更好的解决方法。如果我想获得更多信息,我会更新这个答案。