當前位置:
首頁 > 知識 > C/C++ 使用 TensorFlow 預訓練好模型——間接調用 Python 實現

C/C++ 使用 TensorFlow 預訓練好模型——間接調用 Python 實現

現在的深度學習框架一般都是基於 Python 來實現,構建、訓練、保存和調用模型都可以很容易地在 Python 下完成。但有時候,我們在實際應用這些模型的時候可能需要在其他編程語言下進行,本文將通過 C/C++ 間接調用 Python 的方式來實現在 C/C++ 程序中調用 TensorFlow 預訓練好的模型。

1. 環境配置

  • 為了能在 C/C++ 中調用 Python,我們需要配置一下頭文件和庫的路徑,本文以 Code::Blocks 為例介紹。
  • 在 Build -> Project options 添加鏈接庫 libpython3.5m.so 和頭文件 Python.h 所在的路徑,不同 Python 版本可以自己根據情況調整。

C/C++ 使用 TensorFlow 預訓練好模型——間接調用 Python 實現

C/C++ 使用 TensorFlow 預訓練好模型——間接調用 Python 實現

2. 初始化並導入 Python 模塊及相關函數

  • 點擊回顧如何在 Python 中調用 TensorFlow 預訓練好的模型

void Initialize()
{
Py_Initialize();
if ( !Py_IsInitialized() )
{
printf("Initialize failed!");
}
// Path of the python file. 需要更改為 python 文件所在路徑
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append("/home/senius/python/c_python/test/")");
const char* modulName = "forward"; // Module name of python file.
pMod = PyImport_ImportModule(modulName);
if(!pMod)
{
printf("Import Module failed!
");
}
const char* funcName = "load_model"; // Function name in the python file.
load_model = PyObject_GetAttrString(pMod, funcName);
if(!load_model)
{
printf("Import load_model Function failed!
");
}
funcName = "predict"; // Function name in the python file.
predict = PyObject_GetAttrString(pMod, funcName);
if(!predict)
{
printf("Import predict Function failed!
");
}
PyEval_CallObject(load_model, NULL); // 導入預訓練的模型
pParm = PyTuple_New(1); // 新建一個元組,參數只能通過元組傳入 Python 程序
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

  • 通過 PyImport_ImportModule 我們可以導入需要調用的 Python 文件,然後再通過 PyObject_GetAttrString 得到模塊裡面的函數,最後導入預訓練的模型並新建一個元組作為參數的傳入。

3. 構建從 C 傳入 Python 的參數

void Read_data()
{
const char* txtdata_path = "/home/senius/python/c_python/test/04t30t00.npy";
//Path of the TXT file. 需要更改為txt文件所在路徑
FILE *fp;
fp = fopen(txtdata_path, "rb");
if(fp == NULL)
{
printf("Unable to open the file!");
}
fread(data, num*SIZE, sizeof(float), fp);
fclose(fp);
// copying the data to the list
int j = 0;
pArgs = PyList_New(num * SIZE); // 新建一個列表,並填入數據
while(j < num * SIZE)
{
PyList_SET_ITEM(pArgs, j, Py_BuildValue("f", data[j]));
j++;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

  • 讀入測試數據,並將數據填入到一個列表。

4. 將列表傳入元組,然後作為參數傳入 Python 中,並解析返回值

void Test()
{
PyTuple_SetItem(pParm, 0, pArgs);
pRetVal = PyEval_CallObject(predict, pParm);
int list_len = PyList_Size(pRetVal);
PyObject *list_item = NULL;
PyObject *tuple_item = NULL;
for (int i = 0; i < list_len; i++)
{
list_item = PyList_GetItem(pRetVal, i);
tuple_item = PyList_AsTuple(list_item);
PyArg_ParseTuple(tuple_item, "f", &iRetVal[i]);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

  • 傳入元組到 Python 程序,調用 predict 函數得到返回值,然後進行解析。

5. 一些參數和主函數

#include <Python.h>
#include <stdio.h>
#define SIZE 41*41*41*3
#define NUM 100
PyObject* pMod = NULL;
PyObject* load_model = NULL;
PyObject* predict = NULL;
PyObject* pParm = NULL;
PyObject* pArgs = NULL;
PyObject* pRetVal = NULL;
float iRetVal[NUM*3] = {0};
float data[NUM * SIZE] = {0};
int num = 1; //實際的樣本數100
void Initialize();
void Read_data();
void Test();
int main(int argc, char **argv)
{
Initialize(); // 初始化
Read_data(); // 讀入數據
Test(); // 調用預測函數並解析返回值

int j = 0;
while(j < num*3)
{
printf("%f
", iRetVal[j]);
j++;
}
printf("Done!
");
Py_Finalize();
return 0;
}

C/C++ 使用 TensorFlow 預訓練好模型——間接調用 Python 實現

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

MyBatis 註解形式返回Map
ELK日誌系統之通用應用程序日誌接入方案

TAG:程序員小新人學習 |