Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zero mean intensity of gradient for some cases #25

Open
HRKpython opened this issue Nov 1, 2018 · 9 comments
Open

zero mean intensity of gradient for some cases #25

HRKpython opened this issue Nov 1, 2018 · 9 comments

Comments

@HRKpython
Copy link

I am using Keras with tensorflow backend and I have fine-tuned the last Conv layer and FC layer of my network based on VGG weights. Now I am using grad-CAM technique to visualize which parts of my image triggered the prediction and I get all zeros for mean intensity of the gradient over a specific feature map channel.

I have 4 classes, for my test sample these are the prediction:

preds_sample = model.predict(x)
output>> array([[1., 0., 0., 0.]], dtype=float32)

# This is the "sample image" entry in the prediction vector    
image_0 = model.output[:, 0]

last_conv_layer = model.get_layer('conv2d_13')
grads = K.gradients(toilet_w, last_conv_layer.output)[0]
grads.shape
output>> TensorShape([Dimension(None), Dimension(512), Dimension(14), Dimension(14)])

Since I am using theano image ordering - when I calculate the mean of grads my axis is (0,2,3)

from keras import backend as K
K.set_image_dim_ordering('th')

pooled_grads = K.mean(grads, axis=(0,2,3))
pooled_grads.shape
output>> TensorShape([Dimension(512)])

iterate = K.function([model.input], [pooled_grads, last_conv_layer.output[0]])
pooled_grads_value, conv_layer_output_value = iterate([x])
pooled_grads_value.shape, conv_layer_output_value.shape
output>> ((512,), (512, 14, 14))

pooled_grads_value is all zero

Reference: https://github.com/fchollet/deep-learning-with-python-notebooks/blob/master/5.4-visualizing-what-convnets-learn.ipynb

I tested the algorithm with more images and found out it works for some of the images. Then I noticed that I have a dropout layer after my last conv layer. I did more research #2 and modified the code as:

last_conv_layer = model.get_layer('conv2d_13')
grads = K.gradients(sample_output, last_conv_layer.output)[0]

# normalization trick: we normalize the gradient
#grads = normalize_grad(grads)

pooled_grads = K.mean(grads, axis=(0, 2, 3))
iterate = K.function([model.input, K.learning_phase()], [pooled_grads, last_conv_layer.output[0]])

pooled_grads_value, conv_layer_output_value = iterate([x, 0])

But Still for some of the images all pooled_grads are zeros.

@hequn
Copy link

hequn commented Nov 9, 2018

I got the same problem and haven't solved it yet (¦3」∠)

@hequn
Copy link

hequn commented Nov 19, 2018

I did solve my error for the case that i did not choose the right layer output as the target.

@janphhe
Copy link

janphhe commented Dec 6, 2018

What layer did you take? Or what is the correct layer?

@hequn
Copy link

hequn commented Dec 10, 2018

@janphhe In my project, I used Xception. The target layer will be the global_avg_pooling layer, we should get a vector which seemed to be flattened. The grad visualization was made on it.

@surfaniac
Copy link

Somebody has a solution for this. I get the same issue with a VGG19 network :/ I appreciate every help! Thanks a lot!

@Ada-Nick
Copy link

Ada-Nick commented Mar 30, 2020

I'm having the same problem, i'm sure I have selected the correct conv layer as it works for some images and not others. I'm not using a pre-trained model.

EDIT: Change to using Leaky-relu activations to prevent the vanishing gradient problem has solved it for me, all though this probably isn't easy with pre-trained networks

@andreimargeloiu
Copy link

@Ada-Nick, can you please give more details about your solution/intuition?

@Ada-Nick
Copy link

@margiki Leaky-relu allows the gradient of negative values to be non-zero, preventing pooled_grads from being a null-matrix

@andreimargeloiu
Copy link

In my case, using LeakyReLU didn't solve the issue.

I delved deeper and found that the gradients computed by GradCAM were actually negative. Then, GradCAM applies a ReLU and the result was an empty map.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants