TensorFlow中的命令式编程
机器之心报道
参与:晏奇
在标准TensorFlow库中,计算规范根据计算图静态地完成,并且它与计算图地执行相分离。这个编程地模型被称为lazy、deferred、dynamic或者asynchronous。 这个库将命令式编程方法(地址为:http://www.numpy.org/)引入了TensorFlow。使用该库你可以:
以命令式编写代码:系统每执行一行代码就会得到一个可用的结果。
在tensors上使用TensorFlow运算,获得所有GPU加速的好处。
可以当编写计算过程时,可以插入任意Python控制流语句如while 和 if。
用标准 tf.gradients (https://www.tensorflow.org/api_docs/python/train/gradient_computation#gradients) 函数在你的代码上执行自动微分。(函数地址:https://www.tensorflow.org/api_docs/python/train/gradient_computation#gradients)
开始
这个库是对标准TensorFlow Python库的一个简单包装。源代码在以下地址:https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/imperative 。你可以通过在Linux上安装链接GitHub主页的nightly PIP包来开始。其它平台请参阅这份文档(https://github.com/tensorflow/tensorflow#installation) ,PIP包也支持GPU。
写下你的第一个命令式TensorFlow程序
$ python
>>> import tensorflow.contrib.imperative as tf>>> x = tf.constant([[7.], [6]])>>> y = tf.constant([[6., 7]])>>> tf.matmul(x, y)
array([[ 42., 49.],
[ 36., 42.]], dtype=float32)
请注意,这个代码与就程序员对下述NumPy代码的思维模型而言是相同的。
>>> import numpy as np>>> x = np.array([[7.], [6]])>>> y = np.array([[6., 7]])>>> x.dot(y)
array([[ 42., 49.],
[ 36., 42.]])
该库以import tensorflow.contrib.imperative as tf 导入(它与导入TensorFLow的 import tensorflow as tf不同)。这个导入申明让所有标准TensorFlow可用于 tf 记号。然而,不必须要创建会话对象,并设置它来运行和获取张量。
特征
该库提供标准TensorFlow之上的如下进一步特征:
当张量被在预测其值的文本中使用时,会被自动获取。
打印
x = tf.constant(10)
y = tf.constant(32)print(x + y)42
使用条件语句
x = tf.constant(30)if x > 4:
print('Greater than 4')
Greater than 4
x = tf.random_normal([3])
y = x * 2while tf.global_norm([y]) < 1000:
y = y * 2print(y)
[ -213.2868042 -511.02456665 1026.66882324]
变量自动初始化,不需要运行tf.global_variables_initializer() 操作。
梯度如预期地使用标准tf.gradients函数工作。
x = tf.Variable(np.random.rand(1, 3))
y = tf.exp(x)
dy = tf.gradients(y, x)# dy/dx should be equal to y (= exp(x))print(y, dy)
(array([[ 1.79997761, 2.00581881, 2.37302414]]), [array([[ 1.79997761, 2.00581881, 2.37302414]])])
注意事项
该库是在标准TensorFlow顶层之上的实现。它依然在后台建了一个计算图,并按照操作执行。但是当一个操作第一次执行时,其结果会被放入缓存,并且缓存值会被返回以用于以后执行,因此它提供了必要的语义。由于这个实现选项,该库存在以下注意事项:
使用内部Python循环:建立一个计算图,并将其保留在后台,一方面是为了执行使用标准TensorFlow运行时间,另一方面是通过 tf.gradients允许自动微分。这意味着当TensorFlow函数被Python循环内部调用时,计算图会持续增长。这个库提供了一个 tf.new_step 方法,它可以清除计算图和缓存中一直保存的用于梯度计算的张量。 tf.new_step可以被用上下文管理,例如,一个在每一次计算步骤之后清除计算图的训练循环。
x = tf.Variable(constant_op.constant(1.0))for i in range(10):
# Create a new training stepwith tf.new_step() as step:
# Perform computation and variable updates
step.run(tf.assign_sub(x, 0.1))
self.assertAllClose(tf.identity(x), 1.0 - (i + 1) * 0.1)
# The graph within this context is cleared at this point.
速度:冗余的计算图构造和冗余的张量值缓存会增加开销,这些开销在标准TensorFlow中并不存在。在标准TensorFlow中,典型的计算图会被构建一次,操作数次。我们开发该库的目的是为了让其作为实现TensorFlow命令式编程模型原型的媒介渠道。通过对也将同样有利于延迟执行模式的运行时间大量的优化,运行时间的开销可以被降低。