首先需要搞定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库加载模型文件的更多相关文章

  1. tensorflow学习笔记(三十四):Saver(保存与加载模型)

    Savertensorflow 中的 Saver 对象是用于 参数保存和恢复的.如何使用呢? 这里介绍了一些基本的用法. 官网中给出了这么一个例子: v1 = tf.Variable(..., nam ...

  2. VSTO学习笔记(三) 开发Office 2010 64位COM加载项

    原文:VSTO学习笔记(三) 开发Office 2010 64位COM加载项 一.加载项简介 Office提供了多种用于扩展Office应用程序功能的模式,常见的有: 1.Office 自动化程序(A ...

  3. Android 学习笔记之Volley(八)实现网络图片的数据加载

    PS:最后一篇关于Volley框架的博客... 学习内容: 1.使用ImageRequest.java实现网络图片加载 2.使用ImageLoader.java实现网络图片加载 3.使用NetWork ...

  4. 【JAVAWEB学习笔记】网上商城实战2:异步加载分类、Redis缓存分类和显示商品

    网上商城实战2 今日任务 完成分类模块的功能 完成商品模块的功能 1.1      分类模块的功能: 1.1.1    查询分类的功能: 1.1.2    查询分类的代码实现: 1.1.2.1  创建 ...

  5. TensorFlow 学习笔记(1)----线性回归(linear regression)的TensorFlow实现

    此系列将会每日持续更新,欢迎关注 线性回归(linear regression)的TensorFlow实现 #这里是基于python 3.7版本的TensorFlow TensorFlow是一个机器学 ...

  6. PHP7 学习笔记(四)PHP PSR-4 Autoloader 自动加载

    参考文献: 1.PHP PSR-4 Autoloader 自动加载(中文版) 2.PHP编码规范(中文版)导读 3.PHP-PSR-[0-4]代码规范 基本步骤: (1)在vendor 下新建一个项目 ...

  7. WebGL学习笔记(十二):加载模型文件

    目前为止,我们用到的模型顶点uv信息等,都是直接定义在代码中的,实际使用中,这些数据应该是由3D编辑器编辑好后按照一定的格式存储在文件中的,我们需要从文件中提取出对应的数据之后,组合成我们可以使用的信 ...

  8. WP8.1程序开发中,如何加载本地文件资源或安装在程序包中的资源。

    Web 要访问来自 Web 的文件,你可以使用标准的绝对 HTTP URI: <img src="http://www.contoso.com/images/logo.png" ...

  9. tensorflow实战笔记(19)----使用freeze_graph.py将ckpt转为pb文件

    一.作用: https://blog.csdn.net/yjl9122/article/details/78341689 这节是关于tensorflow的Freezing,字面意思是冷冻,可理解为整合 ...

随机推荐

  1. Codechef August Challenge 2018 : Safe Partition

    传送门 (虽然是A了但是不知道复杂度是不是正确的 考虑以某个位置为结尾的合法划分 先考虑min,带来的影响是限制了最小长度,预处理出这个最小长度后,这可以在处理到这个数时,把不能算的部分去掉(不满足m ...

  2. Hash算法的讲解

    散列表,又叫哈希表,它是基于快速存取的角度设计的,也是一种典型的“空间换时间”的做法.顾名思义,该数据结构可以理解为一个线性表,但是其中的元素不是紧密排列的,而是可能存在空隙. 散列表(Hash ta ...

  3. linux中安装和配置 jdk

    01.去官网下载指定的jdk 02.使用xftp把下载好的文件 传递到 linux指定文件夹中03.进入指定的文件夹输入tar -zxvf 文件名称04.发现文件 05.进入文件cd jdk1.8.0 ...

  4. ubuntu16.04中supervisor安装与简单使用(转载)

    ubuntu16.04中supervisor安装与简单使用 supervisor 进程管理是可以让进程在后台运行,而不占用控制台影响使用 1. 安装 supervisor sudo apt insta ...

  5. windows安装虚拟机(VMware)

    一.安装虚拟机 1.打开安装包 2.接受协议 3.选择安装位置 4.按照提示下一步即可 5.完成安装 二.安装带有GUI的Redhat7系统 1.选择自定义安装 2.默认虚拟机硬件兼容 3.选择稍后安 ...

  6. Selenium 3----WebDriver常用方法

    在学会定位元素的基础上,进行元素的操作. WebDriver常用方法: clear(): 清除文本. send_keys (value): 模拟按键输入. click(): 单击元素. submit( ...

  7. Spring Security Session并发控制原理解析

    当使用spring security 的标签,如下,其中<sec:session-management>对应的SessionManagementFilter.从名字可以看出,这是一个管理S ...

  8. 关于ico图标

    ico图标可以作为网页标签上显示的小logo,比如: 要获取一个网站的ico图标,只需要在url后输入/favicon.ico即可,比如   https://www.baidu.com/favicon ...

  9. 在Vuex更新,组件内的视图更新问题

    由于js的限制,vue无法进行监听数组; 当你利用索引直接设置一个项时,例如: vm.items[indexOfItem] = newValue 当你修改数组的长度时,例如: vm.items.len ...

  10. 用vue怎么写点击保存之后的返回的代码?

    点击完保存调用接口之后,如果使用  this.$router.go(-1); 返回到编辑页面,数据不会有更新,使用 this.$router.replace({ name: '信息展示', param ...