1.3 TensorFlow基本使用
TensorFlow是一个编程系统,使用图来表示计算任务。图中的节点被称为op (operation的缩写),一个op获得0个或多个Tensor,执行计算产生0个或多个Tensor。每个Tensor是一个类型化的多维数组。例如,用户可以将一个小组图像集表示为一个四维数组,这四个维度分别是[batch,height,width,channels]。
一个TensorFlow图描述了计算的过程。为了进行计算,图必须在会话里被启动。会话将图的op分发到CPU或GPU等设备上,同时提供执行op的方法。这些方法执行后,将产生的Tensor返回。在Python语言中,返回的Tensor是numpy ndarray对象;在C 和C++语言中,返回的Tensor是TensorFlow::Tensor 实例。
我们使用TensorFlow,必须明白TensorFlow:
·使用图(graph)来表示计算任务;
·在被称为会话(Session)的上下文(context)中执行图;
·使用Tensor表示数据;
·通过变量(Variable)维护状态;
·使用feed和fetch可以为任意的操作(arbitrary operation)赋值或者从中获取数据。
1.3.1 计算图
TensorFlow程序通常被组织成一个构建阶段和一个执行阶段。在构建阶段,op的执行步骤被描述成一个图;在执行阶段,使用会话执行图中的op。
例如,通常在构建阶段创建一个图来表示和训练神经网络,然后在执行阶段反复执行图中的训练op。
TensorFlow支持C、C++、Python 编程语言。目前,TensorFlow的Python库更加容易被使用,它提供了大量的辅助函数来简化构建图的工作,这些函数尚未被C和C++编程语言支持。
C、C++、Python这三种编程语言的会话库是一致的。
1.3.2 构建图
构建图需要先创建源op(source op)。源op不需要任何输入,如常量(constant),源op的输出被传递给其他op进行运算。
Python库中,op构造器的返回值代表被构造出的op的输出,这些返回值可以传递给其他op构造器作为输入。
TensorFlow库有一个默认图(default graph),op构造器可以为其增加节点,这个默认图对许多程序来说已经足够用了。以下代码用于构建图:
默认图中现在有三个节点,分别为两个constant()节点和一个matmul()节点。为了真正进行矩阵相乘运算,并得到矩阵乘法的结果,用户必须在会话里启动这个图。
1.3.3 在一个会话中启动图
构造阶段完成后才能启动图,启动图需要先创建一个Session对象,如果无任何创建参数,会话构造器将启动默认图。
输出如下:
Session对象在使用完后需要关闭以释放资源,除了调用close,也可以使用with代码块来自动完成关闭动作。
在实现上,TensorFlow将图形定义转换成分布式执行的操作,以充分利用可用的计算资源(如CPU或GPU)。一般用户不需要显式指定使用的是CPU还是GPU,TensorFlow能自动检测。如果检测到GPU,TensorFlow就会尽可能地利用找到的第一个GPU来执行操作。
如果计算机上有超过一个可用的GPU,那么除第一个以外的其他GPU默认是不参与计算的。为了让TensorFlow使用这些GPU,用户必须将op明确指派给它们执行。with...device语句用来指派特定的CPU或GPU执行操作:
设备用字符串进行标识,目前支持的设备包括:
·"/cpu:0":计算机的CPU;
·"/gpu:0":计算机的第一个GPU,若有的话;
·"/gpu:1":计算机的第二个GPU,以此类推。
1.3.4 交互式使用
1.3.3节中的示例使用一个会话Session来启动图,并调用Session.run()方法来执行操作。
为了便于使用IPython的Python交互环境,可以使用InteractiveSession代替 Session类,使用Tensor.eval()和Operation.run()方法代替Session.run()。这样可以避免使用一个变量来持有会话。
运行程序,输出如下:
TensorFlow程序使用Tensor数据结构来代表所有的数据,在计算图中,操作之间传递的数据都是Tensor。用户可以把TensorFlow的Tensor看作是一个n维的数组或列表。一个Tensor包含一个静态类型rank和一个shape。
1.3.5 Fetch
为了取回操作的输出内容,可以在使用Session对象的run()调用执行图时,传入一些Tensor,这些Tensor会帮助用户取回结果。在之前的例子中,我们只取回了单个节点state,但是用户也可以取回多个Tensor:
运行程序,输出如下:
在op的一次运行中一起获得需要获取的多个Tensor值(不是逐个去获取Tensor值)。
1.3.6 Feed
1.3.5节在计算图中引入了Tensor,以常量或变量的形式存储。TensorFlow还提供了Feed机制,该机制可以临时替代图中的任意操作,Tensor可以对图中任何操作提交补丁,直接插入一个Tensor。
Feed使用一个Tensor值临时替换一个操作的输出结果。用户可以提供Feed数据作为run() 调用的参数。Feed只在调用它的方法内有效,方法结束,Feed就会消失。最常见的用例是将某些特殊的操作指定为Feed操作,标记的方法是使用tf.placeholder()为这些操作创建占位符。
运行程序,输出如下:
如果没有正确提供Feed,tf.placeholder()操作将会产生错误。