浅谈tensorflow框架和深度学习应用

来源:互联网 发布:ubuntu unsable 编辑:程序博客网 时间:2024/05/18 00:44

由于本框架支持python和C++接口,从系统和代码的角度分析内部实现的原理,从核心框架到Opkemels模块、Graph模块、Session模块。由于具有良好的延展性所以得到广泛应用,设计理念我认为和现在的模块式并没有多大区别这种基于UML的建模方法计算框架应用已经非常成熟。从底层的设备管理层-通信层-数据操作层-图计算层
设备管理层主要是对CPU、GPU、Mobile的MPU、APU的调用问题,理多线程就是异步,单线程就是同步
同步是阻塞模式,异步是非阻塞模式。

从一定意义上讲,进程就是一个应用程序在处理机上的一次执行过程,它是一个动态的概念,而线程是进程中的一部分,进程包含多个线程在运行。
程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们称其为进程。
通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源。在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度。
线程和进程的区别在于,子进程和父进程有不同的代码和数据空间,而多个线程则共享数据空间,每个线程有自己的执行堆栈和程序计数器为其执行上下文
多线程主要是为了节约CPU时间,发挥利用,根据具体情况而定。**要使用计算机的内存资源和CPU。
进程间相互独**
进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
**体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,
只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。**程所拥有的全部资源。

CPU和GPU之所以大不相同,是由于其设计目标的不同,它们分别针对了两种不同的应用场景。CPU需要很强的通用性来处理各种不同的数据类型,同时又要逻辑判断又会引入大量的分支跳转和中断的处理。这些都使得CPU的内部结构异常复杂。而GPU面对的则是类型高度统一的、相互无关联的大规模数据和不需要重复性大规模计算环境下面就是CPU和GPU架构的比对
tensorflow目录包括tf核心代码模块
public API接口头文件目录用于外部接口的API定义调用,主要是session.h和tensor_c_api.h
client API实现文件目录
plattrom OS系统的接口文件,file、system、env and so on
common_runtime公共运行库主要是session、excutor,threadpool randezvous,memory管理,设备分配调度算法
distracted_runtime分布式模块,rpc,session,master、rpc,worker、graph、manager
framework ,(log、memory、tensor)。 graph: 计算流图相关操作,如construct, partition, optimize, execute等
kernels: 核心Op,如matmul, conv2d, argmax, batch_norm等
lib: 公共基础库,如gif、gtl(google模板库)、hash、histogram等。
ops: 基本ops运算,ops梯度运算,io相关的ops,控制流和数据流操作
Tensorflow/stream_executor目录是并行计算框架,由google stream executor团队开发。
Tensorflow/contrib目录是contributor开发目录。Tensroflow/python目录是python API客户端脚本。Tensorflow/tensorboard目录是可视化分析工具,不仅可以模型可视化,还可以监控模型参数变化。third_party目录是TF第三方依赖库eigen3: eigen矩阵运算库,TF基础ops调用gpus: 封装了cuda/cudnn编程库。
理论核心框架
基于Grahp展开,原理是算法和参数封装到tensor里面顺着Graph传递闭合包flow的,这里设计量子数学知识。
Graph之前需要进行的辅助工程是符合编程、计算流图、梯度计算、控制流的概念。
从Matrix表示二维线性映射开始,tensor主要表示多维线性映射,这种维度上为了达到泛化和高维特征的映射,映射关系不是等于不要出现逻辑错误打算用数学的反证法证明是绝对不行的,但是可以从几何角度可以证明,相关案例在纽约大学顾险峰教授的博客,表示在1-dim、2-dim、3-dim到n-dim的高维空间
张量积运算是在matmul和conv2D运算中用到的,张量积和矩阵乘法是两个概念加速张量并行运算是TF优先考虑的问题,如add,contract, slice, reshape, reduce, shuffle等运算。TF中Tensor的维数描述为阶,数值是0阶,向量是1阶,矩阵是2阶,以此类推,可以表示n阶高维数据。TF中Tensor支持的数据类型有很多,如tf.float16, tf.float32, tf.float64, tf.uint8, tf.int8, tf.int16, tf.int32, tf.int64, tf.string, tf.bool, tf.complex64等,所有Tensor运算都使用泛化的数据类型表示。TF的Tensor定义和运算主要是调用Eigen矩阵计算库完成的。TF中Tensor的UML定义如图 2 2。其中TensorBuffer指针指向Eigen::Tensor类型。其中,Eigen::Tensor[5][6]不属于Eigen官方维护的程序,由贡献者提供文档和维护,所以Tensor定义在Eigen unsupported模块中。
Tensor主要包含两个变量m_data和m_dimension,m_data保存了Tensor的数据块,T是泛化的数据类型,m_dimensions保存了Tensor的维度信息。Eigen::Tensor的成员变量很简单,却支持非常多的基本运算,再借助Eigen的加速机制实现快速计算,参考章节3.2。Eigen::Tensor主要包含了
一元运算(Unary),如sqrt、square、exp、abs等。
二元运算(Binary),如add,sub,mul,div等
选择运算(Selection),即if / else条件运算
归纳运算(Reduce),如reduce_sum, reduce_mean等
几何运算(Geometry),如reshape,slice,shuffle,chip,reverse,pad,concatenate,extract_patches,extract_image_patches等
张量积(Contract)和卷积运算(Convolve)是重点运算,后续会详细讲解。
编程模式通常分为命令式编程(imperative style programs)和符号式编程(symbolic style programs)。命令式编程容易理解和调试,命令语句基本没有优化,按原有逻辑执行。符号式编程涉及较多的嵌入和优化,不容易理解和调试,但运行速度有同比提升。这两种编程模式在实际中都有应用,Torch是典型的命令式风格,caffe、theano、mxnet和Tensorflow都使用了符号式编程。其中caffe、mxnet采用了两种编程模式混合的方法,而Tensorflow是完全采用了符号式编程,Theano和Tensorflow的编程模式更相近命令式编程是常见的编程模式,编程语言如python/C++都采用命令式编程。命令式编程明确输入变量,并根据程序逻辑逐步运算,这种模式非常在调试程序时进行单步跟踪,分析中间变量
符号式编程将计算过程抽象为计算图,计算流图可以方便的描述计算过程,所有输入节点、运算节点、输出节点均符号化处理。计算图通过建立输入节点到输出节点的传递闭包,从输入节点出发,沿着传递闭包完成数值计算和数据流动,直到达到输出节点。这个过程经过计算图优化,以数据(计算)流方式完成,节省内存空间使用,计算速度快,但不适合程序调试,通常不用于编程语言中。举上面的例子,先根据计算逻辑编写符号式程序并生成计算图

