tensorflow图形检测_TensorFlow入门
一、综述:
TensorFlow是一个采用数据流图(Data FlowGraphs),用于数值计算的开源软件库。结点(Nodes)在图中表示数学操作,图中的线(Edges)则表示在节点间相互联系的多维数据数组,即张量(Tensor)。可移植性较强。
TensorFlow官方支持的模型代码库(包含学术界的最新成果,包含内容形形色色,适合初学者入门:如网络模型CNN,RNN,GAN;图形识别,语音识别,计算机视觉(对图像的分类,检测等)):
tensorflow/modelsgithub.com二、基础知识:
- Tensor
tensor(张量)是标量和向量的总称。
Tensor其实相当于一个容器,这个容器的形状我们可以随意定义。定义好的容器是空着的(相当于一个桶,里面没有任何东西)。运行TensorFlow程序的时候,这个容器当中才会拥有和之前定好的桶形状大小完全匹配的水,即数据(维度)。
先理解一下维度:
3 ###标量
[1., 2., 3.] ###一维数组或一维向量,形状为[3]
[[1., 2., 3.],[4., 5., 6.]] ###二维数组或二维向量,形状为[2,3]
[[[1., 2., 3.]],[[7., 8., 9.]]] ###三维数组或三维向量,形状为[2,1,3]
tensor(张量)就是用来容纳这些数据的,也可使用下标对容器中的数据进行索引。
tensor主要包括两个主要的属性:
dtype:存储的数据的类型,如tf.float32、tf.int32等;
shape:存储的多维数组中每个维度的数组中元素的个数,也可以理解为定义的桶(容器)的大小。
两种常用的tensor:
tf.constant:常量张量,这个tensor在TensorFlow运算的过程中始终保持不变。
tf.Variable:变量张量,这个tensor在TensorFlow运算过程中会发生变化。
举例:
import tensorflow as tf
# 创建整型常量
t0 = tf.constant(3, dtype=tf.int32)
# 创建一个浮点数的一维数组,shape=[3]
t1 = tf.constant([3., 4.1, 5.2], dtype=tf.int32)
# 创建一个字符串的2 x 2数组,shape=[2, 2]
t2 = tf.constant([['I', 'Love'], ['learning', 'TensorFlow!']], dtype=tf.string)
# 创建一个 2 x 3 x 1 数组,shape=[2, 3, 1]
t3 = tf.constant([[[5], [6], [7]], [[4], [3], [2]]],dtype=tf.int32)
# 打印上面创建的几个 Tensor
print(t0)
print(t1)
print(t2)
print(t3)
上面的代码输出结果为:
>>> print(t0)
Tensor("Const:0", shape=(), dtype=int32)
>>> print(t1)
Tensor("Const_1:0", shape=(3,), dtype=float32)
>>> print(t2)
Tensor("Const_2:0", shape=(2, 2), dtype=string)
>>> print(t3)
Tensor("Const_3:0", shape=(2, 3, 1), dtype=int32)
到此为止,是不是很诧异。为什么不是我们所想的那样输出结果:3,...,[[[5], [6], [7]], [[4], [3], [2]]]这些数值呢?因为,我们上面讲到了,tensor只是一个水桶(容器),只有TF运算的时候水桶中才会有水(数据)。
2.Dataflow Graph(数据流图)
数据流图是一种常用的并行计算编程模型,数据流图是由结点(nodes)和线(edges)构成的有向图:
结点(nodes):表示计算单元,也可以是输入的起点或输出的重点;
线(edges):表示节点与节点之间的输入和输出关系。
在TensorFlow中,每个节点都是用tf.Tensor 的实例来表示的,即每个结点的输入、输出都是Tensor,如下图中 Tensor 在 Graph 中的流动,形象的展示 TensorFlow 名字的由来。
计算图,相当于我们要盖房子之前设计的图纸,使得预先定义好的tensor根据我们的运算逻辑逐步来运行,最终根据我们定义好的目标函数,对图进行整体的优化。
TensorFlow 中的数据流图优点如下:
1. 可并行:计算结点之间有明确的连接线,系统可以很容易易的判断出哪些计算操作可以并行执行。
2. 可分发:图中的各个结点可以分布在不不同的计算单元(CPU、 GPU、 TPU等)或者不同的机器中,每个节点产生的数据可以通过明确的线发送的下一个结点中。
3. 可优化:TensorFlow 中的 XLA 编译器可以根据数据流图进行代码优化,加快运行速度。
4. 可移植:数据流图的信息可以不依赖代码进行保存,如使用Python创建的图,经过保存后可以在C++或Java中使用。
举例:利用典型的机器器学习公式y = wx + b 构建计算图。为了了简化问题,我们先假设w , x , b 都是常量:
import tensorflow as tf
# 创建 w 常量
w = tf.constant(3, dtype=tf.float32)
# 创建 x 常量
x = tf.constant(5, dtype=tf.float32)
# 创建 b 常量
b = tf.constant(4, dtype=tf.float32)
# 前面是三个Tensor即结点,现在创建他们之间的联系即边。
y = w * x + b
注意:从TensorFlow 1.6版本之后,开始引入动态图机制Eager Execution,它是一个命令式、由运行定义的接口,一旦从 Python 被调用,其操作立即被执行。这使得入门 TFlow 变的更简单,也使研发更直观。这个属于TensorFlow的高阶用法,感兴趣的可以阅读TF官方文档。
3.Placeholder
计算图中有一类比较特的结点: tf.placeholder 就是一个Tensor的占位符,这个时候我只描述他的dtype , shape 等一些基本信息。就像上面提到的【水桶】。但不像Tensor那样,我们可以把Tensor想象成真实的【水桶】,而placeholder 还存在与我们的想法中,虽然类型、形状与真实的相同。
什么地方需要用到tf.placeholder 呢? 从上面的例子可以看到,使用tf.constant()创建的Tensor都是常量,一旦创建后其中的值就不能改变了。有时我们还会需要从外部输入数据,这个数据每次输入都不会完全一样。此时它也不是变量,不能像参数一样参与到网络的训练中。这时可以用tf.placeholder 创建占位Tensor,占位Tensor的值可以在运行的时候输入。
如:
import tensorflow as tf
# 创建两个占位 Tensor 结点
a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
# 创建一个 adder 结点,对上面两个节点执行 + 操作
adder_node = a + b
4. Session(会话)
虽然有了Tensor,也有了Dataflow Graph,即:有了容器,也有了怎么对这些容器器进行操作的方法,此时还缺一个执行这个任务的环境。
在TensorFlow中提供了一个叫tf.Session 的会话机制,它为一个任务提供了计算环境,这时需要为这个环境提供输入输出数据。
还记得上面的例子吗?在我们打印Tensor的时候,并没有输出想要的Tensor内部数据,而是Tensor的属性描述,这时候要知道Tensor内部到底存放了什么数据,就需要用到tf.Session 。
例一:(手动关闭会话)
import tensorflow as tf
# 创建一个整型常量
t0 = tf.constant(3, dtype=tf.int32)
# 创建一个会话
sess = tf.Session()
# 打印t0中的数据
print(sess.run(t0))
#关闭会话
sess.close()
此时,输出的t0就是tensor的详细数据:
>>> print(sess.run(t0))
3
对于之前的这个会话,每次结束都需要手动去关闭,不是很方便(有时候可能会忘记)。可以利用Python with的方式来自动关闭会话。
例二:(自动关闭会话)
import tensorflow as tf
# 创建一个整型常量
t0 = tf.constant(3, dtype=tf.int32)
with tf.Session() as sess:
# 打印t0中的数据
print(sess.run(t0))
此时,输出的t0就是tensor的详细数据(同上):
>>> print(sess.run(t0))
3
在TensorFlow中,Session有两种,除了tf.Session() 的方式,还有一种tf.InteractiveSession() ,这种会话一般用在命令行交互的方式,可以通过.eval() 来执行
Graph中的计算逻辑。
import tensorflow as tf
# 初始化InteractiveSession
sess = tf.InteractiveSession()
# 创建 w 常量
w = tf.constant(3, dtype=tf.float32)
# 创建 x 常量
x = tf.constant(5, dtype=tf.float32)
# 创建 b 常量
b = tf.constant(4, dtype=tf.float32)
# 前面是三个Tensor即结,现在创建他们联系即边
y = w * x + b
# 运行计算图
print(y.eval())
sess.close()
运行结果如下:
>>> print(y.eval())
19.0
使用InteractiveSession就不用每次都sess.run( )一下会话,这种情况比较适用于命令行的方式,一般会写一些比较简单的验证代码,当代码逻辑复杂的时候,还是需要使用tf.Session() 。
Session一般会包括两个参数:
fetches : 在当前会话run的过程中想要的返回值,可以是一个Tensor或者Tensor list。
feed_dict : 传入一个dict。这个参数是要输入给此次run过程中的参数,需要有对应的placeholder。
例如上例中y = w * x + b ,不想只计算y = 3 * 5 + 4 ,而想计算y = 3x + 4 。这时候x
是需要传入到Graph,需要使用tf.placeholder 。
import tensorflow as tf
# 初始化Session
sess = tf.Session()
w = tf.constant(3, dtype=tf.float32)
b = tf.constant(4, dtype=tf.float32)
# 创建x的占位符,因为是一个标量,所以shape为空
x = tf.placeholder(tf.float32, [])
# 前面是三个Tensor即结点,现在创建他们联系即边
y = w * x + b
# 运行计算图
print(sess.run(y, {x: 6}))
sess.close()
运行结果可以随着x 的变化而变化
>>> print(sess.run(y, feed_dict={x: 6}))
22.0
5. TensorBoard
为了更方便 TensorFlow 的建模和调优,Google还为TensorFlow开发了一款可视化的工具:TensorBoard。这里我们使用Tensorboard的最基础功能——查看计算图。
下面我们给出查看y=3x + 4 的完整计代码,并且通过web的形式可视化计算图。
import tensorflow as tf
sess = tf.Session()
w = tf.constant(3, dtype=tf.float32, name='w')
b = tf.constant(4, dtype=tf.float32, name='b')
x = tf.placeholder(tf.float32, [],name='x')
y = w * x + b
merged = tf.summary.merge_all()
#其中tf.summary.FileWriter('根据自己习惯命名', sess.graph)
tf.summary.FileWriter('yEwxPb', sess.graph)
sess.close()
可以看到在运行的代码目录下面多了yEwxPb 的文件夹,我们可以在命令行输入:
$ tensorboard - -logdir yEwxPb
此时我们使用google浏览器,输入http://localhost:6006/ 可以查看我们创建的计算图
tensorboard还有很多用法,例如用来监控训练过程中loss下降趋势、参数分布等。想进一步了解可以参考TensorFlow 官方文档中文版
三、总结:
以上学写了TensorFlow框架中五个最重要的概念—— Tensor 、Dataflw Graph 、
Placeholder 、Session 、Tensorboard 。
Tensor :计算逻辑的基本单元,用于存储和描述数据
Graph :Tensor之间的计算逻辑,用于完成对任务的定义
Placeholder :占位符,运行自定义输入数据
Session :TensorFlow的运行环境,每次run都在对应的Session运行
Tensorboard :强大优雅的可视化工具
参考:
- Vlon Jang
- TensorFlow官方文档
1.英文:
TensorFlowtensorflow.google.cn2.中文:
TensorFlow 官方文档中文版www.tensorfly.cn有帮助就点个赞呗,欢迎指正!