在 C/C++ 中使用 TensorFlow 预训练好的模型—— 间接调用 Python 实现

栏目: C++ · 发布时间: 6年前

内容简介:现在的深度学习框架一般都是基于 Python 来实现,构建、训练、保存和调用模型都可以很容易地在 Python 下完成。但有时候,我们在实际应用这些模型的时候可能需要在其他编程语言下进行,本文将通过 C/C++ 间接调用 Python 的方式来实现在 C/C++ 程序中调用 TensorFlow 预训练好的模型。获取更多精彩,请关注「seniusen」!

现在的深度学习框架一般都是基于 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 模块及相关函数

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!\n");
    }

    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!\n");
    }

    funcName = "predict";  // Function name in the python file.
    predict = PyObject_GetAttrString(pMod, funcName);
    if(!predict)
    {
        printf("Import predict Function failed!\n");
    }

    PyEval_CallObject(load_model, NULL); // 导入预训练的模型
    pParm = PyTuple_New(1); // 新建一个元组,参数只能通过元组传入 Python 程序
}

复制代码
  • 通过 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++;
    }
}

复制代码
  • 读入测试数据,并将数据填入到一个列表。

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]);
    }
}
复制代码
  • 传入元组到 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\n", iRetVal[j]);
        j++;
    }
    printf("Done!\n");
    Py_Finalize();

    return 0;
}
复制代码

获取更多精彩,请关注「seniusen」!

在 C/C++ 中使用 TensorFlow 预训练好的模型—— 间接调用 Python 实现

以上所述就是小编给大家介绍的《在 C/C++ 中使用 TensorFlow 预训练好的模型—— 间接调用 Python 实现》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Effective C# 中文版

Effective C# 中文版

Bill Wagner / 李建忠 / 人民邮电出版社 / 2007-5 / 49.00元

本书围绕一些关于C#和.NET的重要主题,包括C#语言元素、.NET资源管理、使用C#表达设计、创建二进制组件和使用框架等,讲述了最常见的50个问题的解决方案,为程序员提供了改善C#和.NET程序的方法。本书通过将每个条款构建在之前的条款之上,并合理地利用之前的条款,来让读者最大限度地学习书中的内容,为其在不同情况下使用最佳构造提供指导。 本书适合各层次的C#程序员阅读,同时可以推荐给高校教......一起来看看 《Effective C# 中文版》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具