在 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 版本可以自己根据情况调整。
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 预训练好的模型—— 直接调用 C++ 接口实现
现在的深度学习框架一般都是基于 Python 来实现,构建.训练.保存和调用模型都可以很容易地在 Python 下完成.但有时候,我们在实际应用这些模型的时候可能需要在其他编程语言下进行,本文将通过直 ...
- TensorFlow 调用预训练好的模型—— Python 实现
1. 准备预训练好的模型 TensorFlow 预训练好的模型被保存为以下四个文件 data 文件是训练好的参数值,meta 文件是定义的神经网络图,checkpoint 文件是所有模型的保存路径,如 ...
- TensorFlow 同时调用多个预训练好的模型
在某些任务中,我们需要针对不同的情况训练多个不同的神经网络模型,这时候,在测试阶段,我们就需要调用多个预训练好的模型分别来进行预测. 调用单个预训练好的模型请点击此处 弄明白了如何调用单个模型,其实调 ...
- 【猫狗数据集】使用预训练的resnet18模型
数据集下载地址: 链接:https://pan.baidu.com/s/1l1AnBgkAAEhh0vI5_loWKw提取码:2xq4 创建数据集:https://www.cnblogs.com/xi ...
- pytorch中如何使用预训练词向量
不涉及具体代码,只是记录一下自己的疑惑. 我们知道对于在pytorch中,我们通过构建一个词向量矩阵对象.这个时候对象矩阵是随机初始化的,然后我们的输入是单词的数值表达,也就是一些索引.那么我们会根据 ...
- 转载:tensorflow保存训练后的模型
训练完一个模型后,为了以后重复使用,通常我们需要对模型的结果进行保存.如果用Tensorflow去实现神经网络,所要保存的就是神经网络中的各项权重值.建议可以使用Saver类保存和加载模型的结果. 1 ...
- tensorflow 使用预训练好的模型的一部分参数
vars = tf.global_variables() net_var = [var for var in vars if 'bi-lstm_secondLayer' not in var.name ...
- Tensorflow 用训练好的模型预测
本节涉及点: 从命令行参数读取需要预测的数据 从文件中读取数据进行预测 从任意字符串中读取数据进行预测 一.从命令行参数读取需要预测的数据 训练神经网络是让神经网络具备可用性,真正使用神经网络时,需要 ...
- Tensorflow使用训练好的模型进行测试,发现计算速度越来越慢
实验时要对多个NN模型进行对比,依次加载直到第8个模型时,发现运行速度明显变慢而且电脑开始卡顿,查看内存占用90+%. 原因:使用过的NN模型还会保存在内存,继续加载一方面使新模型加载特别特别慢,另一 ...
随机推荐
- 安装sass遇到的坑
一.安装Sass https://www.sass.hk/install/ 根据网站的步骤进行安装 Ruby版本的选择 我第一次下载是在Ruby官网上下的2.5.0版本得ruby.然而下载了之后无(不 ...
- OCCI开发环境搭建(Ubuntu)
OCCI开放包(下载与服务器版本相同的开发包, 这用的是12.1.0.2): instantclient-basic-linux.x64-12.1.0.2.0.zip instantclient-sd ...
- 【前行】◇第3站◇ Codeforces Round #512 Div2
[第3站]Codeforces Round #512 Div2 第三题莫名卡半天……一堆细节没处理,改一个发现还有一个……然后就炸了,罚了一啪啦时间 Rating又掉了……但是没什么,比上一次好多了: ...
- CentOS6.5安装zabbix3.2.6
1.安装好httpd和php Zabbix 3需要PHP是至少5.4或更高版本 rpm -ivh http://repo.webtatic.com/yum/el6/latest.rpm yum -y ...
- linux基础指令以及权限管理
基础指令 #打印字符串 echo hello linux #将file1 和 file2粘合在一起,打印到标准输出流 cat file1 file2 标准输入输出 标准输入,stdin,即键盘.鼠标输 ...
- 转:深入理解jvm
深入理解JVM 原文链接:http://www.cubrid.org/blog/dev-platform/understanding-jvm-internals 每个使用Java的开发者都知道Java ...
- 【ospf-链路验证】
根据项目需求搭建好拓扑图 配置RT1的环回口IP和G0/0/0IP地址 开启RT1接口ospf认证,配置接口密码为H3C 配置RT1的ospf区域 同理 开启RT2接口ospf认证,配置接口密码为g0 ...
- JS高级. 06 缓存、分析解决递归斐波那契数列、jQuery缓存、沙箱、函数的四种调用方式、call和apply修改函数调用方法
缓存 cache 作用就是将一些常用的数据存储起来 提升性能 cdn //-----------------分析解决递归斐波那契数列<script> //定义一个缓存数组,存储已经计算出来 ...
- Mina 组件介绍之 IoAcceptor 与 IoConnector
在网络通信中,Socket通信的双方分为服务端与客户端,在Java NIO 的实现中采用Socket/ServerSocket, SocketChannel/ServerSocketChannel分别 ...
- java服务端项目开发规范
更新内容 2015-03-13 (请先更新svn的mybatis.xml.BaseMapper.java.Pager.java文件) 加入测试类规范 加入事物控制规范 加入mapper接口规则 ...