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

1. 环境配置

  • 为了能在 C/C++ 中调用 Python,我们需要配置一下头文件和库的路径,本文以 Code::Blocks 为例介绍。

  • 在 Build -> Project options 添加链接库 libpython3.5m.so 和头文件 Python.h 所在的路径,不同 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 实现的更多相关文章

  1. 在 C/C++ 中使用 TensorFlow 预训练好的模型—— 直接调用 C++ 接口实现

    现在的深度学习框架一般都是基于 Python 来实现,构建.训练.保存和调用模型都可以很容易地在 Python 下完成.但有时候,我们在实际应用这些模型的时候可能需要在其他编程语言下进行,本文将通过直 ...

  2. TensorFlow 调用预训练好的模型—— Python 实现

    1. 准备预训练好的模型 TensorFlow 预训练好的模型被保存为以下四个文件 data 文件是训练好的参数值,meta 文件是定义的神经网络图,checkpoint 文件是所有模型的保存路径,如 ...

  3. TensorFlow 同时调用多个预训练好的模型

    在某些任务中,我们需要针对不同的情况训练多个不同的神经网络模型,这时候,在测试阶段,我们就需要调用多个预训练好的模型分别来进行预测. 调用单个预训练好的模型请点击此处 弄明白了如何调用单个模型,其实调 ...

  4. 【猫狗数据集】使用预训练的resnet18模型

    数据集下载地址: 链接:https://pan.baidu.com/s/1l1AnBgkAAEhh0vI5_loWKw提取码:2xq4 创建数据集:https://www.cnblogs.com/xi ...

  5. pytorch中如何使用预训练词向量

    不涉及具体代码,只是记录一下自己的疑惑. 我们知道对于在pytorch中,我们通过构建一个词向量矩阵对象.这个时候对象矩阵是随机初始化的,然后我们的输入是单词的数值表达,也就是一些索引.那么我们会根据 ...

  6. 转载:tensorflow保存训练后的模型

    训练完一个模型后,为了以后重复使用,通常我们需要对模型的结果进行保存.如果用Tensorflow去实现神经网络,所要保存的就是神经网络中的各项权重值.建议可以使用Saver类保存和加载模型的结果. 1 ...

  7. tensorflow 使用预训练好的模型的一部分参数

    vars = tf.global_variables() net_var = [var for var in vars if 'bi-lstm_secondLayer' not in var.name ...

  8. Tensorflow 用训练好的模型预测

    本节涉及点: 从命令行参数读取需要预测的数据 从文件中读取数据进行预测 从任意字符串中读取数据进行预测 一.从命令行参数读取需要预测的数据 训练神经网络是让神经网络具备可用性,真正使用神经网络时,需要 ...

  9. Tensorflow使用训练好的模型进行测试,发现计算速度越来越慢

    实验时要对多个NN模型进行对比,依次加载直到第8个模型时,发现运行速度明显变慢而且电脑开始卡顿,查看内存占用90+%. 原因:使用过的NN模型还会保存在内存,继续加载一方面使新模型加载特别特别慢,另一 ...

随机推荐

  1. Android学习笔记_3_四种布局

    Android布局是应用界面开发的重要一环,在Android中,共有四种布局方式, 分别是:FrameLayout( 帧布局 ).LinearLayout (线性布局).TableLayout(表格布 ...

  2. java常见验证邮箱、电话号码、日期等格式

    package besttone.utils; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 90%的验证 ...

  3. img的空白内容如何处理

    给img加一个 vertical-align: bottom;

  4. 用c#语言编写1000以内能整除3的数字

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...

  5. [Linux]文件浏览

    1.使用file命令查看文件中数据的类型 [oracle@linuxforlijiaman Desktop]$ ls linux oracle.txt test.png [oracle@linuxfo ...

  6. 使用js获取表单元素的值

    function getParams(formName) { var frmMain = document.getElementById(formName)?document.getElementBy ...

  7. MySQL 避免行锁升级为表锁——使用高效的索引

    文章目录 普通索引 属性值重复率高 属性值重复率低 小结 众所周知,MySQL 的 InnoDB 存储引擎支持事务,支持行级锁(innodb的行锁是通过给索引项加锁实现的).得益于这些特性,数据库支持 ...

  8. django写一个简单的登陆注册

    要写这个,前提还是需要知道三个知识: 一个是urls.py,它是写我们的路由关系的,之前我写了通过wsgiref写一个简单的服务端,也用到了路由,就是 请求过来的url和视图函数的对应关系. 二是就是 ...

  9. 安装sass遇到的坑

    一.安装Sass https://www.sass.hk/install/ 根据网站的步骤进行安装 Ruby版本的选择 我第一次下载是在Ruby官网上下的2.5.0版本得ruby.然而下载了之后无(不 ...

  10. QT基于model/view数据库编程2

    Qt中数据编程主要分为以下两点:1.利用qt提供类 访问数据库或者成为简单的数据库编程2.数据库编程中引入model/view编程模型 基于model/view数据库编程: qt提供model类: Q ...