TensorFlow tips笔记

概述:
  • TensorFlow是一种将计算表示为图的编程系统。图中的节点称为ops(operation的简称)。一个ops使用0个或以上的Tensors,通过执行某些运算,产生0个或以上的Tensors
  • TensorFlow中的图描述了计算过程,图通过Session的运行而执行计算。Session将图的节点们(即ops)放置到计算设备(如CPUs和GPUs)上,然后通过方法执行它们;这些方法执行完成后,将返回tensors。在Python中的tensor的形式是numpy ndarray对象,而在C/C++中则是tensorflow::Tensor.
  • 图的创建类似于一个 [施工阶段],而在 [执行阶段] 则利用一个session来执行图中的节点。很常见的情况是,在 [施工阶段] 创建一个图来表示和训练神经网络,而在 [执行阶段] 在图中重复执行一系列的训练操作。
  • Constant是一种没有输入的ops,但是你可以将它作为其他ops的输入。Python库中的ops构造器将返回构造器的输出。TensorFlow的Python库中有一个默认的图,将ops构造器作为节点。


几个概念:
1、graph(图)
即计算任务

2、op(operation缩写)
一个完成任务的步骤

3、session(会话)
实现图和计算内核的交互。

$ python                          		  #进入python语言环境,出现>>>即代表进入了
>>> import tensorflow as tf       		  #1,声明引用tensorflow,在后面的代码中以tf来使用tensorflow的所有功能
>>> hello = tf.constant('Hello, TensorFlow!')	  #2,创建一个变量hello,其值是tf的一个op结果
>>> sess = tf.Session()           		  #3,创建一个变量sess,其是tf的一个Session实例
>>> print hello
Tensor("Const:0", shape=(), dtype=string)	  #只是类型说明,不是具体值
>>> print sess.run(hello)         		  #4,调用Session对象的run方法对hello这个op进行处理,然后将结果返回给print打印
Hello, TensorFlow!
>>> a = tf.constant(10)       			  #5, 创建一个变量a,其值是tf的一个op结果
>>> b = tf.constant(32)       			  #6, 创建一个变量b,其值是tf的一个op结果
>>> print a 
Tensor("Const_1:0", shape=(), dtype=int32)	#只是类型说明,不是具体值
>>> print b
Tensor("Const_2:0", shape=(), dtype=int32)	#只是类型说明,不是具体值
>>> print sess.run(a+b)             		#7, 调用Session对象的run方法对a这个op和b这个op进行加法处理,然后将结果返回给print打印
42

  • “TensorFlow程序通常被组织成一个构建阶段, 和一个执行阶段. 在构建阶段, op 的执行步骤被描述成一个图.在执行阶段, 使用会话执行图中的 op.”
  • 在tensorflow中,调用run方法时是执行阶段,其它是构建阶段,构建阶段你声明和定义的任何op操作只是被记下来了,但并没有落实,只有到了run时,tensorflow才真正的使用CPU执行这些op操作。这样基本上消除了一段代码内在tf和python之间的切换,会大大减小开支,提升计算效率。同时,将很多操作攒在一堆,也方便分布式执行。
  • 会话 (Session)存在的意义就是为了区别执行阶段和构建阶段,因为常规开发语言中,每一行代码都是执行阶段。
  • Sessions最后需要关闭,以释放相关的资源;你也可以使用with模块,session在with模块中自动会关闭。
————————————————————————————————————————————————————————————————
  • Session是Graph和执行者之间的媒介,Session.run()实际上将graph、fetches、feed_dict序列化到字节数组中,并调用tf_session.TF_Run(参见/usr/local/lib/python2.7/site-packages/tensorflow/python/client/session.py)
  • 而这里的tf_session.TF_Run实际上调用了动态链接库_pywrap_tensorflow.so中实现的_pywrap_tensorflow.TF_Run接口(参见/usr/local/lib/python2.7/site-packages/tensorflow/python/pywrap_tensorflow.py),这个动态链接库是tensorflow提供的诸多语言接口中python语言的接口;
  • 事实上这里的_pywrap_tensorflow.so和pywrap_tensorflow.py是通过SWIG工具自动生成,大家都知道tensorflow核心语言是c语言,这里是通过SWIG生成了各种脚本语言的接口。
————————————————————————————————————————————————————————————————

4、Tensor
用来表示常规的程序数据。

每个 Tensor 是一个类型化的多维数组,一个Tensor具有固定的类型、级别和大小。

一个 op获得 0 个或多个Tensor , 执行计算, 产生 0 个或多个Tensor 。


5、tensorboard
  • tensorflow因为代码执行过程是先构建图,然后在执行,所以对中间过程的调试不太方便,所以提供了一个tensorboard工具来便于调试,用法如下:
  • 在训练时会提示写入事件文件到哪个目录(比如:/tmp/tflearn_logs/11U8M4/)
  • 执行如下命令并打开http://192.168.1.101:6006就能看到tensorboard的界面:
  • tensorboard --logdir=/tmp/tflearn_logs/11U8M4/
  • 生成的图就是上面这段代码生成的graph结构,这个graph描述了整个梯度下降解决线性回归问题的整个过程,每一个节点都代表了代码中的一步操作。

6、Variables

变量在图执行的过程中,保持自己的状态信息。

# Create a Variable, that will be initialized to the scalar value 0.
state = tf.Variable(0, name="counter")

# Create an Op to add one to `state`.

one = tf.constant(1)
new_value = tf.add(state, one)
update = tf.assign(state, new_value)

所有tensors的输出都是一次性连贯执行的。


7、placeholder占位符

input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
output = tf.mul(input1, input2)

