首页 文章

TensorFlow中的引导反向传播

提问于
浏览
7

我想在TensorFlow中实现在Paper中引入"Guided back-propagation"的技术,并在recipe中进行了描述 .

计算上意味着当我计算例如输入wrt的梯度时 . NN的输出,我将 modify the gradients computed at every RELU unit . 具体地说,这些单元上的反向传播信号必须在零上设置阈值,以使该技术起作用 . 换句话说,必须忽略RELU的负偏导数 .

鉴于我有兴趣仅在测试示例中应用这些梯度计算,即,我没有参数 - 我该怎么做?

到目前为止,我尝试过两件事(不成功):

  • 使用 tf.py_func 来包装我的简单numpy版本的RELU,然后有资格通过 g.gradient_override_map 上下文管理器重新定义它的渐变操作 .

  • 收集BackProp的前向/后向值,并对源自Relus的那些值应用阈值 .

我用这两种方法都失败了,因为它们需要一些目前我没有的TF内部知识 .

任何人都可以建议任何其他路线,或草拟代码?

非常感谢 .

2 回答

  • 5

    tf.gradients 具有可用于此目的的 grad_ys 参数 . 假设您的网络只有一个 relu 层,如下所示:

    before_relu = f1(inputs, params)
    after_relu = tf.nn.relu(before_relu)
    loss = f2(after_relu, params, targets)
    

    首先,计算导数到 after_relu .

    Dafter_relu = tf.gradients(loss, after_relu)[0]
    

    然后对您发送的渐变进行阈值处理 .

    Dafter_relu_thresholded = tf.select(Dafter_relu < 0.0, 0.0, Dafter_relu)
    

    将实际梯度w.r.t计算为 params .

    Dparams = tf.gradients(after_relu, params, grad_ys=Dafter_relu_thresholded)
    

    您可以轻松地为具有许多 relu 层的网络扩展此相同方法 .

  • 5

    使用ops.RegisterGradienttf.Graph.gradient_override_map 的更好的解决方案(您的方法1) . 它们一起覆盖预定义Op的梯度计算,例如:仅使用python代码在 gradient_override_map 上下文中重新调用 .

    @ops.RegisterGradient("GuidedRelu")
    def _GuidedReluGrad(op, grad):
        return tf.where(0. < grad, gen_nn_ops._relu_grad(grad, op.outputs[0]), tf.zeros(grad.get_shape()))
    
    ...
    with g.gradient_override_map({'Relu': 'GuidedRelu'}):
        y = tf.nn.relu(x)
    

    这是引导relu的完整示例实现:https://gist.github.com/falcondai/561d5eec7fed9ebf48751d124a77b087

    Update :在Tensorflow> = 1.0中, tf.select 被重命名为 tf.where . 我相应更新了代码段 . (感谢@sbond将此引起我的注意:)

相关问题