在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.]]})
答案 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)
的梯度。使用这个(以及我跳过的更多详细信息),可以减少峰值内存需求。