首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从现有Tensorflow op的组合中创建新的Tensorflow op

如何从现有Tensorflow op的组合中创建新的Tensorflow op
EN

Stack Overflow用户
提问于 2018-01-25 13:14:13
回答 3查看 291关注 0票数 0

我知道在CPU上运行的how to use tf.py_func to create a new custom op。我还知道可以在C++中通过TF guide创建一个新的op及其渐变

我要找的都不是上面提到的。我想为TF运算的组合定义一个自定义梯度函数。tf.register_gradients可以与gradient_override_map一起使用来为现有op定义自定义渐变,但是如何将TF op的组合注册为新op呢?

类似的问题也被问到了here,但没有答案。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-03-03 03:03:24

我已经提供了在this repo的Tensorflow中定义自定义渐变的三种不同方法。

custom_gradient_with_py_func

在这种方法中,我们使用tf.py_func定义了一个tf op,并为其分配了一个自定义梯度函数。

代码语言:javascript
运行
复制
with g.gradient_override_map({"PyFunc": rnd_name}):
    return tf.py_func(func, inp, Tout, stateful=stateful, name=name)

custom_gradient_with_python:

在此方法中,我们使用变通方法为Tensorflow操作的组合定义自定义渐变。我们覆盖身份op的梯度。

代码语言:javascript
运行
复制
def python_func(x_in, name=None):
    with ops.name_scope(name):
        backward_func = tf.identity(x_in) # We'll later override the gradient of identity to deflect our desired gradient function.
        forward_func = tf.subtract(2 * tf.exp(x_in), x_in) 
        return backward_func + tf.stop_gradient(forward_func - backward_func) 

def my_op(func, inp, grad, name=None, victim_op='Identity'):
    # Need to generate a unique name to avoid duplicates.
    rnd_name = 'my_gradient' + str(np.random.randint(0, 1E+8))
    tf.RegisterGradient(rnd_name)(grad)
    g = tf.get_default_graph()
    with g.gradient_override_map({victim_op: rnd_name}):
        return func(inp, name=name)

custom_gradient_with_eager:

此方法使用TensorFlow1.5提供的tensorflow.contrib.eager为Tensorflow操作的组合定义自定义渐变。

代码语言:javascript
运行
复制
@tfe.custom_gradient
def python_func(x_in):
    def grad_func(grad):
        return grad * ((2 * tf.exp(x_in)) - 1)

    forward_func = tf.subtract(2 * tf.exp(x_in), x_in)
    return forward_func, grad_func
票数 0
EN

Stack Overflow用户

发布于 2018-01-26 04:34:39

tfe.custom_gradient是您想要使用的装饰器

票数 0
EN

Stack Overflow用户

发布于 2018-03-16 23:16:43

我不确定您是如何解决您的问题的,但上面解决方案中的名称'op_name‘和'some_name’不会显示在图表中。因此您将无法使用gradient_override_map({"op_name":"SynthGrad"})。

一种可能的解决方案:如果你在forwardpass中有一个自定义的tensorflow op x=f(a,b),但你想让它在backwardpass中表现为g(a,b),你可以这样做:

t=g(a,b) out=t+tf.stop_gradient(f(a,b)-t)

但是,您需要在C++中将g(a,b)定义为带名称的虚拟/标识操作符。稍后,您可以使用gradient_override_map。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48436073

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档