eager怎么读英语 eager


eager怎么读英语 eager

文章插图
图:pixabay
原文来源:Google Brain
作者:Asim Shankar 、 Wolff Dobson
「雷克世界」编译:嗯~阿童木呀
今天,我们在TensorFlow中引入了Eager Execution 。Eager Execution是一个命令式、运行定义式的接口,其中,操作一旦从Python中调用便立刻得以执行 。这样TensorFlow的入门使用就变得相对简单,并可以使研究和开发过程更为直观 。
使用Eager Execution的益处包括以下几点:
?具有面对即时运行错误的快速调试和Python工具的集成 。
?支持使用易用的Python控制流的动态模型 。
?大力支持自定义的、高阶梯度 。
?适用几乎所有可用的TensorFlow操作 。
现在,eager可作为一个实验性特征,所以我们正在寻求来自社区的反馈意见,以指导我们的研究方向 。
为了更好地理解这一点,我们可以看一些相关代码,这就非常具有技术性了,而且如果熟悉TensorFlow的话也将会有所帮助 。
使用Eager Execution
一旦你启用Eager Execution,操作将立即得以执行,并将其值返回给Python,而不需要调用Session.run() 。例如,将两个矩阵相乘,代码为:
importtensorflow as tf
importtensorflow.contrib.eager as tfe
tfe.enable_eager_execution()
x = [[2.]]
m = tf.matmul(x, x)
使用print或Python调试器来检查中间结果其实是很简单的 。
print(m)
# The 1x1 matrix [[4.]]
可以使用Python控制流来构建动态模型 。下面是使用TensorFlow算术运算构建考拉兹猜想(Collatz conjecture)的一个示例:
a = tf.constant(12)
counter = 0
while not tf.equal(a, 1):
iftf.equal(a % 2, 0):
a = a / 2
else:
a = 3 * a + 1
print(a)
其中,tf.constant(12)张量对象的使用可以促进将所有的数学运算提升到张量运算中,因此所有返回值都将是张量 。
梯度
大多数TensorFlow用户都对自动微分法(automatic differentiation)感兴趣 。因为在每个调用期间可能会出现不同的操作,所以我们将所有的前向操作记录到一个磁带上,然后在计算梯度时回放 。一旦我们计算好梯度之后,就可以将磁带丢弃 。
如果你对autograd包非常熟悉的话,那就很简单了,因为API与它是很相似的 。例如:
def square(x):
returntf.multiply(x, x)
grad = tfe.gradients_function(square)
print(square(3.)) # [9.]
print(grad(3.)) # [6.]
gradients_function调用使用Python函数square()作为参数,并返回一个Python可调用的函数,用以计算函数square()相对于其输入的偏导数 。所以,为了得到输入为3.0时的square()的导数,调用grad(3.0),即结果为6 。
可以使用相同的gradients_function调用以得到square的二阶导数:
gradgrad = tfe.gradients_function(lambda x: gra
d(x)[0])
print(gradgrad(3.)) # [2.]
正如我们所说,控制流可以导致不同的操作得以运行,正如在这个例子中显示的那样:
def abs(x):
return x if x > 0. else -x
grad = tfe.gradients_function(abs)
print(grad(2.0)) # [1.]
print(grad(-2.0)) # [-1.]
自定义梯度
用户可能希望为操作或函数自定义梯度 。如果从多方面考虑的话,这可能会是有益的,包括为一系列操作提供一个更有效或数值更稳定的梯度 。
下面是一个示例,说明了自定义梯度的使用 。我们先看看函数log(1 + ex),它通常出现在交叉熵和对数似然值(log likelihoods)的计算中 。
def log1pexp(x):
return tf.log(1 + tf.exp(x))
grad_log1pexp = tfe.gradients_function(log1pexp
)
# The gradient computation works fine at x = 0.
print(grad_log1pexp(0.))
# [0.5]
# However it returns a `nan` at x = 100 due to
numerical instability.
print(grad_log1pexp(100.))
# [nan]
我们可以使用上述函数的自定义梯度来分析简化梯度表达式 。需要注意的是,下面的梯度函数实现是如何重用在正向传递期间得以计算的表达式(tf.exp(x))的,通过避免冗余计算使得梯度计算更加高效 。
@tfe.custom_gradient
def log1pexp(x):
e = tf.exp(x)
def grad(dy):
returndy * (1 - 1 / (1 + e))
return tf.log(1 + e), grad
grad_log1pexp = tfe.gradients_function(log1pexp
)
# Gradient at x = 0 works as before.
print(grad_log1pexp(0.))
# [0.5]
# And now gradient computation at x=100 works a
s well.
print(grad_log1pexp(100.))
# [1.0]
构建模型
模型可以在类中进行组织 。下面是一个模型类,它创建一个(简单的)双层网络,可以对标准的MNIST手写数字进行分类 。

秒懂生活扩展阅读