在 C/C++ 中使用 TensorFlow 预训练好的模型—— 直接调用 C++ 接口实现
生活随笔
收集整理的這篇文章主要介紹了
在 C/C++ 中使用 TensorFlow 预训练好的模型—— 直接调用 C++ 接口实现
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
現(xiàn)在的深度學(xué)習(xí)框架一般都是基于 Python 來實現(xiàn),構(gòu)建、訓(xùn)練、保存和調(diào)用模型都可以很容易地在 Python 下完成。但有時候,我們在實際應(yīng)用這些模型的時候可能需要在其他編程語言下進行,本文將通過直接調(diào)用 TensorFlow 的 C/C++ 接口來導(dǎo)入 TensorFlow 預(yù)訓(xùn)練好的模型。
1.環(huán)境配置 點此查看 C/C++ 接口的編譯
2. 導(dǎo)入預(yù)定義的圖和訓(xùn)練好的參數(shù)值
// set up your input pathsconst string pathToGraph = "/home/senius/python/c_python/test/model-10.meta";const string checkpointPath = "/home/senius/python/c_python/test/model-10";auto session = NewSession(SessionOptions()); // 創(chuàng)建會話if (session == nullptr){throw runtime_error("Could not create Tensorflow session.");}Status status;// Read in the protobuf graph we exportedMetaGraphDef graph_def;status = ReadBinaryProto(Env::Default(), pathToGraph, &graph_def);  // 導(dǎo)入圖模型if (!status.ok()){throw runtime_error("Error reading graph definition from " + pathToGraph + ": " + status.ToString());}// Add the graph to the sessionstatus = session->Create(graph_def.graph_def());  // 將圖模型加入到會話中if (!status.ok()){throw runtime_error("Error creating graph: " + status.ToString());}// Read weights from the saved checkpointTensor checkpointPathTensor(DT_STRING, TensorShape());checkpointPathTensor.scalar<std::string>()() = checkpointPath; // 讀取預(yù)訓(xùn)練好的權(quán)重status = session->Run({{graph_def.saver_def().filename_tensor_name(), checkpointPathTensor},}, {},{graph_def.saver_def().restore_op_name()}, nullptr);if (!status.ok()){throw runtime_error("Error loading checkpoint from " + checkpointPath + ": " + status.ToString());} 復(fù)制代碼3. 準(zhǔn)備測試數(shù)據(jù)
const string filename = "/home/senius/python/c_python/test/04t30t00.npy";//Read TXT data to arrayfloat Array[1681*41];ifstream is(filename);for (int i = 0; i < 1681*41; i++){is >> Array[i];}is.close();tensorflow::Tensor input_tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({1, 41, 41, 41, 1}));auto input_tensor_mapped = input_tensor.tensor<float, 5>();float *pdata = Array;// copying the data into the corresponding tensorfor (int x = 0; x < 41; ++x)//depth{for (int y = 0; y < 41; ++y) {for (int z = 0; z < 41; ++z) {const float *source_value = pdata + x * 1681 + y * 41 + z;input_tensor_mapped(0, x, y, z, 0) = *source_value;}}} 復(fù)制代碼- 本例中輸入數(shù)據(jù)是一個 [None, 41, 41, 41, 1] 的張量,我們需要先從 TXT 文件中讀出測試數(shù)據(jù),然后正確地填充到張量中去。
4. 前向傳播得到預(yù)測值
std::vector<tensorflow::Tensor> finalOutput;std::string InputName = "X"; // Your input placeholder's namestd::string OutputName = "sigmoid"; // Your output tensor's namevector<std::pair<string, Tensor> > inputs;inputs.push_back(std::make_pair(InputName, input_tensor));// Fill input tensor with your input datasession->Run(inputs, {OutputName}, {}, &finalOutput);auto output_y = finalOutput[0].scalar<float>();std::cout << output_y() << "\n"; 復(fù)制代碼- 通過給定輸入和輸出張量的名字,我們可以將測試數(shù)據(jù)傳入到模型中,然后進行前向傳播得到預(yù)測值。
5. 一些問題
- 本模型是在 TensorFlow 1.4 下訓(xùn)練的,然后編譯 TensorFlow 1.4 的 C++ 接口可以正常調(diào)用模型,但若是想調(diào)用更高版本訓(xùn)練好的模型,則會報錯,據(jù)出錯信息猜測可能是高版本的 TensorFlow 中添加了一些低版本沒有的函數(shù),所以不能正常運行。
- 若是編譯高版本的 TensorFlow ,比如最新的 TensorFlow 1.11 的 C++ 接口,則無論是調(diào)用舊版本訓(xùn)練的模型還是新版本訓(xùn)練的模型都不能正常運行。出錯信息如下:Error loading checkpoint from /media/lab/data/yongsen/Tensorflow_test/test/model-40: Invalid argument: Session was not created with a graph before Run()!,網(wǎng)上暫時也查不到解決辦法,姑且先放在這里。
6. 完整代碼
#include </home/senius/tensorflow-r1.4/bazel-genfiles/tensorflow/cc/ops/io_ops.h> #include </home/senius/tensorflow-r1.4/bazel-genfiles/tensorflow/cc/ops/parsing_ops.h> #include </home/senius/tensorflow-r1.4/bazel-genfiles/tensorflow/cc/ops/array_ops.h> #include </home/senius/tensorflow-r1.4/bazel-genfiles/tensorflow/cc/ops/math_ops.h> #include </home/senius/tensorflow-r1.4/bazel-genfiles/tensorflow/cc/ops/data_flow_ops.h>#include <tensorflow/core/public/session.h> #include <tensorflow/core/protobuf/meta_graph.pb.h> #include <fstream>using namespace std; using namespace tensorflow; using namespace tensorflow::ops;int main() {// set up your input pathsconst string pathToGraph = "/home/senius/python/c_python/test/model-10.meta";const string checkpointPath = "/home/senius/python/c_python/test/model-10";auto session = NewSession(SessionOptions());if (session == nullptr){throw runtime_error("Could not create Tensorflow session.");}Status status;// Read in the protobuf graph we exportedMetaGraphDef graph_def;status = ReadBinaryProto(Env::Default(), pathToGraph, &graph_def);if (!status.ok()){throw runtime_error("Error reading graph definition from " + pathToGraph + ": " + status.ToString());}// Add the graph to the sessionstatus = session->Create(graph_def.graph_def());if (!status.ok()){throw runtime_error("Error creating graph: " + status.ToString());}// Read weights from the saved checkpointTensor checkpointPathTensor(DT_STRING, TensorShape());checkpointPathTensor.scalar<std::string>()() = checkpointPath;status = session->Run({{graph_def.saver_def().filename_tensor_name(), checkpointPathTensor},}, {},{graph_def.saver_def().restore_op_name()}, nullptr);if (!status.ok()){throw runtime_error("Error loading checkpoint from " + checkpointPath + ": " + status.ToString());}cout << 1 << endl;const string filename = "/home/senius/python/c_python/test/04t30t00.npy";//Read TXT data to arrayfloat Array[1681*41];ifstream is(filename);for (int i = 0; i < 1681*41; i++){is >> Array[i];}is.close();tensorflow::Tensor input_tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({1, 41, 41, 41, 1}));auto input_tensor_mapped = input_tensor.tensor<float, 5>();float *pdata = Array;// copying the data into the corresponding tensorfor (int x = 0; x < 41; ++x)//depth{for (int y = 0; y < 41; ++y) {for (int z = 0; z < 41; ++z) {const float *source_value = pdata + x * 1681 + y * 41 + z; // input_tensor_mapped(0, x, y, z, 0) = *source_value;input_tensor_mapped(0, x, y, z, 0) = 1;}}}std::vector<tensorflow::Tensor> finalOutput;std::string InputName = "X"; // Your input placeholder's namestd::string OutputName = "sigmoid"; // Your output placeholder's namevector<std::pair<string, Tensor> > inputs;inputs.push_back(std::make_pair(InputName, input_tensor));// Fill input tensor with your input datasession->Run(inputs, {OutputName}, {}, &finalOutput);auto output_y = finalOutput[0].scalar<float>();std::cout << output_y() << "\n";return 0; } 復(fù)制代碼- Cmakelist?文件如下
獲取更多精彩,請關(guān)注「seniusen」!
總結(jié)
以上是生活随笔為你收集整理的在 C/C++ 中使用 TensorFlow 预训练好的模型—— 直接调用 C++ 接口实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mysql-高性能索引
- 下一篇: MariaDB数据库日志