数据流图 Data Flow Graphs , 深度学习--Tensorflow 编程原理

如果你是 Theano 出身的学院派,比如我,可以很轻松的理解和使用 Tensorflow 。因为,TensorFlow 工具的编写参考了 Theano 的数据流图的思想。唯一一点需要记住的是,请忘掉 Theano.funciton() 函数吧。

如果你是从C、汇编这样面向过程的语言开始,或者从 c++、java 、python等面向对象的编程语言开始,涉足 Tensorflow 的话,我相信我的教程,对你入门 TensorFlow 、甚至掌握 TensorFlow 会有非常大的帮助。原因有两点:

1)大学阶段,为了提高自己的 Windows 安防知识、软件破解技能,我曾经阅读过大量的汇编代码和c语言代码;我知道像 C++ 这样面向对象的语言如何编译成汇编代码的;在我看来,面向对象语言在汇编层面其实是个谎言。(当然,汇编,c,c++,java 都是我主修的专业课,因为我的专业计算机科学与技术) 因此,我把他们统称为面向过程的语言。

2)研究生阶段,我开始学习神经网络、DL 的理论知识,并且开始用 Theano 做实验。当时,因为数据流图的思想,跟传统的编程模式,Gap 很大,也很苦恼。于是便,花时间心思,去理解 数据流图的编程原理。

那让我们开始吧。

一、TF数据流图的数学计算,由数据驱动的;面向过程语言的数学计算,由代码驱动的

TensorFlow 数据流图的编程思想是,数学计算由数据驱动执行的;而面向过程的语言(以python语言示例)的编程思想是,数学计算由代码驱动执行的。

例子,(a + b) * c 在TensorFlow 和 python 的实现

import tensorflow as tf

def func_of_python():
  a = 2
  b = 17
  c = 91

  add_res = a + b
  print("   [Debug] 此处,你可以打印中间结果的信息。add_res = {}".format(add_res))
  
  mul_res = add_res * c

  return mul_res

def func_of_tf():
  a = tf.constant(2)
  b = tf.constant(17)
  c = tf.constant(91)
  
  add_op = a + b
  print("   [Debug] 此处,你如果想打印 a + b 的值,控制台输出肯定不是你期望的结果。add_op = {}".format(add_op))
  
  mul_op = add_op * c

  init = tf.global_variables_initializer()
  sess = tf.Session()
  
  sess.run(init)
  mul_op_res = sess.run([mul_op])
  return mul_op_res

if __name__ == '__main__':
  print("调用 python 版 (a + b) * c ")
  result = func_of_python()
  print("(a + b) * c = {}".format(result))

  print("调用 tensorflow 版 (a + b) * c ")
  result = func_of_tf()
  print("(a + b) * c = {}".format(result))
  pass

控制台输出:

调用 python 版 (a + b) * c 
   [Debug] 此处,你可以打印中间结果的信息。add_res = 19
(a + b) * c = 1729
调用 tensorflow 版 (a + b) * c 
   [Debug] 此处,你如果想打印 a + b 的值,控制台输出肯定不是你期望的结果。add_op = Tensor("add:0", shape=(), dtype=int32)
(a + b) * c = [1729]

你可能会埋怨,(a+b)*c 这么简单的运算,python 5行代码就实现了,为什么要用 tensorflow 的9行代码去实现呢?

你可能会吃惊,为什么打印的 add_op 不是一个数字呢?

你可能会不解,因为遇到,好几个陌生 Tensorflow 的函数!

但是,我们此行的目的是解释,数据流图的数学计算,由数据驱动的,过程语言的数学计算,由用代码驱动的。

对于 python 语言来说,当机器执行到下面的语句时,

add_res = a + b

实际上,已经计算出了 add_res 的值。换句话说,过程语言,遇到代码,便进行计算。

而,对于 Tensorflow 程序来说,请看下面程序注解:

def func_of_tf():
  a = tf.constant(2)    # 此处 a 不是基本的 int 类型,而是一个由 const Tensor 创建的类实例
  b = tf.constant(17)
  c = tf.constant(91)
  
  add_op = a + b
  
  mul_op = add_op * c

  # 上面的几行,仅仅画了一个数据的流程图,并没有真正的做数学计算

  init = tf.global_variables_initializer() # 
  sess = tf.Session()   # 打开了一个与 Tensorflow 会话的 Session
  
  sess.run(init)

  # 执行完run,tensorflow 才真正的开始做数学计算
  mul_op_res = sess.run([mul_op])

  return mul_op_res

Tensorflow 函数首先在 Graph 画板上画出了一个数据流图,如下:

数据流图 Data Flow Graphs , 深度学习--Tensorflow 编程原理_第1张图片

区别于 func_of_python 中的 a、b、c,此处的a、b、c 均是 Tensor 类的实例,且绑定了常量数据分别为 2、17、91。                 要想获得 (a + b) * c 的值,需要调用 sess.run() 方法获得。

二、总结,TF数据流图和面向过程语言的数学运算,触发的时间点是不同的

上一节,从代码角度,讲解了 TF 数据流图和面向过程语言触发的时机。宏观上来讲,面向过程的语言是不会关注,整个数学运算的所有环节,而 TF 数据流图掌控整个数学运算的所有环节。至于优势吗?TF 可以在了解了所有数学运算环节之后,进行优化。

三、 Eager Execution 模型,可以像面向过程语言一样,随时计算

最近,Eager Execution 出炉了。他可以像 python numpy 一样,时刻计算,随时打印。不过,数据流图也不难嘛!大家加油学好它。同时,也期待 Google 的工程师能优化 Eager Execution 模型的计算效率,使其和数据流图一样高效,那时候,我们就不需要跨越数据流图这个鸿沟了。

你可能感兴趣的:(深度学习或神经网络)