学习笔记(1.4)

使用占位符(Placeholder)和变量
占位符和变量是在TensorFlow中使用计算图(computational graphs)时用到的主要的工具,我们必须理解它们之间的区别,以及什么时间使用对我们最有利。
准备工作
处理数据时最主要的一点是区分数据是占位符还是变量:变量是算法的参数,TensorFlow会跟踪它是如何改变的以达到优化的目的;占位符是一种允许“喂入”(feed in)特定类型及“形状”(shape)的数据的对象,它依赖于计算图的结果,比如计算过程期望的输出结果。
如何做...
创建变量的主要方法是使用Variable()函数,此函数接受一个“张量”(tensor)作为输入,再输出变量;不过这才算完成声明,我们仍需要初始化这个变量。初始化时要把带有对应方法的变量放入到计算图中。下面是创建并进行初始化变量的例子:
my_var = tf.Variable(tf.zeros[2, 3])
sess = tf.Session()
initialize_op = tf.global_variables_initializer()
sess.run(initialize_op)

关于创建并初始化变量后计算图是什么样子的,这节的下一部分会有说明。
占位符只是为要“喂入”计算图的数据保留一个位置而已,它是从会话(session)的feed_dict参数取得数据的。把占位符放入计算图后,必须要对它进行至少一种操作。我们初始化图,把x声明为占位符,y定义为对x的恒等(identity)操作,也就是返回x;然后把数据“喂入”x占位符,再运行恒等操作,TensorFlow并不会在“喂入”字典(feed dictionary)中返回自引用的占位符。下面是代码,最终的计算图下一节会给出:
sess = tf.Session()
x = tf.placeholder(tf.float32, shape=[2, 2])
y = tf.identity(x)
x_vals = np.random.rand(2, 2)

sess.run(y, feed_dict={x: x_vals}) # 如果写成 sess.run(x, feed_dict={x: x_vals})会产生自引用的错误


如何工作...

下图中展示了将变量初始化为一个零张量的计算图

<TensorFlow Machine Learning Cookbook>学习笔记(1.4)

在上图中,我们可以看到变量初始化为全零的计算图的详细画面。灰色阴影区域详细说明了涉及到的操作及常量,灰色区域外的右上角则是稍为粗略的主要计算图。关于创建并将计算图进行可视化的更多说明,第10章第一节会讲到。

同样地,将一个numpy矩阵(array)“喂入”到占位符,可以在下面的图中看到:

<TensorFlow Machine Learning Cookbook>学习笔记(1.4)


更多...

在计算图运行过程中,我们必须告诉TensorFlow什么时候初始化创建的变量;TensorFlow也要知道什么时候可以初始化变量。每个变量都有initializer方法,最常用的方法是使用帮助函数,global_variables_initializer()。这个函数会在计算图中添加初始化我们创建的所有变量的操作:
initializer_op = tf.global_variables_initializer()
但是如果想根据另外一变量的初始化结果来初始化此变量,我们就必须按顺序来进行:
sess = tf.Session()
first_var = tf.Variable(tf.zeros([2, 3]))
sess.run(first_var.initializer())
second_var = tf.Variable(tf.zeros_like(first_var))
sess.run(second_var.initializer())
#依赖于第一个变量