tf.gradients,如何理解和使用`grad_ys`?

时间:2018-06-21 11:49:16

标签: tensorflow

tf.gradients中,有一个关键字参数grad_ys

  

grad_ys是与ys相同长度的张量列表,其中包含y中每个ys的初始梯度。当grad_ys为None时,我们为y中的每个y填充一个ys形状的'1'张量。用户可以提供自己的初始grad_ys来为每个y使用不同的初始梯度来计算导数(例如,如果要为每个y中的每个值不同地加权梯度)。

为什么这里需要grads_ys?这里的文档是隐式的。您能提供一些具体的用途和代码吗?

我的tf.gradients示例代码是

In [1]: import numpy as np

In [2]: import tensorflow as tf

In [3]: sess = tf.InteractiveSession()

In [4]: X = tf.placeholder("float", shape=[2, 1])

In [5]: Y = tf.placeholder("float", shape=[2, 1])

In [6]: W = tf.Variable(np.random.randn(), name='weight')

In [7]: b = tf.Variable(np.random.randn(), name='bias')

In [8]: pred = tf.add(tf.multiply(X, W), b)

In [9]: cost = 0.5 * tf.reduce_sum(tf.pow(pred-Y, 2))

In [10]: grads = tf.gradients(cost, [W, b])

In [11]: sess.run(tf.global_variables_initializer())

In [15]: W_, b_, pred_, cost_, grads_ = sess.run([W, b, pred, cost, grads], 
                                    feed_dict={X: [[2.0], [3.]], Y: [[3.0], [2.]]})

1 个答案:

答案 0 :(得分:1)

grad_ys仅在高级用例中需要。这是您可以考虑的方式。

tf.gradients允许您计算tf.gradients(y, x, grad_ys) = grad_ys * dy/dx。换句话说,grad_ys是每个y的乘数。在这种表示法中,提供这种说法似乎很愚蠢,因为一个人应该只能自我复活,即tf.gradients(y, x, grad_ys) = grad_ys * tf.gradients(y, x)。不幸的是,这种相等性不成立,因为当向后计算梯度时,我们在每一步之后执行还原(通常是求和)以获得“中间损失”。

此功能在许多情况下可能很有用。 doc字符串中提到了一个。这是另一个。记住连锁规则-dz/dx = dz/dy * dy/dx。假设我们想计算dz/dx,但dz/dy是不可微的,我们只能对其进行近似。假设我们以某种方式计算了近似值,并将其称为approx。然后,dz/dx = tf.gradients(y, x, grad_ys=approx)

另一个用例是当您的模型带有“巨大扇入”时。假设您有100个输入源,它们经过几层(称为“ 100个分支”),在y处合并,再经过10层,直到到达loss。可能无法立即计算整个模型的所有梯度(这需要记住许多激活)。一种方法是首先计算d(loss)/dy。然后,使用branch_i计算loss中变量tf.gradients(y, branch_i_variables, grad_ys=d(loss)/dy)的梯度。使用这个(以及我跳过的更多详细信息),可以减少峰值内存需求。