基本用法

  • 使用图(graph)表示计算任务,描述了计算过程
  • 会话(Session)用于执行图,即执行计算任务,
  • 使用tensor表示数据
  • 变量(variable) 维护状态
  • 通过 feed 和 fetch 可以为任何的操作(arbitrary operation) 赋值或者从中获取数据

综述

  • 图中的节点,即operation操作,称为op
  • 一个op获得0或多个数据输入,即tensor,执行计算,产生0或多个tensor输出
  • 每个tensor是一个类型化的多维数组。
  • graph必须在session中启动,session将op分发给诸如cpu或gpu之类的设备上,同时提供执行op的方法

计算图

  • Tensorflow程序通常分为:构建阶段和执行阶段。
  • 构建阶段:把op的执行步骤描述成一个图
  • 执行阶段:使用会话执行图中的op

构建图

  • 第一步,创建源op(source op),source op 不需要任何输入,如常量,source op的输出被传递给其他的op做运算
  • tensorflow python库中有一个默认的图default graph,op构造器可以为其增加节点
import tensorflow as tf
#创建一个常量op,产生一个1*2矩阵,这个op被作为一个节点加入到默认图中
#构造器的返回值代表该常量op的返回值
matrx1 = tf.constant([[3., 3.]])
#创建另一个常量op,产生一个2*1矩阵
matrix2 = tf.constant([[2.], [2.]])
#创建一个矩阵乘法 matmul op, 把matrix1和matrix2作为输入

#返回值product表示乘法结果
product = tf.matmul(matrix1, matrix2)
#上面创建了矩阵运算的图,但是需要在session中启动这个图才能得到结果



在一个会话中启动图

  • 启动图的第一步是创建一个session对象,如果无任何参数,会话构造器将启动默认图。
#启动默认图
sess = tf.Session()
#调用 sess 的 run() 方法来执行矩阵乘法op, 传入 product作为该方法的参数。product表示矩阵乘法op的输出,传入作为参数是向方法表示,我们希望取回矩阵乘法op的输出#整个执行过程是自动化的, 会话负责传递op所需的全部输入,op通常是并发执行
#函数调用run(product) 触发了图的三个op(两个常量op和一个矩阵乘法op)的执行
#返回值result是一个numpy ‘ndarray’对象(python中tensor是numpy ndarray对象,c和c++中,tensor是tensorflow::tensor实例)
result = sess.run(product)print result
#==>[[12.]]

#任务完成,关闭会话
sess.close()
  • Session对象在使用完需要关闭以释放资源。除了显示调用close外,也可以用with代码块赖自动完成关闭动作
with tf.Session() as sess:    
    result = sess.run([product])    
    print result
  • tensorflow不需要显示指定使用cpu还是gpu,tensorflow可以自动检测,有gpu则尽可能利用第一个gpu来执行操作。
  • 如果机器上有超过一个可用的gpu,除了第一个外的其他gpu是不参与计算。为了让Tensorflow使用这些gpu,必须就爱你op明确指派给他们执行。使用with device语句指派特定cpu或gpu执行操作
with tf.Session() as sess:
    with tf.device("/gpu:1"): 
       matrix1 = tf.constant([[3., 3.]]) 
       matrix2 = tf.constant([[2.],[2.]]) 
       product = tf.matmul(matrix1, matrix2)
        ...
  • device用字符串进行标示,目前支持的设备包括

"/cpu:0"

  • : 机器的 CPU.

"/gpu:0"

  • : 机器的第一个 GPU, 如果有的话.

"/gpu:1"

  • : 机器的第二个 GPU, 以此类推.

交互式使用

  • 为了方便使用诸如IPython之类的python交互环境,可以使用InteractiveSession替代Session类,使用tensor.eval()和operation.run()方法替代Session.run()。这样可以避免使用一个变量来持有会话。
#进入一个交互式tensorflow会话
import tensorflow as tf

sess = tf.InteractiveSession()
x = tf.Variable([1.0, 2.0])
a = tf.constant([3.0, 3.0])

#使用初始化器 initializer op的run()方法出事化x(变量需要初始化)
x.initializer.run()

#增加一个减法sub op,从 x 减去a,运行减法op,输出结果
sub = tf.sub(x, a)
print sub.eval()

#==> [-2., -1.]

Tensor

  • tensorflow中使用tensor数据结构标示所有的数据,一个tensor可以看作一个n维的数组或列表
  • 一个tensor包含一个静态类型rank和一个shape

变量Variable

  • 变量维护图执行过程中的状态信息。下面演示使用变量variable实现一个简单的计数器
#创建一个变量,初始化为标量 0
state = tf.Variable(0, name="counter")
#创建一个op,其作用是使 state 增加 1
one = tf.constant(1)
new_value = tf.add(state, one)
update = tf.assign(state, new_value)

#启动图后, 变量必须先经过初始化 (init) op 初始化,首先必须增加一个初始化 op到图中
init_op = tf.initialize_all_variables()
#启动图,运行op
with tf.Session() as sess:
    #运行 init op
    sess.run(init_op)
    #打印 state 的初始值
    print sess.run(state) 
    #运行op,更新 state, 并打印state
    for _ in range(3):
        sess.run(update)
        print sess.run(state)

#输出:
#0
#1
#2
#3
  • 代码中assign()操作是图所描述的表达式的一部分,正如add()操作一样。在调用run()之前,并不会真正执行赋值操作
  • 通常可以将一个模型中的参数表示为一组变量。如将一个神经网络的权重作为某个变量存储在tensor中,在训练过程中,通过重复运行训练图,更新tensor

Fetch

  • 可以在使用session对象的run()调用执行图时,传入一个或多个tensor作为参数,这些tensor可以取回运行结果
input1 = tf.constant(3.0)
input2 = tf.constant(2.0)
input3 = tf.constant(5.0)
intermed = tf.add(input2, input3)
mul = tf.mul(input1, intermed)
with tf.Session():
    result = sess.run([mul, intermed])
    print result

# 输出:
# [array([ 21.], dtype=float32), array([ 7.], dtype=float32)]
  • 需要获取的多个tensor值,在op的一次运行中一起获取而不是逐个去获取

Feed

  • feed机制可以临时替代图中的任意op中的tensor,可以对图中任何op提交补丁,直接插入一个tensor
  • feed使用一个tensor值临时替换一个op的输出结果。你可以提供feed数据作为run()调用的参数,feed只在调用它的方法内有效,方法结束,feed消失
  • 常见的用法是将某些特殊的操作制定为feed操作,标记的方法是使用tf.placeholder()为这些操作创建占位符
input1 = tf.placeholder(tf.types.float32)
input2 = tf.placeholder(tf.types.float32)
output = tf.mul(input1, input2)
with tf.Session() as sess:
    print sess.run([output], feed_dict={input1:[7.], input2:[2.]})

#输出:
#[array([14.], dtype=float32)]
  • 如果没有正确提供feed, placeholder()操作将会产生错误