我想使用来自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网络吗?
答案 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询问是否有更好的解决方法。如果我想获得更多信息,我会更新这个答案。