tensorflow学习笔记2:c++程序静态链接tensorflow库加载模型文件
首先需要搞定tensorflow c++库,搜了一遍没有找到现成的包,于是下载tensorflow的源码开始编译;
tensorflow的contrib中有一个makefile项目,极大的简化的接下来的工作;
按照tensorflow makefile的说明文档,开始做c++库的编译:
1. 下载依赖
在tensorflow的项目顶层运行:
tensorflow/contrib/makefile/download_dependencies.sh
东西会下载到tensorflow/contrib/makefile/downloads/目录里;
2. 在linux下进行编译
首先确保编译工具都已经装好了:
sudo apt-get install autoconf automake libtool curl make g++ unzip zlib1g-dev git python
然后运行编译脚本;
注意:运行之前打开看一眼,第一步竟然是把tensorflow/contrib/makefile/downloads/目录里的东西清空然后重新下载。。。注掉注掉
tensorflow/contrib/makefile/build_all_linux.sh
然后在tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a就看到静态库了;
3. 准备好加载模型的c++代码
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/platform/env.h" using namespace tensorflow; int main(int argc, char* argv[]) {
// Initialize a tensorflow session
Session* session;
Status status = NewSession(SessionOptions(), &session);
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return 1;
} // Read in the protobuf graph we exported
// (The path seems to be relative to the cwd. Keep this in mind
// when using `bazel run` since the cwd isn't where you call
// `bazel run` but from inside a temp folder.)
GraphDef graph_def;
status = ReadBinaryProto(Env::Default(), "models/test_graph.pb", &graph_def);
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return 1;
} // Add the graph to the session
status = session->Create(graph_def);
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return 1;
} // Setup inputs and outputs: // Our graph doesn't require any inputs, since it specifies default values,
// but we'll change an input to demonstrate.
Tensor a(DT_FLOAT, TensorShape());
a.scalar<float>()() = 3.0; Tensor b(DT_FLOAT, TensorShape());
b.scalar<float>()() = 2.0; Tensor x(DT_FLOAT,TensorShape());
x.scalar<float>()() = 10.0; std::vector<std::pair<string, tensorflow::Tensor>> inputs = {
{ "a", a },
{ "b", b },
{ "x", x },
}; // The session will initialize the outputs
std::vector<tensorflow::Tensor> outputs; // Run the session, evaluating our "y" operation from the graph
status = session->Run(inputs, {"y"}, {}, &outputs);
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return 1;
} // Grab the first output (we only evaluated one graph node: "c")
// and convert the node to a scalar representation.
auto output_y = outputs[0].scalar<float>(); // (There are similar methods for vectors and matrices here:
// https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/public/tensor.h) // Print the results
std::cout << outputs[0].DebugString() << "\n"; // Tensor<type: float shape: [] values: 32>
std::cout << output_y() << "\n"; // 32 // Free any resources used by the session
session->Close();
return 0;
}
保存成load_graph.cc;
写Makefile:
TARGET_NAME := load_graph TENSORFLOW_MAKEFILE_DIR := /mnt/data/tensorflow/tensorflow/contrib/makefile INCLUDES := \
-I /usr/local/lib/python3.6/dist-packages/tensorflow/include NSYNC_LIB := \
$(TENSORFLOW_MAKEFILE_DIR)/downloads/nsync/builds/default.linux.c++11/nsync.a PROTOBUF_LIB := \
$(TENSORFLOW_MAKEFILE_DIR)/gen/protobuf/lib/libprotobuf.a TENSORFLOW_CORE_LIB := \
-Wl,--whole-archive $(TENSORFLOW_MAKEFILE_DIR)/gen/lib/libtensorflow-core.a -Wl,--no-whole-archive LIBS := \
$(TENSORFLOW_CORE_LIB) \
$(NSYNC_LIB) \
$(PROTOBUF_LIB) \
-lpthread \
-ldl SOURCES := \
load_graph.cc $(TARGET_NAME):
g++ -std=c++11 $(SOURCES) $(INCLUDES) -o $(TARGET_NAME) $(LIBS) clean:
rm $(TARGET_NAME)
这里的tensorflow-core、nsync和protobuf全都用静态链接了,这些静态库以后考虑都放一份到系统目录下;
有几个点需要注意:
1) INCLUDE使用了python3.6的带的tensorflow头文件,只是觉得反正python都已经带头文件了,就不需要再另外拷一份头文件进系统目录了;
2) nsync库是多平台的,因而可能需要仔细分析一下nsync的编译结果所在位置,尤其如果是交叉编译的话;
3) 链接顺序不能错,tensorflow-core肯定要在其它两个前面;
4) tensorflow_core库需要全链接进来,否则会出现这个错:tensorflow/core/common_runtime/session.cc:69] Not found: No session factory registered for the given session options: {target: "" config: } Registered factories are {}.
想想也大概能知道为什么,肯定是在静态代码层面只依赖父类,然后再在运行时通过名字找子类,所以在符号层面是不直接依赖子类的,不强制whole-archive的话,子类一个都带不进来;
4. 运行程序
运行前先看看事先准备好的graph在不在预定位置,生成graph的方法见上一篇;
运行一下,没啥好说的,结果正确。
参考:
http://blog.163.com/wujiaxing009@126/blog/static/7198839920174125748893/
https://blog.csdn.net/xinchen1234/article/details/78750079
tensorflow学习笔记2:c++程序静态链接tensorflow库加载模型文件的更多相关文章
- tensorflow学习笔记(三十四):Saver(保存与加载模型)
Savertensorflow 中的 Saver 对象是用于 参数保存和恢复的.如何使用呢? 这里介绍了一些基本的用法. 官网中给出了这么一个例子: v1 = tf.Variable(..., nam ...
- VSTO学习笔记(三) 开发Office 2010 64位COM加载项
原文:VSTO学习笔记(三) 开发Office 2010 64位COM加载项 一.加载项简介 Office提供了多种用于扩展Office应用程序功能的模式,常见的有: 1.Office 自动化程序(A ...
- Android 学习笔记之Volley(八)实现网络图片的数据加载
PS:最后一篇关于Volley框架的博客... 学习内容: 1.使用ImageRequest.java实现网络图片加载 2.使用ImageLoader.java实现网络图片加载 3.使用NetWork ...
- 【JAVAWEB学习笔记】网上商城实战2:异步加载分类、Redis缓存分类和显示商品
网上商城实战2 今日任务 完成分类模块的功能 完成商品模块的功能 1.1 分类模块的功能: 1.1.1 查询分类的功能: 1.1.2 查询分类的代码实现: 1.1.2.1 创建 ...
- TensorFlow 学习笔记(1)----线性回归(linear regression)的TensorFlow实现
此系列将会每日持续更新,欢迎关注 线性回归(linear regression)的TensorFlow实现 #这里是基于python 3.7版本的TensorFlow TensorFlow是一个机器学 ...
- PHP7 学习笔记(四)PHP PSR-4 Autoloader 自动加载
参考文献: 1.PHP PSR-4 Autoloader 自动加载(中文版) 2.PHP编码规范(中文版)导读 3.PHP-PSR-[0-4]代码规范 基本步骤: (1)在vendor 下新建一个项目 ...
- WebGL学习笔记(十二):加载模型文件
目前为止,我们用到的模型顶点uv信息等,都是直接定义在代码中的,实际使用中,这些数据应该是由3D编辑器编辑好后按照一定的格式存储在文件中的,我们需要从文件中提取出对应的数据之后,组合成我们可以使用的信 ...
- WP8.1程序开发中,如何加载本地文件资源或安装在程序包中的资源。
Web 要访问来自 Web 的文件,你可以使用标准的绝对 HTTP URI: <img src="http://www.contoso.com/images/logo.png" ...
- tensorflow实战笔记(19)----使用freeze_graph.py将ckpt转为pb文件
一.作用: https://blog.csdn.net/yjl9122/article/details/78341689 这节是关于tensorflow的Freezing,字面意思是冷冻,可理解为整合 ...
随机推荐
- page1201未完成
import java.util.Scanner; /** * @author:李柏宏(LiberHome) * @date:Created in 2019/3/4 20:37 * @descript ...
- Java作业四(2017-10-8)
import java.util.Scanner; public class Helloworld { public static void main(String[] args) { System. ...
- 秒杀ecshop的前台写shell 0day
ECSHOP号称最大的开源网店系统,官方是这样介绍它的:“ECShop网店系统是一套免费开源的网上商店软件,无论在稳定性.代码优化.运行效率.负载能力.安全等级.功能可操控性和权限严密性等方面都居国内 ...
- 2018-2019-2 20165311《网络对抗技术》Exp5 MSF基础应用
<网络对抗技术>Exp5 MSF基础应用 实验目的 实验内容 一个主动攻击实践(ms08_067) 一个针对浏览器的攻击(ms11_050) 一个针对客户端的攻击(adobe_toolbu ...
- java第二次作业之一
package dama; public class person { private String name; private String sex; private int age; privat ...
- 2018-2019-2 网络对抗技术 20165336 Exp1 PC平台逆向破解
2018-2019-2 网络对抗技术 20165336 Exp1 PC平台逆向破解 1. 逆向及Bof基础实践说明 1.1 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件.该程序正常 ...
- cnblogs
想注册个博客园来着的,看着大佬们的博客都十分漂亮,但是发现我因为太菜没有办法搞定美化问题. 以后再说吧 写写东西,反正也没人看,但是写的时候尽量按给别人看的格式写吧 2019.3.15 开通博客 计划 ...
- VisualStudioCode中用dotnet命令创建多个ASP.NET Core 项目、类库、控制台程序,并添加应用间的引用
一.准备工作 首先安装VisualStudioCode并且可以使用. 1.首先新创建空的MyApps文件夹,作为项目主目录,下面将在这个文件夹中创建多个web应用程序.类型.控制台程序等. 2.打开V ...
- python练习题-day23
1.人狗大战(组合) class Person: def __init__(self,name,hp,aggr,sex,money): self.name=name self.hp=hp self.a ...
- UISplitViewController使用
分割控制器UISplitViewController <1>功能:它也是ipad的一个新特性,在屏幕上可以同时显示两个控制器,左边一个,右边一个:左边的为主控制器,右边的为详细控制器,主控 ...