部分内容from: Tensorflow C++ 从训练到部署(1):环境搭建

在之前的编译中,已经编译好了tensorflow_pkg相关的wheel。现在有一个需求,需要按照C++的代码进行模型加载和训练。查询资料后发现,需要重新编译一套TensorFlow支持的C++接口,主要是编译出来libtensorflow_cc.so和libtensorflow_framework.so这两个文件。

bazel build -c opt --copt=-mavx --copt=-msse4.2 --config=monolithic //tensorflow:libtensorflow_cc.so
bazel build -c opt --copt=-mavx --copt=-msse4.2 --config=monolithic //tensorflow:libtensorflow_framework.so

像这种严格与机器相关的选项,虽然可以加快执行速度,但是在使用之前一定要查明自己的目标机器是否适合。

中间可能会遇到之前的一些问题,功查找https://www.cnblogs.com/jourluohua/p/9180709.html

编译完成后,安装第三方库

source tensorflow/contrib/makefile/build_all_linux.sh
若出现 /autogen.sh: 4: autoreconf: not found 错误,安装 sudo apt-get install autoconf automake libtool
安装头文件和lib文件(不安装也可以,主要是要在CMakeLists文件中配置好就可以)
sudo cp -r bazel-genfiles/ /usr/local/include/tf
sudo cp -r tensorflow/cc /usr/local/include/tf/tensorflow
sudo cp -r tensorflow/core /usr/local/include/tf/tensorflow
sudo cp -r third_party /usr/local/include/tf
sudo cp bazel-bin/tensorflow/libtensorflow_cc.so /usr/local/lib
sudo cp bazel-bin/tensorflow/libtensorflow_framework.so /usr/local/lib

如果你使用的是C的接口,用的是libtensorflow.so库的话,需要拷贝tensorflow/c/相关的文件

之后是新建一个Python文件,去生成相关的pb文件(代码来源于他人代码,有修改)

#!/usr/bin/env python

import tensorflow.compat.v1 as tf
import numpy as np with tf.Session() as sess: a=tf.placeholder(tf.float32,shape=None, name='a')
b=tf.placeholder(tf.float32,shape=None, name='b')
c = tf.multiply(a, b, name='c') sess.run(tf.global_variables_initializer()) tf.train.write_graph(sess.graph_def, 'model/', 'simple.pb', as_text=False) res = sess.run(c, feed_dict={'a:0': 2.0, 'b:0': 3.0})
print("res = ", res)

生成了model/simple.pb文件

写load_simple_net.cpp文件(代码来源于他人代码,有修改https://gitee.com/liuzc/tensorflow_cpp.git)

#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::cerr << status.ToString() << std::endl;
return ;
} else {
std::cout << "Session created successfully" << std::endl;
} if (argc != )
{
std::cerr << std::endl << "Usage: ./project path_to_graph.pb" << std::endl;
return ;
} // Load the protobuf graph
GraphDef graph_def;
std::string graph_path = argv[];
status = ReadBinaryProto(Env::Default(), graph_path, &graph_def);
if (!status.ok()) {
std::cerr << status.ToString() << std::endl;
return ;
} else {
std::cout << "Load graph protobuf successfully" << std::endl;
} // Add the graph to the session
status = session->Create(graph_def);
if (!status.ok()) {
std::cerr << status.ToString() << std::endl;
return ;
} else {
std::cout << "Add graph to session successfully" << std::endl;
} // 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>()() = 2.0; Tensor b(DT_FLOAT, TensorShape());
b.scalar<float>()() = 3.0; std::vector<std::pair<string, tensorflow::Tensor>> inputs = {
{ "a:0", a },
{ "b:0", b },
}; // The session will initialize the outputs
std::vector<tensorflow::Tensor> outputs; // Run the session, evaluating our "c" operation from the graph
status = session->Run(inputs, {"c:0"}, {}, &outputs);
if (!status.ok()) {
std::cerr << status.ToString() << std::endl;
return ;
} else {
std::cout << "Run session successfully" << std::endl;
} // Grab the first output (we only evaluated one graph node: "c")
// and convert the node to a scalar representation.
auto output_c = outputs[].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[].DebugString() << std::endl; // Tensor<type: float shape: [] values: 30>
std::cout << "Output value: " << output_c() << std::endl; // 30 // Free any resources used by the session
session->Close(); return ;
}

