前言
本节主要介绍(一)中的代码,了解如何使用C++创建图和tensor,并使用它们进行计算。
代码
// tensorflow/cc/example/example.cc
#include "tensorflow/cc/client/client_session.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/tensor.h"
int main() {
using namespace tensorflow;
using namespace tensorflow::ops;
Scope root = Scope::NewRootScope();
// Matrix A = [3 2; -1 0]
auto A = Const(root, { {3.f, 2.f}, {-1.f, 0.f}});
// Vector b = [3 5]
auto b = Const(root, { {3.f, 5.f}});
// v = Ab^T
auto v = MatMul(root.WithOpName("v"), A, b, MatMul::TransposeB(true));
std::vector<Tensor> outputs;
ClientSession session(root);
// Run and fetch v
TF_CHECK_OK(session.Run({v}, &outputs));
// Expect outputs[0] == [19; -3]
std::cout<< outputs[0].matrix<float>();
return 0;
}
Scope
tensorflow::Scope 结构是用来维护图的当前状态的主要数据结构。Scope就像一个指针一样,同时这个结构里面也维护了一些tensorflow的操作。Scope对象也是众多操作构造函数的第一个参数,这些以scope对象作为构造函数的第一个参数的操作会拥有这个scope对象的各种属性。另外,同一个scope对象也可以用于不同的图。
使用Scope::NewRootScope,来生成一个新的scope.
Scope root = Scope::NewRootScope();
生成scope的同时也生成一个tensorflow::Status对象,这个对象主要用来维护执行操作期间的错误信息。
由NewRootScope生成的Scope对象叫做根root Scope。子Scope可以通过根scope的一些成员函数来创建,他们具有继承关系。子scope继承父结点的所有属性,同时一般会有自已的不同父结点的属性。
scope维护的属性有:
· 操作名 operation names
· 操作的控制依赖
· 给某个操作的设备分配
· 给某个操作的内核属性
Operation Construtors
在C++里面,每个Tensorflow操作都对应一个类,因此是通过类的构造函数来为图加上操作。
如:
MatMul m(scope,a,b);
声明了一种矩阵乘法的操作m.第一个参数是scope对象,后面为输入tensor及一些属性。
不过官方推荐的作法是:
auto m=MatMul(scope,a,b);
操作属性的一般引用方法为:操作名::属性名
如:
//单个属性
auto m =MatMul(scope,a,b,MatMul::TransposeA(true));
//多个属性
auto m =MatMul(scope,a,b,MatMul::Attrs().TransposeA(true).TranposeB(true));
常量
可以使用Const函数来创建Tensorflow的常量
标量
auto f =Const(scope,43.0);
auto s =Const(scope,"hello world");
生成常量tensor
//2*2 矩阵
auto m =Const(scope,{{1,2},{2,4}};
//生成 1x3x1的tensor
auto t =Const(scope,{{{1},{2},{3}}});
图的执行
与python类似,图的执行也需要在session里面进行。
C++ API提供了一个tensorflow::ClientSession类来创建一个session.然后调用ClientSession的Run函数来执行实际的计算。
其构造函数需要传入scope对象。
std::vector<Tensor> outputs;
上一句则是一个流执行的返回值,是一个Tensor的vector
auto v = MatMul(root.WithOpName("v"), A, b, MatMul::TransposeB(true));
TF_CHECK_OK(session.Run({v}, &outputs));
// Expect outputs[0] == [19; -3]
std::cout<< outputs[0].matrix<float>();
图的执行为:session.Run({操作},&输出);
最后打印中,outputs[0]则是第一个返回值,打印出来即可。