如何为由tf操作组成的操作注册自定义渐变

goo*_*ict 11 python machine-learning tensorflow

更具体地说,我有一个简单的fprop,它是tf操作的组合.我想使用RegisterGradient使用我自己的渐变方法覆盖tensorflow梯度计算.

这段代码出了什么问题?

import tensorflow as tf
from tensorflow.python.framework import ops

@ops.RegisterGradient("MyopGrad")
def frop_grad(op, grad):
    x = op.inputs[0]
    return 0 * x  # zero out to see the difference:

def fprop(x):
    x = tf.sqrt(x)
    out = tf.maximum(x, .2)
    return out

a = 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])
Run Code Online (Sandbox Code Playgroud)

我想看到印刷品中的所有零,但我得到:

[ 0.2236068   0.25000003  0.28867513  0.35355341  0.5       ]
Run Code Online (Sandbox Code Playgroud)

MZH*_*ZHm 11

您需要在范围内定义op with g.gradient_override_map({'Myop': 'MyopGrad'})

此外,您需要Identity将名称而不是名称映射Myop到新渐变.

这是完整的代码:

import tensorflow as tf
from tensorflow.python.framework import ops

@ops.RegisterGradient("MyopGrad")
def frop_grad(op, grad):
    x = op.inputs[0]
    return 0 * x  # zero out to see the difference:

def fprop(x):
    x = tf.sqrt(x)
    out = tf.maximum(x, .2)
    return out

a = 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])
Run Code Online (Sandbox Code Playgroud)

输出:

[ 0.  0.  0.  0.  0.]
Run Code Online (Sandbox Code Playgroud)

  • 这不是为身份op而不是fprop函数定义自定义渐变函数吗?如果你没有将x乘以零,你将看不到[5.,4.,3.,2.,1.],而是你会看到identity()op的输入. (4认同)