添加CMakeLists文件,目录结构变为

添加eigen库,这里的原因是TensorFlow默认的eigen库,里边实际上是不支持C++接口的,不信的人可以试下,里边的unsupported/CXX/Tensor里边自己include了自己,会导致递归死循环包含错误,因此需要自己添加eigen库,拷贝到当前目录eigen3文件夹下

修改CMakeLists文件,内容为

cmake_minimum_required(VERSION 3.5)
project(tensorflow_cpp) set(CMAKE_CXX_STANDARD ) find_package(OpenCV 3.0 QUIET)
if(NOT OpenCV_FOUND)
find_package(OpenCV 2.4. QUIET)
if(NOT OpenCV_FOUND)
message(FATAL_ERROR "OpenCV > 2.4.3 not found.")
endif()
endif() set(TENSORFLOW_INCLUDES
/usr/local/include/tf/
/usr/local/include/tf/bazel-genfiles
/usr/local/include/tf/tensorflow/
/usr/local/include/tf/tensorflow/third-party
) set(TENSORFLOW_LIBS
/usr/local/lib/libtensorflow_cc.so
/usr/local/lib/libtensorflow_framework.so
) include_directories(
${TENSORFLOW_INCLUDES}
${PROJECT_SOURCE_DIR}/eigen3
) add_executable(load_simple_net load_simple_net.cpp)
target_link_libraries(load_simple_net
${TENSORFLOW_LIBS}
${OpenCV_LIBS}
)

新建build文件,进入该build文件中

cd ./build
cmake ..
make

这里有一个非常重要的点,/usr/local/lib/libtensorflow_cc.so /usr/local/lib/libtensorflow_framework.so的顺序关系,如果顺序不对,会一直报

E tensorflow/core/common_runtime/session.cc:89] Not found: No session factory registered for the given session options: {target: "" config: } Registered factories are {}.

使用./load_simple_net  ../model/simple.pb,按道理可以得到正确的值

Session created successfully
Load graph protobuf successfully
Add graph to session successfully
Run session successfully
Tensor<type: float shape: [] values: >
Output value:

参考资料:

https://medium.com/jim-fleming/loading-tensorflow-graphs-via-host-languages-be10fd81876f

https://medium.com/jim-fleming/loading-a-tensorflow-graph-with-the-c-api-4caaff88463f#.z4qeoyfb0

https://www.tensorflow.org/install/install_c

http://www.liuxiao.org/2018/08/ubuntu-tensorflow-c-%e4%bb%8e%e8%ae%ad%e7%bb%83%e5%88%b0%e9%a2%84%e6%b5%8b1%ef%bc%9a%e7%8e%af%e5%a2%83%e6%90%ad%e5%bb%ba/

https://blog.csdn.net/melissa_cjt/article/details/85983659

https://www.cnblogs.com/shouhuxianjian/p/9416934.html

