TensorFlow 随笔2 -- Session与其他

Session其他

Session.run()、Tensor.eval() 和 Operation.run()

tf 其实提供了非Session层面的run或者叫eval函数。分别位于Tensor类和Operation类中,他们虽然有的叫做run,有的叫做eval,但是其实功能都是execute。

对于一个系统的神经网络,我们是不推荐一步一步地使用后两者的,这会让系统很难懂而且不成体系,不过如果你使用ipython或者jupyter这样的交互式shell,或者用于debug神经网络,后两个可以一试。

一个典型的sample如下,因为不甚推荐,代码没有测试,直接从TensorFlow官网上面摘下,请各位自行品味:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Enter an interactive TensorFlow Session.
import tensorflow as tf
sess = tf.InteractiveSession()

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

# Initialize 'x' using the run() method of its initializer op.
x.initializer.run()

# Add an op to subtract 'a' from 'x'.  Run it and print the result
sub = tf.sub(x, a)
print(sub.eval())
# ==> [-2. -1.]

# Close the Session when we're done.
sess.close()

小内存电脑必备:Session.close()

对于一个session,tf会一直hold所占用的内存,DL的input一般都非常大,所以在进行完一次实验之后,尤其是interactive模式中,务必要把session关闭,再进行下一次实验,否则内存很有可能会爆掉。

Graph

上一篇中,虽然我们描述了Graph的概念并且说明有一个Graph类,也将Graph写入了tf的执行流程,但是例程代码中并没有Graph的相关东西。

这是因为我们没有显示指定Graph。

tf维护了一个默认的Graph,使用tf.get_default_graph() 可以得到该graph,在声明新的operation时,默认加入这个graph中,运行下面的代码可见一斑。

c = tf.constant(4.0)
assert c.graph is tf.get_default_graph()

如果需要显示声明graph,可以使用tf.Graph().as_default() 来进行显式graph声明一个default graph。

with tf.Graph().as_default() as g:
  c = tf.constant(5.0)
  assert c.graph is g

其实, graph有很多方法协助使用,但是在可以预见的未来,tf.Graph().as_default() 是足够用的。

详情可以参考:https://www.tensorflow.org/versions/r0.11/api_docs/python/framework.html#Graph

Placeholder

如前所言,TensorFlow有一系列抽象概念。当然不止于此。

在NN的设计中,很多时候你并不知道一个unit,或者按照tf的说法,一个op里面,数据究竟是是多少,但是你需要这个op摆在这里作为NN的结构的一部分,数据会流向这里,按照规则运算,再流出去。tf设计了一个叫做placeholder的op来做这件事。

placehodler就是一个没有数据的op,在执行前只需要将数据填进去才可以正常执行。填入数据的方法在tf中是以run函数的一个参数feed_dict的形式存在的:sess.run(y, feed_dict={x: rand_array})

一个最基本的例子:

x = tf.placeholder(tf.float32, shape=(1024, 1024))
y = tf.matmul(x, x)

with tf.Session() as sess:
  print(sess.run(y))  # ERROR: will fail because x was not fed.

  rand_array = np.random.rand(1024, 1024)
  print(sess.run(y, feed_dict={x: rand_array}))  # Will succeed.

placeholder只暴露了三个api函数,所以我们可以都讲一讲。

普通的placeholder

最基本的placeholder的prototype如下:

tf.placeholder(dtype, shape=None, name=None)
  • 如果shape没有指定,那么可以传入任意形状的tensor进来,如果shape被指定,形状不对的tensor会报错

带缺省值的placeholder

tf.placeholder_with_default(input, shape, name=None)
  • input是一个tensor类型,表示缺省值
  • 这个placeholder可以不feed,缺省使用input

稀疏数据的placeholder

最开始placeholder不支持稀疏矩阵,怨声载道,于是tf更新后支持了sparse matrix的形式,prototype如下:

tf.sparse_placeholder(dtype, shape=None, name=None)

用法如下:

x = tf.sparse_placeholder(tf.float32)
y = tf.sparse_reduce_sum(x)

with tf.Session() as sess:
  print(sess.run(y))  # ERROR: will fail because x was not fed.

  indices = np.array([[3, 2, 0], [4, 5, 1]], dtype=np.int64)
  values = np.array([1.0, 2.0], dtype=np.float32)
  shape = np.array([7, 9, 2], dtype=np.int64)
  print(sess.run(y, feed_dict={
    x: tf.SparseTensorValue(indices, values, shape)}))  # Will succeed.
  print(sess.run(y, feed_dict={
    x: (indices, values, shape)}))  # Will succeed.

  sp = tf.SparseTensor(indices=indices, values=values, shape=shape)
  sp_value = sp.eval(session)
  print(sess.run(y, feed_dict={x: sp_value}))  # Will succeed.
Comments
Write a Comment
  • chrysalis reply

    最后的一段代码中

    sp = tf.SparseTensor(indices=indices, values=values, shape=shape)

    sp_value = sp.eval(session)

    session应该是sess