如何在Tensorflow 2.0中应用Guided BackProp?

时间:2019-04-30 15:33:49

标签: python tensorflow keras backpropagation tensorflow2.0

我从foo_copy Base copy Derived destruction Flag: true Base destruction Base destruction foo_move Base move Derived destruction Flag: false Base destruction Base destruction 开始,尝试实现Guided BackProp来显示Saliency Map。我首先计算图像Tensorflow 2.0y_pred之间的损耗,然后查找由于该损耗而引起的所有图层的梯度。

y_true

但是,我不知道如何使用渐变来获得引导传播。

这是我的模特。我使用Keras图层创建了它:

with tf.GradientTape() as tape:
    logits = model(tf.cast(image_batch_val, dtype=tf.float32))
    print('`logits` has type {0}'.format(type(logits)))
    xentropy = tf.nn.softmax_cross_entropy_with_logits(labels=tf.cast(tf.one_hot(1-label_batch_val, depth=2), dtype=tf.int32), logits=logits)
    reduced = tf.reduce_mean(xentropy)
    grads = tape.gradient(reduced, model.trainable_variables)

很高兴在需要时提供更多代码。

2 个答案:

答案 0 :(得分:3)

首先,您必须通过ReLU(即Guided BackProp Formula

来更改梯度的计算

下面是paper中的图形示例。Graphical example

可以使用以下代码实现此公式:

@tf.RegisterGradient("GuidedRelu")
def _GuidedReluGrad(op, grad):
   gate_f = tf.cast(op.outputs[0] > 0, "float32") #for f^l > 0
   gate_R = tf.cast(grad > 0, "float32") #for R^l+1 > 0
   return gate_f * gate_R * grad

现在,您必须使用以下方法覆盖ReLU的原始TF实现:

with tf.get_default_graph().gradient_override_map({'Relu': 'GuidedRelu'}):
   #put here the code for computing the gradient

计算梯度后,您可以可视化结果。 但是,最后一句话。您可以为单个类计算可视化效果。这意味着,您将激活所选神经元,并将其他神经元的所有激活都设置为零作为Guided BackProp输入。

答案 1 :(得分:1)

我按照@Simdi的建议尝试了@tf.RegisterGradientgradient_override_map,但对TF2无效。我不确定在任何步骤上我是否都错了,但是看来Relu并没有被GuidedRelu取代。我认为这是因为:“ TensorFlow 2.0中没有内置机制可以覆盖作用域内内置运算符的所有梯度。” mrry在本讨论中得到的答复:https://stackoverflow.com/a/55799378/11524628

我按照@tf.custom_gradient的说法使用mrry,它对我来说非常合适:

@tf.custom_gradient
def guidedRelu(x):
  def grad(dy):
    return tf.cast(dy>0,"float32") * tf.cast(x>0, "float32") * dy
  return tf.nn.relu(x), grad

model = tf.keras.applications.resnet50.ResNet50(weights='imagenet', include_top=True)
gb_model = Model(
    inputs = [model.inputs],
    outputs = [model.get_layer("conv5_block3_out").output]
)
layer_dict = [layer for layer in gb_model.layers[1:] if hasattr(layer,'activation')]
for layer in layer_dict:
  if layer.activation == tf.keras.activations.relu:
    layer.activation = guidedRelu

with tf.GradientTape() as tape:
  inputs = tf.cast(preprocessed_input, tf.float32)
  tape.watch(inputs)
  outputs = gb_model(inputs)

grads = tape.gradient(outputs,inputs)[0]

您可以在此Google Colab笔记本中使用上述两种方法查看实施:https://colab.research.google.com/drive/17tAC7xx2IJxjK700bdaLatTVeDA02GJn?usp=sharing

  • @tf.custom_gradient有效
  • @tf.RegisterGradient不能正常工作,因为relu没有被注册的GuidedRelu覆盖。