目前的符号语言比起来,TF最大的特点是强化了数据流图,引入了mutation的概念。这一点是TF和包括Theano在内的符号编程框架最大的不同。所谓mutation,就是可以在计算的过程更改一个变量的值,而这个变量在计算的过程中会被带入到下一轮迭代里面去。
Mutation是机器学习优化算法几乎必须要引入的东西(虽然也可以通过immutable replacement来代替,但是会有效率的问题)。 Theano的做法是引入了update statement来处理mutation。TF选择了纯符号计算的路线,并且直接把更新引入了数据流图中去。从目前的白皮书看还会支持条件和循环。这样就几乎让TF本身成为一门独立的语言。不过这一点会导致最后的API设计和使用需要特别小心,把mutation 引入到数据流图中会带来一些新的问题,比如如何处理写与写之间的依赖
梯度计算主要应用在误差反向传播和数据更新,是深度学习平台要解决的核心问题。梯度计算涉及每个计算节点,每个自定义的前向计算图都包含一个隐式的反向计算图。从数据流向上看,正向计算图是数据从输入节点到输出节点的流向过程,反向计算图是数据从输出节点到输入节点的流向过程。对应的反向计算图。由于C=A*B,则dA=B*dC, dB=A*dC。在反向计算图中,输入节点dD,输出节点dA和dB,计算表达式为dA=B*dC=B*dD, dB=A*dC=A*dD。每一个正向计算节点对应一个隐式梯度计算节点。
控制流主要为了提高逻辑计算控制,接口函数是pred判别表达式,fn1和fn2运算表达式当pred为true时执行fn1,反正false时执行fn2.
TF还可以协调多个数据流,在存在依赖节点的场景下非常有用,例如节点B要读取模型参数θ更新后的值,而节点A负责更新参数θ,则节点B必须等节点A完成后才能执行,否则读取的参数θ为更新前的数值,这时需要一个运算控制器。接口函数如下,tf.control_dependencies函数可以控制多个数据流执行完成后才能执行接下来的操作,通常与tf.group函数结合使用。

TF支持的控制算子有Switch、Merge、Enter、Leave和NextIteration等。TF不仅支持逻辑控制,还支持循环控制。TF使用和MIT Token-Tagged machine相似的表示系统,将循环的每次迭代标记为一个tag,迭代的执行状态标记为一个frame,但迭代所需的数据准备好的时候,就可以开始计算,从而多个迭代可以同时执行。

1 0
原创粉丝点击