簡體   English   中英

從 Python 導出 Tensorflow 圖以在 C++ 中使用

[英]Export Tensorflow graphs from Python for use in C++

究竟應該如何導出 python 模型以在 C++ 中使用?

我正在嘗試做一些類似於本教程的事情: https : //www.tensorflow.org/versions/r0.8/tutorials/image_recognition/index.html

我正在嘗試在 C++ API 中導入我自己的 TF 模型,而不是最初的模型。 我調整了輸入大小和路徑,但奇怪的錯誤不斷出現。 我花了一整天的時間閱讀堆棧溢出和其他論壇,但無濟於事。

我嘗試了兩種導出圖形的方法。

方法一:元圖。

...loading inputs, setting up the model, etc....

sess = tf.InteractiveSession()
sess.run(tf.initialize_all_variables())


for i in range(num_steps):  
  x_batch, y_batch = batch(50)  
  if i%10 == 0:
        train_accuracy = accuracy.eval(feed_dict={
        x:x_batch, y_: y_batch, keep_prob: 1.0})
        print("step %d, training accuracy %g"%(i, train_accuracy))
  train_step.run(feed_dict={x: x_batch, y_: y_batch, keep_prob: 0.5})

print("test accuracy %g"%accuracy.eval(feed_dict={
    x: features_test, y_: labels_test, keep_prob: 1.0}))

saver = tf.train.Saver(tf.all_variables())
checkpoint = 
   '/home/sander/tensorflow/tensorflow/examples/cat_face/data/model.ckpt'
    saver.save(sess, checkpoint)

   tf.train.export_meta_graph(filename=
   '/home/sander/tensorflow/tensorflow/examples/cat_face/data/cat_graph.pb',  
    meta_info_def=None,
    graph_def=sess.graph_def,
    saver_def=saver.restore(sess, checkpoint),
    collection_list=None, as_text=False)

嘗試運行程序時,方法 1 會產生以下錯誤:

[libprotobuf ERROR 
google/protobuf/src/google/protobuf/wire_format_lite.cc:532] String field 
'tensorflow.NodeDef.op' contains invalid UTF-8 data when parsing a protocol 
buffer. Use the 'bytes' type if you intend to send raw bytes. 
E tensorflow/examples/cat_face/main.cc:281] Not found: Failed to load 
compute graph at 'tensorflow/examples/cat_face/data/cat_graph.pb'

我還嘗試了另一種導出圖形的方法:

方法二:write_graph:

tf.train.write_graph(sess.graph_def, 
'/home/sander/tensorflow/tensorflow/examples/cat_face/data/', 
'cat_graph.pb', as_text=False)

這個版本實際上似乎加載了一些東西,但我收到一個關於變量未初始化的錯誤:

Running model failed: Failed precondition: Attempting to use uninitialized  
value weight1
[[Node: weight1/read = Identity[T=DT_FLOAT, _class=["loc:@weight1"], 
_device="/job:localhost/replica:0/task:0/cpu:0"](weight1)]]

首先,您需要使用以下命令將定義圖形化到文件中

with tf.Session() as sess:
//Build network here 
tf.train.write_graph(sess.graph.as_graph_def(), "C:\\output\\", "mymodel.pb")

然后,使用 saver 保存您的模型

saver = tf.train.Saver(tf.global_variables()) 
saver.save(sess, "C:\\output\\mymodel.ckpt")

然后,您的輸出將有 2 個文件,mymodel.ckpt,mymodel.pb

這里下載 freeze_graph.py 並在 C:\\output\\ 中運行以下命令。 如果輸出節點名稱與您不同,請更改它。

python freeze_graph.py --input_graph mymodel.pb --input_checkpoint mymodel.ckpt --output_node_names softmax/Reshape_1 --output_graph mymodelforc.pb

您可以直接從 C 使用 mymodelforc.pb。

您可以使用以下 C 代碼加載 proto 文件

#include "tensorflow/core/public/session.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/cc/ops/image_ops.h"

Session* session;
NewSession(SessionOptions(), &session);

GraphDef graph_def;
ReadBinaryProto(Env::Default(), "C:\\output\\mymodelforc.pb", &graph_def);

session->Create(graph_def);

現在您可以使用會話進行推理。

您可以應用推理參數如下:

// Same dimension and type as input of your network
tensorflow::Tensor input_tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({ 1, height, width, channel }));
std::vector<tensorflow::Tensor> finalOutput;

// Fill input tensor with your input data

std::string InputName = "input"; // Your input placeholder's name
std::string OutputName = "softmax/Reshape_1"; // Your output placeholder's name

session->Run({ { InputName, input_tensor } }, { OutputName }, {}, &finalOutput);

// finalOutput will contain the inference output that you search for

你可以試試這個(修改輸出層的名稱):

import os
import tensorflow as tf
from tensorflow.python.framework import graph_util


def load_graph_def(model_path, sess=None):
    sess = sess if sess is not None else tf.get_default_session()
    saver = tf.train.import_meta_graph(model_path + '.meta')
    saver.restore(sess, model_path)


def freeze_graph(sess, output_layer_name, output_graph):
    graph = tf.get_default_graph()
    input_graph_def = graph.as_graph_def()

    # Exporting the graph
    print("Exporting graph...")
    output_graph_def = graph_util.convert_variables_to_constants(
        sess,
        input_graph_def,
        output_layer_name.split(","))

    with tf.gfile.GFile(output_graph, "wb") as f:
        f.write(output_graph_def.SerializeToString())


def freeze_from_checkpoint(checkpoint_file, output_layer_name):

    model_folder = os.path.basename(checkpoint_file)
    output_graph = os.path.join(model_folder, checkpoint_file + '.pb')

    with tf.Session() as sess:

        load_graph_def(checkpoint_file)

        freeze_graph(sess, output_layer_name, output_graph)


if __name__ == '__main__':
    freeze_from_checkpoint(
        checkpoint_file='/home/sander/tensorflow/tensorflow/examples/cat_face/data/model.ckpt',
        output_layer_name='???')

您會發現 OpenCV 的DNN模塊非常有用。 它使加載和使用使用 Tensorflow(和其他框架)開發的預訓練模型變得簡單。

它可以在 C++ 程序中使用。

是一個教程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM