简体   繁体   English

将keras h5转换为tensorflow pb以进行批处理推断

[英]convert keras h5 to tensorflow pb for batch inference

I have a problem with making batch inference using a tensorflow protobuf graph exported from a keras h5 model. 我使用从keras h5模型导出的tensorflow protobuf图进行批处理推理时遇到问题。 Eventhough the exported pb graph can accept multiple inputs (samples), it always gives a single output regardless of the number of inputs. 尽管导出的pb图可以接受多个输入(样本),但无论输入数量如何,它始终提供单个输出。 Here is a simple example to demonstrate the problem. 这是一个简单的示例来演示此问题。

from keras.models import Model,load_model
from keras.layers import Dense, Input
from keras import backend as K
import tensorflow as tf
import numpy as np
import os
import os.path as osp

pinput = Input(shape=[10,], name='my_input')
poutput = Dense(1, activation='sigmoid')(pinput)
model = Model(inputs=[pinput], outputs=[poutput])

model.compile(loss='mean_squared_error',optimizer='sgd',metrics=['accuracy'])
data = np.random.random((100, 10))
labels = np.random.randint(2, size=(100, 1))
model.fit(data, labels, epochs=1, batch_size=32)

x = np.random.random((3, 10))
y = model.predict(x)
print y

####################################
# Save keras h5 to tensorflow pb
####################################

K.set_learning_phase(0)

#alias output names
numoutputs = 1
pred = [None]*numoutputs
pred_node_names = [None]*numoutputs
for i in range(numoutputs):
    pred_node_names[i] = 'output'+'_'+str(i)
    pred[i] = tf.identity(model.output[i], name=pred_node_names[i])
print('Output nodes names are: ', pred_node_names)

sess = K.get_session()

# Write the graph in human readable
f = 'graph_def_for_reference.pb.ascii'
tf.train.write_graph(sess.graph.as_graph_def(), '.', f, as_text=True)

input_graph_def = sess.graph.as_graph_def()

#freeze graph
from tensorflow.python.framework.graph_util import convert_variables_to_constants
output_names = pred_node_names
output_names += [v.op.name for v in tf.global_variables()]
constant_graph = convert_variables_to_constants(sess, input_graph_def,output_names)

# Write the graph in binary .pb file
from tensorflow.python.framework import graph_io
graph_io.write_graph(constant_graph, '.', 'model.pb', as_text=False)

def load_graph(frozen_graph_filename):
    # We load the protobuf file from the disk and parse it to retrieve the 
    # unserialized graph_def
    with tf.gfile.GFile(frozen_graph_filename, "rb") as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())

    # Then, we import the graph_def into a new Graph and returns it 
    with tf.Graph().as_default() as graph:
        # The name var will prefix every op/nodes in your graph
        # Since we load everything in a new graph, this is not needed
        tf.import_graph_def(graph_def, name="prefix")
    return graph

###################################
# Test batch inference with tf
###################################
graph = load_graph("model.pb")
for op in graph.get_operations():
    print(op.name)

minput = graph.get_tensor_by_name('prefix/my_input:0')
moutput = graph.get_tensor_by_name('prefix/output_0:0')
with tf.Session(graph=graph) as sess:
    y = sess.run(moutput, feed_dict={minput: x})
print y

The output of the run is 运行的输出是

Epoch 1/1
100/100 [==============================] - 0s 661us/step - loss: 0.2655 - acc: 0.3900
[[0.62018263]
 [0.41664478]
 [0.40322617]]
('Output nodes names are: ', ['output_0'])
prefix/my_input
prefix/dense_1/kernel
prefix/dense_1/kernel/read
prefix/dense_1/bias
prefix/dense_1/bias/read
prefix/dense_1/MatMul
prefix/dense_1/BiasAdd
prefix/dense_1/Sigmoid
prefix/SGD/iterations
prefix/SGD/lr
prefix/SGD/momentum
prefix/SGD/decay
prefix/training/SGD/Variable
prefix/training/SGD/Variable_1
prefix/strided_slice/stack
prefix/strided_slice/stack_1
prefix/strided_slice/stack_2
prefix/strided_slice
prefix/output_0
[0.62018263]

You can see the keras h5 graphs gives 3 ouputs wile the tensorflow pb graph just gives the first output. 您可以看到keras h5图给出了3个输出,而tensorflow pb图仅给出了第一个输出。 What am I doing wrong? 我究竟做错了什么? I would like to modify the h5 to pb conversion process so that I can do batch inference using the pb grapth with the python and c++ tensorflow backends. 我想修改h5到pb的转换过程,以便可以使用python和c ++ tensorflow后端的pb grapth进行批推断。

It turns out this is due to a bug I inherited from k2tf_convert 原来这是由于我从k2tf_convert继承的错误

pred[i] = tf.identity(model.output[i], name=pred_node_names[i])

should be 应该

pred[i] = tf.identity(model.outputs[i], name=pred_node_names[i])

It seems the keras model class has both 'output' and 'outputs' members that makes this bug hard to track. 看来keras模型类同时具有'output'和'outputs'成员,这使得此bug难以跟踪。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将 Keras.h5 导出为 tensorflow.pb? - How to export Keras .h5 to tensorflow .pb? 无法将 keras/tensorflow h5/json 转换为 tensorflow pb - Trouble converting keras/tensorflow h5/json into tensorflow pb 如何将预训练的 tensorflow pb 冻结图转换为可修改的 h5 keras 模型? - How to convert a pretrained tensorflow pb frozen graph into a modifiable h5 keras model? Convert a Tensorflow model in SavedModel format (.pb file) saved with tf.saved_model.save to a Keras model (.h5 file) - Convert a Tensorflow model in SavedModel format (.pb file) saved with tf.saved_model.save to a Keras model (.h5 file) 如何将具有自定义 keras 层(.h5)的 keras 模型冻结到张量流图(.pb)? - How to freeze a keras model with custom keras layers(.h5) to tensorflow graph(.pb)? tf.keras h5到Tensorflow pb-即使输入明显具有输出的结果,pb也没有输出节点? - tf.keras h5 to Tensorflow pb - resulting pb lacks output node even though input clearly has it? 如何将 .h5 文件转换为 .pb 文件? - how to convert .h5 file to .pb file? 如何将 .pb 文件转换为 .h5。 (Tensorflow 模型到 keras) - How to convert .pb file to .h5. (Tensorflow model to keras) .pb文件的推断结果与.h5不匹配 - Inference result with .pb file does not match with .h5 Tensorflow lite model 推理与 keras h5 model(VGG16 预训练)相比非常慢 - Tensorflow lite model inference is very slow compared to keras h5 model (VGG16 pretrained)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM