TensorFlow系统架构
设计理念
图的定义和图的运行完全分开。
TensorFlow为“符号主义”的库。
编程模式通常分为命令式编程和符号式编程。
命令式编程:编写通常意义上的程序,容易理解和调试,按照原有的逻辑执行。
符号式编程:涉及很多的嵌入式和优化,不同意理解和调试,运行速度相对提升。
符号式计算:先定义各种变量,然后建立一个数据流图,在数据流图中规定各个变量间的计算关系,最后对数据流图进行编译,此时的数据流图还是空壳,里面的没有任何实际数据,把需要的运算的输入放进去,在模型中形成数据流,形成输出值。
TensorFlow中涉及的运算都要放在图中,图的运行只发生在会话中,开启会话后,就可以用数据填充节点,进行运算;关闭会话后,就不能计算。
会话提供了操作运行和tensor求值的环境。
案例:
import tensorflow as tf
# 创建图
a = tf.constant([1.0,2.0])
b = tf.constant([3.0,4.0])
c = a + b
# 创建会话
sess = tf.Session()
# 计算 c
print sess.run(c)
sess.close()
编程模型
TensorFlow的数据流图是由节点和边组成的有向无环图(DAG)。
TensorFlow有tensor和flow组成,tensor(张量)代表数据流图中的边,flow(流)代表数据流图中节点所做的操作。
边:
TensorFlow的边有两种连接关系:数据依赖(实线边,张量)和控制依赖(虚线边)
张量的数据属性:
数据类型 | Python 类型 | 描述 |
DT_FLOAT | tf.float32 | 32 位浮点数. |
DT_DOUBLE | tf.float64 | 64 位浮点数. |
DT_INT64 | tf.int64 | 64 位有符号整型. |
DT_INT32 | tf.int32 | 32 位有符号整型. |
DT_INT16 | tf.int16 | 16 位有符号整型. |
DT_INT8 | tf.int8 | 8 位有符号整型. |
DT_UINT8 | tf.uint8 | 8 位无符号整型. |
DT_STRING | tf.string | 可变长度的字节数组.每一个张量元素都是一个字节数组. |
DT_BOOL | tf.bool | 布尔型. |
DT_COMPLEX64 | tf.complex64 | 由两个32位浮点数组成的复数:实数和虚数. |
DT_QINT32 | tf.qint32 | 用于量化Ops的32位有符号整型. |
DT_QINT8 | tf.qint8 | 用于量化Ops的8位有符号整型. |
DT_QUINT8 | tf.quint8 | 用于量化Ops的8位无符号整型. |
节点(算子):
节点代表一个操作,一般用来表示施加的数学运算,也可以表示数据输入的起点以及输出的终点。
TensorFlow实现的算子:
运算类型 | 运算示例 |
标量运算 | add、sub、mul、div、exp、log、greater、less、equal |
向量运算 | concat、slice、split、constant、rank、shape、shuffle |
矩阵运算 | matmul、matricinverse、matrixdeterminant |
带状态的运算 | variable、assign、assignadd |
神经网络组件 | softmax、sigmoid、relu、convolution2D、maxpooling |
储存,恢复 | save、restore |
队列及同步运算 | enqueue、dequeue、mutexAcquire、mutexrelease |
控制流 | merge、switch、enter、leave、nextInteration |
图:
图为有向无环图,是操作任务的描述。
会话:
创建一个会话能执行图,创建会话时创建一张空图,在会话汇总添加节点和边,形成一张图,最后执行图。
调用Session对象的run方法来执行图时,传入一些tensor,这个过程叫填充。
返回的结果类型根据输入的类型而定,这个过程叫取回。
一个会话可以有多个图,会话可以修改图的结构,也可以往图中注入数据进行计算。
会话主要有两个接口:Extend(在图中添加节点和边)和Run(执行图)
设备:
一块可以用来运算并且拥有自己的地址空间的硬件,如cpu,gpu
变量:
一种特殊的数据,在图中有固定的位置,不像普通张量一样流动。
创建变量张量使用tf.Variable函数,需要给定一个初始值,初始值的形状和类型决定这个变量的形状和类型。
TensorFlow提供填充机制,构建图时使用tf.placeholder()临时代替任意操作的张量,调用结束后填充数据消失。
内核:
操作是对抽象操作的统称。
内核是能够运行在特定设备上的一种对操作的实现,同一个操作可以对应多个内核。