更具体地说,我有一个简单的正向传播,它是由TensorFlow操作组成的。我想使用RegisterGradient来覆盖TensorFlow的梯度计算,用我自己的梯度方法。
这段代码有什么问题?
import tensorflow as tffrom tensorflow.python.framework import ops@ops.RegisterGradient("MyopGrad")def frop_grad(op, grad): x = op.inputs[0] return 0 * x # 置零以查看差异:def fprop(x): x = tf.sqrt(x) out = tf.maximum(x, .2) return outa = tf.Variable(tf.constant([5., 4., 3., 2., 1.], dtype=tf.float32))h = fprop(a)h = tf.identity(h, name="Myop")grad = tf.gradients(h, a)g = tf.get_default_graph()with g.gradient_override_map({'Myop': 'MyopGrad'}): with tf.Session() as sess: sess.run(tf.initialize_all_variables()) result = sess.run(grad)print(result[0])
我想在打印中看到全是零,但实际上我得到的是:
[ 0.2236068 0.25000003 0.28867513 0.35355341 0.5 ]
回答:
你需要在with g.gradient_override_map({'Myop': 'MyopGrad'})
的范围内定义操作。
另外,你需要将Identity
而不是Myop
映射到你的新梯度。
这是完整的代码:
import tensorflow as tffrom tensorflow.python.framework import ops@ops.RegisterGradient("MyopGrad")def frop_grad(op, grad): x = op.inputs[0] return 0 * x # 置零以查看差异:def fprop(x): x = tf.sqrt(x) out = tf.maximum(x, .2) return outa = tf.Variable(tf.constant([5., 4., 3., 2., 1.], dtype=tf.float32))h = fprop(a)g = tf.get_default_graph()with g.gradient_override_map({'Identity': 'MyopGrad'}): h = tf.identity(h, name="Myop") grad = tf.gradients(h, a)with tf.Session() as sess: sess.run(tf.initialize_all_variables()) result = sess.run(grad)print(result[0])
输出:
[ 0. 0. 0. 0. 0.]