.h5模型和.pb模型之间的输出值误差很小

时间:2020-05-05 17:17:45

标签: python-3.x tensorflow keras deep-learning

我在d = df.to_dict(orient="index") d {1495: {'Acct_num': 5001, 'Acct_Name': 'Alpha', 'Prod': 'ret34', 'Date': '4/30/2020', 'Rev': 4999}, 1496: {'Acct_num': 5002, 'Acct_Name': 'Beta', 'Prod': 'pro45', 'Date': '4/30/2020', 'Rev': 18076}, 1497: {'Acct_num': 5003, 'Acct_Name': 'Gamma', 'Prod': 'sli55', 'Date': '4/30/2020', 'Rev': 5671}, 1498: {'Acct_num': 5004, 'Acct_Name': 'Delta', 'Prod': 'ret34', 'Date': '4/30/2020', 'Rev': 16683}} tf-gpu1.4+keras2.1.3上都尝试过,问题总是会发生。

问题是:将keras.application.ResNet50()模型转换为.pb格式的冻结图模型后,我将同一张图片输入转换后的.pb模型中,但是输出值仅改变了小。

下面是代码,这些代码打印ResNet输出向量的前10个元素,并冻结图形以输出pb模型文件:

tf-gpu1.12+keras2.2.4

,打印日志为:

from tensorflow.python.framework.graph_util_impl import convert_variables_to_constants
from keras.preprocessing import image
from keras.applications.resnet50 import preprocess_input, ResNet50
import keras.backend as K
K.set_learning_phase(0)

img = image.load_img('images/34rews.jpg', target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x_input = preprocess_input(x)

net_model = ResNet50(weights='imagenet', include_top=False, pooling='avg')
sess = K.get_session()
preds = sess.run(net_model.get_output_at(0), feed_dict={net_model.get_input_at(0): x_input})
print('before convert to pb :', np.array(preds).squeeze()[:10])

output_name0 = net_model.get_output_at(0).op.name  # 'global_average_pooling2d_1/Mean'
constant_graph = convert_variables_to_constants(sess, sess.graph_def, [output_name0])

with tf.gfile.GFile('saved_model_constant.pb', 'wb') as f:
    f.write(constant_graph.SerializeToString())

然后我们通过上述代码生成的pb文件预测相同的图像:

before convert to pb : [**0.99536467** 0.31807986 2.0998483  0.9077819  0.10606026 0.93215793
 0.04187933 0.10000334 1.1727284  1.0535308 ]

输出打印日志为:

def test_constant(pb_dir, img_path='images/34rews.jpg'):
    img = image.load_img(img_path, target_size=(224, 224))
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)

    from tensorflow.python.platform import gfile
    with tf.Session() as sess:
        with gfile.FastGFile(pb_dir, 'rb') as f:
            graph_def = tf.GraphDef()
            graph_def.ParseFromString(f.read())

        result = tf.import_graph_def(graph_def, return_elements=["global_average_pooling2d_1/Mean:0"], name='')
        preds = sess.run(result, feed_dict={sess.graph.get_tensor_by_name('input_1:0'):x})
        print('using pb file:', np.array(preds).squeeze()[:10])

使用冻结图方法后,我可以清楚地找到原始矢量模型和PB模型之间的预测矢量极小值误差。 例如使用原始keras模型的resnet输出向量的第一个元素值为 0.99536467 ,但使用转换后的pb文件的输出值为 0.99536514 。 我不知道为什么会有这么小的数值误差?可能不会导致较大的精度误差,但这确实很奇怪!

1 个答案:

答案 0 :(得分:0)

我删除了K.set_learning_phase(0),问题已解决。也许让Keras亲自处理K.learning_phase()可能更好。 对于我的实验,请使用Keras.model.predict()的值作为正确的结果:

with K.set_learning_phase(0) and without convert_variables_to_constants:  value is the same.
without K.set_learning_phase(0) and without convert_variables_to_constants:  value is the same.
without K.set_learning_phase(0) and with convert_variables_to_constants:  value is the same.
with K.set_learning_phase(0) and with convert_variables_to_constants:  value is changed!