TensorFlow C++接口编译和使用的更多相关文章

  1. ubuntu14 编译tensorflow C++ 接口

    tensorflow1.11 bazel 0.15.2 protobuf 3.6.0 eigen 3.3.5 wget -t 0 -c https://github.com/eigenteam/eig ...

  2. caffe 在window下编译(windows7, cuda8.0,matlab接口编译)

    1. 环境:Windows7,Cuda8.0,显卡GTX1080,Matlab2016a,VS2013 (ps:老板说服务器要装windows系统,没办法,又要折腾一番,在VS下编译好像在cuda8. ...

  3. tensorflow 源码编译tensorflow 1.1.0到 tensorflow 2.0,ver:1.1.0rc1、1.4.0rc1、1.14.0-rc1、2.0.0b1

    目录 tensorflow-build table 更多详细过程信息及下载: tensorflow-build tensorflow 源码编译,提升硬件加速,支持cpu加速指令,suport SSE4 ...

  4. tensorflow c++接口的编译安装与一些问题记录

    参考这篇文章安装,依次安装bazel,protocbuf,eigen3,然后下载tensorflow源码,编译c++ api,将编译结果拷贝到搜索路径 最后测试案例时遇到一些问题 (1)fatal e ...

  5. win10编译tensorflow C++接口

    ​原文地址:https://www.bearoom.xyz/2018/08/28/win10-build-tf-cc/ 首先,我觉得这是一个比较DT的活,因为,tensorflow支持最好的编程语言应 ...

  6. 机器学习caffe环境搭建——redhat7.1和caffe的python接口编译

    相信看这篇文章的都知道caffe是干嘛的了,无非就是深度学习.神经网络.计算机视觉.人工智能这些,这个我就不多介绍了,下面说说我的安装过程即遇到的问题,当然还有解决方法. 说下我的环境:1>虚拟 ...

  7. caffe在windows 下的配置及matlab接口编译(无GPU)

    本人机子windows 10,matlab2015a,vs2013(官网使用的是vs2013) 1.首先去github上下载caffe的windows包,地址:https://github.com/B ...

  8. caffe matlab接口编译遇到的问题记录

    今天编译的过程中遇到的问题以及查阅到的资料,记录在这里,希望可以帮到其他人. BVLC的caffe源码,如果要编译matlab的接口时,首先需要将makefile.config文件中的matlab的安 ...

  9. 使用SSD目标检测c++接口编译问题解决记录

    本来SSD做测试的Python接口用起来也是比较方便的,但是如果部署集成的话,肯定要用c++环境,于是动手鼓捣了一下. 编译用的cmake,写的CMakeList.txt,期间碰到一些小问题,简单记录 ...

随机推荐

  1. microsoft 官方学习资源

    https://devblogs.microsoft.com/dotnet/  :_NET Blog https://docs.microsoft.com/zh-cn/learn/ :Microsof ...

  2. gateway启动报错:org.springframework.cloud.gateway.config.GatewayAutoConfiguration required a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' that could not be found

    将pom.xml中关于spring-boot-start-web模块的jar依赖去掉. 错误分析: 根据上面描述(Description)中信息了解到GatewayAutoConfiguration这 ...

  3. 当微信小程序遇到AR(二)

    当微信小程序遇到AR,会擦出怎么样的火花?期待与激动...... 通过该教程,可以从基础开始打造一个微信小程序的AR框架,所有代码开源,提供大家学习. 本课程需要一定的基础:微信开发者工具,JavaS ...

  4. java中如何在键盘中输入一串数字然后存入数组中?

    import java.util.Scanner; public class Tset { public static void main(String[] args) { System.out.pr ...

  5. 用Python给你的代码上个进度条吧 | 【代码也要面子的】

    微信公众号:AI算法与图像处理如果你觉得对你有帮助,欢迎关注.转发以及点赞哦-( ̄▽ ̄-)~ 前言 最近在跑一些代码的时候,很烦...因为有时候不知道这段程序什么时候能执行完,现在执行哪里了,如果报错 ...

  6. Centos7服务器环境搭建

    1.Apache安装 yum install httpd systemctl start httpd.service #启动 systemctl stop httpd.service#停止 syste ...

  7. NDK学习笔记-文件的拆分与合并

    文件的拆分与合并在开发中经常会用到,上传或是下载的时候都有这样的运用 文件拆分的思路 将文件大小拆分为n个文件 那么,每个文件的大小就是等大小的 如果文件大小被n除不尽,那么就使用n+1个文件来拆分 ...

  8. jquery防止快速点击

    jquery防止快速点击(推荐第三种方式) //全站ajax加载提示 (function ($) { var str = '<div class="ajax-status" ...

  9. 第35课.函数对象分析("()"重载)

    1.编写一个函数 a.函数可以获得斐波那契数列 b.每调一次返回一个值 c.函数可以根据需要重复使用 2.函数数对象 a.使用具体的类对象取代函数 b.改类的对象具备函数调用的行为 c.构造函数指具体 ...

  10. 解决java.lang.SecurityException: Invalid signature file digest for Manifest main attributes

    解决java.lang.SecurityException: Invalid signature file digest for Manifest main attributes 当项目依赖其他jar ...