Tensorflow是一个通过计算图的形式表述计算的编程系统.计算图中包含张量(tensor)和运算(operation),张量
即为Tensorflow的数据结构,运算
为Tensorflow的计算方式.图结构包含节点(node)和边缘(edge),节点表示运算(operation),边表示张量(tensor).
1 图(Graph)
Tensorflow程序会自动维护一个默认的图,对图中的变量进行计算.通过tf.get_default_graph
获取当前默认的计算图.可通过tf.Graph
生成新的计算图,不同计算图的张量和运算不会共享.
1.0 使用默认图
- Demo
import tensorflow as tf
tf.reset_default_graph()
# 节点即运算
# 新建节点(node),将值(250)添加到图中,得到张量(tensor)
# 使用name自定义名称
v1 = tf.constant(250, name="v_1")
# 系统自动分配name
v2 = tf.constant(250)
# 将运算(op)和张量(tensor)添加到默认图中,得到新的运算(op)
total = v1 + v2
# 新建操作(op),使用Variable封装,可操作对应的张量
v3 = tf.Variable(tf.constant(250), name="v_3")
print("variable 1 : {}".format(v1))
print("variable 2 : {}".format(total))
print("variable 3 : {}".format(v3))
- Result
variable 1 : Tensor("v_1:0", shape=(), dtype=int32)
variable 2 : Tensor("add:0", shape=(), dtype=int32)
variable 3 : <tf.Variable 'v_3:0' shape=() dtype=int32_ref>
- Analysis
(1) 使用Tensorflow
默认图进行节点和边的定义;
(2)tf.consant
直接新建节点,并将节点存入图结构中,返回张量;
(3)tf.Variable
将节点封装,存入图中,返回张量;
1.2 新建图
- Demo
import tensorflow as tf
tf.reset_default_graph()
g = tf.Graph()
with g.as_default():
# 节点即运算
# 新建节点(node),将值添加到图中,得到张量(tensor)
# 使用name自定义名称
v1 = tf.constant(250, name="v_1")
v2 = tf.constant(250, name="v_2")
# 系统自动分配name
v3 = tf.constant(250)
# 将运算(op)和张量(tensor)添加到默认图中,得到新的运算(op)
total = v1 + v2
# 新建操作(op),使用Variable封装,可操作对应的张量
# 使用name自定义名称
v4 = tf.Variable(tf.constant(250), name="v_4")
# 使用系统分配name
v5 = tf.Variable(tf.constant(250))
print("variable 1 : {}".format(v1))
print("variable 2 : {}".format(total))
print("variable 3 : {}".format(v3))
print("variable 4 : {}".format(v4))
print("variable 5 : {}".format(v5))
- Result
variable 1 : Tensor("v_1:0", shape=(), dtype=int32)
variable 2 : Tensor("add:0", shape=(), dtype=int32)
variable 3 : Tensor("Const:0", shape=(), dtype=int32)
variable 4 : <tf.Variable 'v_4:0' shape=() dtype=int32_ref>
variable 5 : <tf.Variable 'Variable:0' shape=() dtype=int32_ref>
- Analysis
(1) 利用tf.Graph
自定义图,在图中定义节点和边;
(2)tf.Graph
构建一个命名空间,为每个节点指定一个唯一的名称,如v_1:0
,其中,v_1
为设定的name
,若不指定name则系统自动分配,如Const:0
,Variable:0
,命名格式:OP_Name:i
,其中OP_NAME为生成该张量的操作名称,如Const,Variable,i为索引的,是一个整数;
(3) 将自定义的图作为默认图g.as_default
,其他同1.0节;
1.3 获取默认图
- Demo
import tensorflow as tf
import numpy as np
tf.reset_default_graph()
g = tf.Graph()
with g.as_default():
v1 = tf.placeholder(tf.int32, shape=[1], name="v_1")
v2 = tf.placeholder(tf.int32, shape=[1], name="v_1")
# 查看张量所属的计算图
print("graph address: {}".format(v1.graph))
# 获取当前默认图
print("graph : {}".format(v1.graph is tf.get_default_graph()))
- Result
graph address: <tensorflow.python.framework.ops.Graph object at 0x7fa78c6747b8>
graph : True
- Analysis
(1) 张量通过属性graph
可查看所属的计算图;
(2) 通过tf.get_default_graph
方法获取当前计算图;
2 张量(Tensor)
张量是Tensorflow
的核心数据单位,一个张量由一组形成阵列(任意维度)的原始值组成,张量的阶
是其维数,形状是一个整数元组.
- Demo
import tensorflow as tf
import numpy as np
tf.reset_default_graph()
v1 = tf.Variable(np.random.rand(2, 3))
print("variable 1: {}".format(v1))
- Result
variable 1: <tf.Variable 'Variable:0' shape=(2, 3) dtype=float64_ref>
- Analysis
(1) 默认图新建节点,返回Tensor,Tensor的shape即形状为元组(2, 3),维数为2行3列,即变量的阶;
(2) Tensorflow中的值可以使用外部的模块产生值,存入图中,如numpy;
3 会话(Session)
tf.Session在Tensorflow中表示客户端程序,即实现访问本地设备和分布式Tensorflow运行时的设备,也可用于缓存tf.Graph
的信息,完成图结构的计算.
3.1 默认会话
-Demo
import tensorflow as tf
tf.reset_default_graph()
# 节点即运算
# 新建节点(node),将值添加到图中,得到张量(tensor)
v1 = tf.constant(250, name="v_1")
v2 = tf.constant(250, name="v_2")
# 将运算(op)和张量(tensor)添加到默认图中,得到新的运算(op)
total = v1 + v2
# 新建操作(op),使用Variable封装,可操作对应的张量
v3 = tf.Variable(tf.constant(250), name="v_3")
print("variable 1 : {}".format(v1))
print("total : {}".format(total))
with tf.Session() as sess:
print("variable 1: {}".format(sess.run(v1)))
print("total: {}".format(sess.run(total)))
- Result
variable 1 : Tensor("v_1:0", shape=(), dtype=int32)
total : Tensor("add:0", shape=(), dtype=int32)
variable 1: 250
total: 500
- Analysis
(1) 默认会话,默认图,会话使用with
结构,调用结束会自动关闭;
(2) 会话方法run
用于运行节点或评估张量,可向sess.run
传递多个节点或张量;
(3) 使用sess.run
即可获取张量或节点的值,如250和500;
3.2 自定义图结构使用会话
- Demo
import tensorflow as tf
tf.reset_default_graph()
g = tf.Graph()
with g.as_default():
# 节点即运算
# 新建节点(node),将值添加到图中,得到张量(tensor)
# 使用name自定义名称
v1 = tf.constant(250, shape=[1], name="v_1")
v2 = tf.constant(250, name="v_2")
# 系统自动分配name
v3 = tf.constant(250)
# 将运算(op)和张量(tensor)添加到默认图中,得到新的运算(op)
total = v1 + v2
# 新建操作(op),使用Variable封装,可操作对应的张量
# 使用name自定义名称
v4 = tf.Variable(tf.constant(250), name="v_4")
# 使用系统分配name
v5 = tf.Variable(tf.constant(250))
print("variable 1 : {}".format(v1))
print("total : {}".format(total))
# 使用新建图
with tf.Session(graph=g) as sess:
print("variable 1: {}".format(sess.run(v1)))
print("total: {}".format(sess.run(total)))
- Result
variable 1 : Tensor("v_1:0", shape=(1,), dtype=int32)
total : Tensor("add:0", shape=(1,), dtype=int32)
variable 1: [250]
total: [500]
- Analysis
(1) 自定义图,会话在新建图中运行,会话使用with
结构,调用结束会自动关闭;
(2) 会话方法run
用于运行节点或评估张量,可向sess.run
传递多个节点或张量;
(3) 使用sess.run
即可获取张量或节点的值,如[250]和[500];
3.3 会话使用dict数据
- Demo
import tensorflow as tf
import numpy as np
tf.reset_default_graph()
g = tf.Graph()
with g.as_default():
v1 = tf.placeholder(tf.int32, shape=[1], name="v_1")
v2 = tf.placeholder(tf.int32, shape=[1], name="v_1")
total = v1 + v2
with tf.Session() as sess:
a = [125]
b = [125]
total = sess.run(total, feed_dict={v1: a, v2: b})
print("total : {}".format(total))
- Result
total : [250]
- Analysis
(1)tf.Session
的run
方法可接受dict
形式的数据,通过placeholder
占位符获取传输的数据;
(2) 传入数据的形状与placeholder数据形状保持一致;
4 设备(device)
tf.device是Tensorflow
进行指定分布式计算设备的工具,通过该函数分配计算的设备.
tf.device("/job:<JOB_NAME>/task:<TASK_INDEX>/device:<DEVICE_TYPE>:<DEVICE_INDEX>")
序号 | 参数 | 描述 |
---|---|---|
1 | JOB_NAME | 字母数字字符串,不以数字开头 |
2 | DEVICE_TYPE | 注册设备类型,如GPU或CPU |
3 | TASK_INDEX | 非负整数,表明JOB_NAME作业中的任务索引 |
4 | DEVICE_INDEX | 非负整数,表示设备索引 |
4.1 获取运算分配情况
- Demo
import tensorflow as tf
import numpy as np
# 设置打印系统设备信息log_device_placement=True
# 设置GPU与CPU自动切换,即不能使用GPU的计算会自动迁移到CPU上计算
config = tf.ConfigProto(log_device_placement=True, allow_soft_placement=True)
v1 = tf.constant(250, shape=[1], name="v_1")
v2 = tf.constant(250, name="v_2")
# 系统自动分配name
v3 = tf.constant(250)
# 将运算(op)和张量(tensor)添加到默认图中,得到新的运算(op)
total = v1 + v2
with tf.Session(config=config) as sess:
print("total: {}".format(sess.run(total)))
print(config)
- Result
2019-02-21 11:15:21.615593: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
Device mapping:
/job:localhost/replica:0/task:0/device:XLA_CPU:0 -> device: XLA_CPU device
2019-02-21 11:15:21.618821: I tensorflow/core/common_runtime/direct_session.cc:307] Device mapping:
/job:localhost/replica:0/task:0/device:XLA_CPU:0 -> device: XLA_CPU device
add: (Add): /job:localhost/replica:0/task:0/device:CPU:0
2019-02-21 11:15:21.619969: I tensorflow/core/common_runtime/placer.cc:927] add: (Add)/job:localhost/replica:0/task:0/device:CPU:0
v_1: (Const): /job:localhost/replica:0/task:0/device:CPU:0
2019-02-21 11:15:21.619996: I tensorflow/core/common_runtime/placer.cc:927] v_1: (Const)/job:localhost/replica:0/task:0/device:CPU:0
v_2: (Const): /job:localhost/replica:0/task:0/device:CPU:0
2019-02-21 11:15:21.620004: I tensorflow/core/common_runtime/placer.cc:927] v_2: (Const)/job:localhost/replica:0/task:0/device:CPU:0
Const: (Const): /job:localhost/replica:0/task:0/device:CPU:0
2019-02-21 11:15:21.620011: I tensorflow/core/common_runtime/placer.cc:927] Const: (Const)/job:localhost/replica:0/task:0/device:CPU:0
total: [500]
log_device_placement: true
- Analysis
(1) 系统设备信息:XLA_CPU:0
即系统只有一个CPU;
(2)add: (Add): /job:localhost/replica:0/task:0/device:CPU:0
将add操作分配在CPU:0上;
(3) 通过设定allow_soft_placement
自动切换GPU与CPU的调度;
4.1 指定计算设备
- Demo
import tensorflow as tf
# 获取计算所在设备信息
config = tf.ConfigProto(log_device_placement=True)
# 指定计算设备
with tf.device("/device:CPU:0"):
v1 = tf.constant([125], shape=[1], name="v_1")
v2 = tf.constant([125], shape=[1], name="v_2")
total = v1 + v2
with tf.Session(config=config) as sess:
print("total: {}".format(sess.run(total)))
- Result
2019-02-21 17:55:28.521380: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
Device mapping:
/job:localhost/replica:0/task:0/device:XLA_CPU:0 -> device: XLA_CPU device
2019-02-21 17:55:28.524281: I tensorflow/core/common_runtime/direct_session.cc:307] Device mapping:
/job:localhost/replica:0/task:0/device:XLA_CPU:0 -> device: XLA_CPU device
add: (Add): /job:localhost/replica:0/task:0/device:CPU:0
2019-02-21 17:55:28.525161: I tensorflow/core/common_runtime/placer.cc:927] add: (Add)/job:localhost/replica:0/task:0/device:CPU:0
v_1: (Const): /job:localhost/replica:0/task:0/device:CPU:0
2019-02-21 17:55:28.525175: I tensorflow/core/common_runtime/placer.cc:927] v_1: (Const)/job:localhost/replica:0/task:0/device:CPU:0
v_2: (Const): /job:localhost/replica:0/task:0/device:CPU:0
2019-02-21 17:55:28.525183: I tensorflow/core/common_runtime/placer.cc:927] v_2: (Const)/job:localhost/replica:0/task:0/device:CPU:0
total: [250]
- Analysis
(1) 通过tf.device
设定计算的设备;
(2) 可通过指定设备进行计算,这也是合理利用计算机资源和实现并行,提高计算速度的方法.
[参考文献]
[1]https://www.tensorflow.org/guide/low_level_intro
[2]https://www.tensorflow.org/guide/graphs
[3]https://github.com/tensorflow/tensorflow/blob/r1.12/tensorflow/core/protobuf/config.proto