
1.2 TensorFlow介绍
TensorFlow是基于计算图实现的。思考下面的数学表达式:
c=(a+b),d=b+5
e=c*d
图1-2是TensorFlow的一个计算图。因为计算都是并行完成的,所以这很强大。

图1-2 TensorFlow计算图
TensorFlow安装
有两种简单的TensorFlow安装方法:
·使用虚拟环境(推荐并在此说明)。
·使用Docker镜像。
1.针对macOS X/Linux不同版本
下面代码片段用于创建一个Python虚拟环境,并在该环境安装TensorFlow。运行此代码之前,需要先安装Anaconda:

请在TensorFlow官方页面查看最新版本。
尝试在你的Python控制台运行以下代码来验证TensorFlow的安装是否成功。如果安装成功,控制台应该打印出“Hello World!”。

2.TensorFlow基础
在TensorFlow中,数据不是以整型、浮点型、字符串或其他原始数据类型存储的,而是用一个称为张量的数据结构来表示这些数据。它是一个由原始值组成的任意维的数组。张量的维数称为阶。在前面的例子中,hello_constant是一个0阶的常量字符串张量。一些常量张量的例子如下:

TensorFlow程序的核心是计算图。计算图是由以下两部分组成的有向图:
·创建计算图。
·运行计算图。
计算图在会话中执行。会话是计算图的运行时环境,它负责分配CPU、GPU并管理TensorFlow运行时状态。下面的代码使用tf.Session创建一个名为sess的会话实例。然后运行sess.run()函数进行张量的运算,并将返回结果存储在output变量中。最终打印出“Hello World!”

可以使用TensorBoard可视化图形。运行TensorBoard的命令如下:

如下所示,让我们创建一段简单的加法代码。首先创建一个整型常量x,赋值5;然后创建一个新的变量y,赋值为x加5,打印出y的值:

不同的是,没有像在Python代码中那样将x+5的结果直接赋给变量variable_y,而是写成了一个方程。这意味着当计算变量y时,取x在那个时间点的值然后加上5。variable_y值的计算在前面的代码中从未实际执行过。上面的这段代码实际上属于典型的TensorFlow程序的计算图创建部分。运行这段代码后,你将得到类似于<tensorflow.python.ops.variables.Variable object at 0x7f074bfd9ef0>的内容,而不是variable_y的实际值10。为了解决这个问题,必须执行计算图的代码部分,如下所示:

这里执行一些基本的数学函数,如张量间的加、减、乘、除。
3.TensorFlow中的数学基础
tf.add()函数取2个数字,2个张量,或1个数字和1个张量,然后以张量的形式返回它们的和:

减法和乘法的例子如下:

如果想用非常量该怎么处理呢?如何向TensorFlow提供输入数据集?为此,TensorFlow提供了一个API—tf.placeholder(),并运用feed_dict类型。
placeholder是后续会在tf.session.run()函数中赋予值的变量,基于此,我们可以在暂时没有数据的情况下创建我们的操作和计算图。然后,在tf.session.run()函数中使用feed_dict参数值设置placeholder张量,通过这些占位符(placeholder)将数据输入到计算图中。如下示例,在会话运行之前,将字符串“Hello World”设置给张量x:

也可以使用feed_dict参数值设置多个张量,如下所示:

占位符也可以在多维情况下存储数组,请参见如下示例:

当传递给feed_dict参数的数据与张量类型不匹配或者不能强制转换为张量类型时,将抛出错误“ValueError:invalid literal for...”。
tf.truncated_normal()函数返回一个具有正态分布随机值的张量。此函数主要用于网络权重初始化:

4.TensorFlow中的softmax函数
softmax函数将其输入(被称为logit或者logit score)转换为0到1之间的值,并对输出进行归一化,使其总和为1。换句话说,softmax函数将你的logit转换为概率。logit是指一个事件发生与不发生的概率比值的对数。在数学上,softmax函数的定义如下:

TensorFlow中实现了softmax函数。它输入logit并返回与输入同类型同形状的softmax激活,如图1-3所示。

图1-3 TensorFlow中的softmax函数
代码实现如下:

我们在数学上表示标签的方式通常称为one-hot编码。每个标签都由一个向量表示,向量中1表示正确对应的标签,0表示其他。这对大多数问题是很有效的。然而当问题有数百万个标签时,one-hot编码是无效的,因为向量中大多数元素是0。我们用交叉熵测量两个概率向量之间的相似距离,用D表示。
交叉熵是非对称的,即D(S,L)!=D(L,S)
在机器学习中,我们通常用数学函数来定义一个模型的好坏。这个函数叫作损失函数、成本函数或者目标函数。用于确定模型损失的一个很常见的函数叫作交叉熵损失。这个概念来自信息论(想了解更多,请参考视觉信息论https://colah.github.io/posts/2015-09-Visual-Information/)。直观来看,如果模型在训练数据上的分类效果很差,则损失会很高,否则损失将会很低,如图1-4所示。
在TensorFlow中,可以使用tf.reduce_sum()编写一个交叉熵函数。它需要一个数字数组,并将其和作为一个张量返回(请参阅如下代码块):

图1-4 交叉熵损失函数

但实际上,当计算softmax函数时,由于指数的存在,中间项可能会很大,所以除大数会导致数值上的不稳定。我们应该用TensorFlow提供的softmax和交叉熵损失API。如下代码片段手动计算交叉熵损失,并使用TensorFlow API打印相同的数据:

