TensorFlow程序结构

在任何计算机语言中学习的第一个程序是都是 Hello world,本教程中也将遵守这个惯例,从程序 Hello world 开始。

上一节进行 TensorFlow 安装验证的代码如下:

 


 

下面一起看一下这段简单的代码:

  1. 导入tensorflow,这将导入 TensorFlow 库,并允许使用其精彩的功能:

    import tensorflow as if

  2. 由于要打印的信息是一个常量字符串,因此使用 tf.constant:

    message = tf.constant('Welcome to the exciting world of Deep Neural Networks!')

  3. 为了执行计算图,利用 with 语句定义 Session,并使用 run 来运行:

    with tf.Session() as sess:
        print(sess.run(message).decode())

  4. 输出中包含一系列警告消息(W),具体取决于所使用的计算机和操作系统,并声明如果针对所使用的计算机进行编译,代码运行速度可能会更快:



     

  5. 如果使用 TensorFlow GPU 版本,则还会获得一系列介绍设备的提示消息(I):



     

  6. 最后是在会话中打印的信息:

    Welcome to the exciting world of Deep Neural Networks!

TensorFlow 程序解读分析

前面的代码分为以下三个主要部分:

  • 第一部分 import 模块包含代码将使用的所有库,在目前的代码中只使用 TensorFlow,其中语句 import tensorflow as tf 则允许 Python 访问 TensorFlow 所有的类、方法和符号。
  • 第二个模块包含图形定义部分...创建想要的计算图。在本例中计算图只有一个节点,tensor 常量消息由字符串“Welcome to the exciting world of Deep Neural Networks”构成。
  • 第三个模块是通过会话执行计算图,这部分使用 with 关键字创建了会话,最后在会话中执行以上计算图。


现在来解读输出。收到的警告消息提醒 TensorFlow 代码可以以更快的速度运行,这能够通过从 source 安装 TensorFlow 来实现(本章后面的章节中会提及)。收到的提示消息给出计算设备的信息。这两个消息都是无害的,如果不想看到它们,可以通过以下两行代码实现:

import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'

以上代码用于忽略级别 2 及以下的消息(级别 1 是提示,级别 2 是警告,级别 3 是错误)。

该程序打印计算图执行的结果,计算图的执行则使用 sess.run() 语句,sess.run 求取 message 中所定义的 tensor 值;计算图执行结果输入到 print 函数,并使用 decode 方法改进,print 函数向 stdout 输出结果:

b'Welcome to the exciting world of Deep Neural Networks!'

这里的输出结果是一个字节字符串。要删除字符串引号和“b”(表示字节,byte)只保留单引号内的内容,可以使用 decode() 方法。

 

TensorFlow 与其他编程语言非常不同。

首先通过将程序分为两个独立的部分,构建任何拟创建神经网络的蓝图,包括计算图的定义及其执行。起初这对于传统程序员来说看起来很麻烦,但是正是图定义和执行的分开设计让 TensorFlow 能够多平台工作以及并行执行,TensorFlow 也因此更加强大。

计算图:是包含节点和边的网络。本节定义所有要使用的数据,也就是张量(tensor)对象(常量、变量和占位符),同时定义要执行的所有计算,即运算操作对象(Operation Object,简称 OP)。

每个节点可以有零个或多个输入,但只有一个输出。网络中的节点表示对象(张量和运算操作),边表示运算操作之间流动的张量。计算图定义神经网络的蓝图,但其中的张量还没有相关的数值。

为了构建计算图,需要定义所有要执行的常量、变量和运算操作。常量、变量和占位符将在下一节中介绍,数学运算操作将在矩阵运算章节中详细讨论。

本节将用一个简单的例子描述程序结构——通过定义并执行计算图来实现两个向量相加。

计算图的执行:使用会话对象来实现计算图的执行。会话对象封装了评估张量和操作对象的环境。这里真正实现了运算操作并将信息从网络的一层传递到另外一层。不同张量对象的值仅在会话对象中被初始化、访问和保存。在此之前张量对象只被抽象定义,在会话中才被赋予实际的意义。

具体做法

通过以下步骤定义一个计算图:

  1. 在此以两个向量相加为例给出计算图。假设有两个向量 v_1 和 v_2 将作为输入提供给 Add 操作。建立的计算图如下:

  2. 定义该图的相应代码如下所示:

     


     

  3. 然后在会话中执行这个图:

     


     

  4. 以上两行相当于下面的代码。上面的代码的优点是不必显式写出关闭会话的命令:

     


     

  5. 运行结果是显示两个向量的和:

    {3 3 8 7}

请记住,每个会话都需要使用 close() 来明确关闭,而 with 格式可以在运行结束时隐式关闭会话。

解读分析

计算图的构建非常简单。添加变量和操作,并按照逐层建立神经网络的顺序传递它们(让张量流动)。TensorFlow 还允许使用 with tf.device() 命令来使用具有不同计算图形对象的特定设备(CPU/GPU)。在例子中,计算图由三个节点组成, v_1 和 v_2 表示这两个向量,Add 是要对它们执行的操作。

接下来,为了使这个图生效,首先需要使用 tf.Session() 定义一个会话对象 sess。然后使用 Session 类中定义的 run 方法运行它,如下所示:

run(fetches,feed_dict=None,options=None,run_metadata)

运算结果的值在 fetches 中提取;在示例中,提取的张量为 v_add。run 方法将导致在每次执行该计算图的时候,都将对与 v_add 相关的张量和操作进行赋值。如果抽取的不是 v_add 而是 v_1,那么最后给出的是向量 v_1 的运行结果:

{1,2,3,4}

此外,一次可以提取一个或多个张量或操作对象,例如,如果结果抽取的是 [v_1...v_add],那么输出如下:

{array([1,2,3,4]),array([2,1,5,3]),array([3,3,8,7])}

在同一段代码中,可以有多个会话对象。

拓展阅读

你一定会问为什么必须编写这么多行的代码来完成一个简单的向量加,或者显示一条简单的消息。其实你可以利用下面这一行代码非常方便地完成这个工作:

print(tf.Session().run(tf.add(tf.constant([1,2,3,4]),tf.constant([2,1,5,3]))))

编写这种类型的代码不仅影响计算图的表达,而且当在 for 循环中重复执行相同的操作(OP)时,可能会导致占用大量内存。养成显式定义所有张量和操作对象的习惯,不仅可使代码更具可读性,还可以帮助你以更清晰的方式可视化计算图。

注意,使用 TensorBoard 可视化图形是 TensorFlow 最有用的功能之一,特别是在构建复杂的神经网络时。我们构建的计算图可以在图形对象的帮助菜单下进行查看。

如果你正在使用 Jupyter Notebook 或者 Python shell 进行编程,使用 tf.InteractiveSession 将比 tf.Session 更方便。InteractiveSession 使自己成为默认会话,因此你可以使用 eval() 直接调用运行张量对象而不用显式调用会话。下面给出一个例子:
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值