with tf.Session() as sess:
  print(sess.run([output], feed_dict={input1:[7.], input2:[2.]}))


###########################################################################################


技术使用:
1、Tensorflow是完全采用了符号式编程,每个节点都是符号化表示的。通过session创建graph,在调用session.run执行计算。


符号式编程将计算过程抽象为计算图,计算流图可以方便的描述计算过程,所有输入节点、运算节点、输出节点均符号化处理。计算图通过建立输入节点到输出节点的传递闭包,从输入节点出发,沿着传递闭包完成数值计算和数据流动,直到达到输出节点。这个过程经过计算图优化,以数据(计算)流方式完成,节省内存空间使用,计算速度快,但不适合程序调试,通常不用于编程语言中。
A = Variable('A')	#输入符号变量
B = Variable('B')	#输入符号变量
C = B * A		#运算符号变量
D = C + Constant(1)	#运算符号变量,D可复用C的内存空间
F = compile(D)		#生成计算图	

2、TF最大的特点是强化了数据流图,引入了mutation的概念。
TF的计算图如同数据流一样,数据流向表示计算过程。
这一点是TF和包括Theano在内的符号编程框架最大的不同。
所谓mutation,就是可以在计算的过程更改一个变量的值,而这个变量在计算的过程中会被带入到下一轮迭代里面去。
Mutation是机器学习优化算法几乎必须要引入的东西,TF选择了纯符号计算的路线,并且直接把更新引入了数据流图中去。

3、梯度计算
梯度计算涉及每个计算节点,每个自定义的前向计算图都包含一个隐式的反向计算图。
从数据流向上看,正向计算图是数据从输入节点到输出节点的流向过程,反向计算图是数据从输出节点到输入节点的流向过程。
反向计算限制了符号编程中内存空间复用的优势,因为在正向计算中的计算数据在反向计算中也可能要用到。从这一点上讲,粗粒度的计算节点比细粒度的计算节点更有优势,而TF大部分为细粒度操作,虽然灵活性很强,但细粒度操作涉及到更多的优化方案,在工程实现上开销较大,不及粗粒度简单直接。在神经网络模型中,TF将逐步侧重粗粒度运算。

4、控制流
tf.cond(pred,fn1,fn2,name=None) #pred为判别表达式,fn1和fn2为运算表达式。当pred为true是,执行fn1操作;当pred为false时,执行fn2操作。
tf.control_dependencies(control_inputs) #运算控制器,控制多个数据流执行完成后才能执行接下来的操作,通常与tf.group函数结合使用

TF不仅支持逻辑控制,还支持循环控制。将循环的每次迭代标记为一个tag,迭代的执行状态标记为一个frame,当迭代所需的数据准备好的时候,就可以开始计算,从而多个迭代可以同时执行。


5、使用Eigen库
在Tensoflow中核心数据结构和运算主要依赖于Eigen和Stream Executor库,其中Eigen支持CPU和GPU加速计算,Stream Executor主要用于GPU环境加速计算。
Eigen是高效易用的C++开源库,有效支持线性代数,矩阵和矢量运算,数值分析及其相关的算法。不依赖于任何其他依赖包,安装使用都很简便。
Eigen 惰性求值也认为是“延迟求值”,不需要临时变量保存中间结果,可以构造一个无限的数据类型,提高了计算性能。
Eigen 编译加速使用了SSE2加速。假设处理float32类型,指令集支持128bit并行计算,则一次可以计算4个float32类型,速度提升4倍。可以充分发挥计算机的并行计算能力,提高程序运行速度。
Eigen::half,Tensorflow支持的浮点数类型有float16, float32, float64,其中float16本质上是Eigen::half类型,即半精度浮点数。在分布式计算中,如果对数据精度要求不那么高,可以将传输数据转换为float16类型,这样可以大大缩短设备间的数据传输时间。在GPU运算中,float16还可以减少一般的内存占用。在Tensorflow的分布式传输中,默认会将float32转换为float16类型。Tensorflow的转换方式不同于nvidia的标准,采用直接截断尾数的方式转化为半精度浮点数,以减少转换时间。


6、TF设备内存管理模块利用BFC算法(best-fit with coalescing)实现。BFC算法是Doung Lea’s malloc(dlmalloc)的一个非常简单的版本。它具有内存分配、释放、碎片管理等基本功能。
BFC的核心思想是:将内存分块管理,按块进行空间分配和释放;通过split操作将大内存块分解成小内存块;通过merge操作合并小的内存块,做到内存碎片回收。


7、TF系统开发使用了bazel工具实现工程代码自动化管理,使用了protobuf实现了跨设备数据传输,使用了swig库实现python接口封装。
7.1 TF中几乎所有代码编译生成都是依赖Bazel完成的,Bazel是Google开源的自动化构建工具,类似于Make和CMake工具。Bazel的目标是构建“快速并可靠的代码”,并且能“随着公司的成长持续调整其软件开发实践”。
Bazel假定每个目录为[package]单元,目录里面包含了源文件和一个描述文件BUILD,描述文件中指定了如何将源文件转换成构建的输出。
7.2 Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。
Protobuf对象描述文件为.proto类型,编译后生成.pb.h和.http://pb.cc文件。
在分布式环境中,不仅需要传输数据序列化,还需要数据传输协议。Protobuf在序列化处理后,由gRPC完成数据传输。



参考资料

1、TensorFlow学习笔记1:入门

2、自己动手做聊天机器人 三十七-一张图了解tensorflow中的线性回归工作原理

3、『深度长文』Tensorflow代码解析(一)

4、TensorFlow入门一

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bicelove

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值