Closed hnguyentt closed 4 years ago
Should be either conv5_block3_3_conv/BiasAdd:0
or conv5_block3_out/add:0
. Can print out the shapes to verify which one.
Both of them have shape (<num of samples>, 7, 7, 2048)
. They match the shape with the architecture in your document: https://github.com/lindawangg/COVID-Net/blob/master/assets/COVIDNet_CXR.pdf
@nguyenhoa93 , did you finally managed to run Grad-Cam? I have tried to implement it, but it seems GradientTape does not register operations runs with Session.run
with tf.GradientTape() as tape:
tape.watch(image_tensor)
pred = sess.run(pred_tensor, feed_dict={image_tensor: np.expand_dims(x, axis=0)})
convOutputs = sess.run(conv_op, feed_dict={image_tensor: np.expand_dims(x, axis=0)})
loss = pred[:, np.argmax(pred[0])]
If I print the watched variables, there is no variables watched, so grads = tape.gradient(loss, convOutputs)
returns none. However loss and convOutputs have data.
What confuses me is that those variables are numpy arrays instead of tensors.
I am pretty new to tensorflow and a bit lost yet. I'll appreciate any help.
@borjaMinano tf.GradientTape()
is applicable for Tensorflow 2. The model was trained with TensorFlow v 1.x`. Did you retrain the model with TF 2.?
Edit: After reading @haydengunraj 's comment, I read again the document of tf.GradientTap() and realized that it's available in Eager Execution - TF 1.15 as well. Like @haydengunraj said, we need to sess.run()
to get the values.
First, define last_conv_tensor
and grads_tensor
:
lass_conv_tensor = graph.get_tensor_by_name(<last_conv_layer_tensor_name>)
with tf.GradientTape() as tape:
tape.watch(image_tensor)
one_hot = tf.sparse_to_dense(classIdx, [len(self.classes)], 1.0)
signal = tf.multiply(graph.get_tensor_by_name(<output_tensor_name>),one_hot)
loss_tensor = tf.reduce_mean(signal)
grads_tensor = tape.gradient(loss_tensor, last_conv_tensor)
last_conv, grads = sess.run([last_conv_tensor, grad_tensors], feed_dict={image_tensor: np.expand_dims(x, axis=0)})
I did the activation map already but want to make sure that I select the last convolutional layer correctly. You can see my code here: https://gist.github.com/nguyenhoa93/d49564875234f6722ff89e65db34a00b To run the code you should create a json file with the keys:
{
"weightspath": ,
"metaname": ,
"ckptname": ,
"input_tensor": "input_1:0",
"output_tensor": "dense_3/Softmax:0",
"final_conv_tensor": "conv5_block3_out/add:0",
"input_size":
"top_percent":
}
I took conv5_block3_out/add:0
as final_conv_tensor
.
This is the GradCAM result of COVID-19 when the model predict the image as COVID-19.
@borjaMinano I don't have much experience with Grad-CAM, but the main issue in the code snippet you posted above is more of a general Tensorflow thing. When you use session.run()
, you are running the operation in the graph, and Tensorflow returns the result as a numpy array. That numpy array is completely separate from the Tensorflow graph, so calling tape.gradient(loss, convOutputs)
does nothing. You need to pass Tensorflow Tensors to tape.gradient()
, which should return a gradient Tensor that you can then compute using session.run()
.
TL;DR, you need to do something like:
with tf.GradientTape() as tape:
tape.watch(image_tensor)
loss_tensor = ...define your loss tensor here
grad_tensor = tape.gradient(loss_tensor, conv_op)
grads = sess.run(grad_tensor, feed_dict={image_tensor: np.expand_dims(x, axis=0)})
Thank you very much for your help. I adapted @nguyenhoa93 code and get it finally working.
My pleasure, @borjaMinano Happy to hear that it worked for you.
hi @nguyenhoa93 i was referring your code
on line no. 144 what is 'im' ? im_name = im.split("/")[-1])
I got below error : im_name = (im.split("/")[-1]) NameError: name 'im' is not defined
thanks
@ankitdata it should be args.impath.split(“/“)[-1]
I editted here: https://gist.github.com/nguyenhoa93/d49564875234f6722ff89e65db34a00b#file-covid-net-gradcam-py-L144-L145
Thanks @nguyenhoa93, it worked for me.
Any idea what will be the 'final convolutional layer tensor' for Model: COVIDNet-CXR3-A with following inputs
{
"input_tensor": "input_1:0",
"output_tensor": "**norm_dense_1/Softmax:0**",
"final_conv_tensor": " ? ",
}
I checked tensors with below code
tensors = [t.name for op in tf.get_default_graph().get_operations() for t in op.values()]
for t in tensors:
print(t)
which tensor will work from the list ? @lindawangg @nguyenhoa93
Thanks
@ankitdata
I am not sure because I didn't build the network. For COVIDNet-CXR3-A, I guess: conv_7b/convolution:0
@nguyenhoa93
Do you have any plan to build network for COVIDNet-CXR3-A ? If you build, please share the heatmap here.
thanks .
@nguyenhoa93
Do you have any plan to build network for COVIDNet-CXR3-A ? If you build, please share the heatmap here.
thanks .
You can use the same code that I shared and change the name of final conv to conv_7b/convolution:0
. Input size (480, 480, 3).
The code will work for all TensorFlow models (TF 1.15).
Hi @nguyenhoa93
I tried with 3 models (small ,Large & COVIDNet-CXR3-A) heatmaps i shared below
in ' COVIDNet-CXR3-A' I used conv_7b/convolution:0
and Input size (480, 480, 3)
but heatmap in not correct and prediction is Pneumonia.
for model COVIDNet-CXR3-A sensitivity is
Normal: 0.000, Pneumonia: 0.530, COVID-19: 0.470
for small model and large model sensitivity is higher for COVID-19 so prediction is COVID-19
what is your suggestion on this ? let me know if you get more accuracy in heatmap for COVIDNet-CXR3-A.
Heatmaps predictions for : COVIDNet-CXR Small - COVID-19 COVIDNet-CXR Large - COVID-19 COVIDNet-CXR3-A - Pneumonia
input-image - assets/ex-covid.jpeg thanks
@ankitdata , I tried with the three new models (and also with Large model) and I see the same detection problem with model-A, but not with models B and C, even though the heatmaps are different from Large model. I think the Large model's heatmap is the most accurate, watching at the raw image.
Model B
Model C
@nguyenhoa93 Hello! I was wondering if you had done this with model: COVIDNet-CXR4-A
The naming convention for the convolutional layers seems quite different and I was wondering what to use for the final conv layer name. any help would be so much appreciated! Thank you.
using @nguyenhoa93 gradcam code these are the results I get using these input specifications:
using model COVIDNet-CXR4-A from: https://github.com/lindawangg/COVID-Net/blob/master/docs/models.md
{ "weightspath": "path/to/models/COVIDNet-CXR4-A", "metaname":"model.meta" , "ckptname":"model-18540" , "input_tensor": "input_1:0", "output_tensor": "norm_dense_1/Softmax:0", "final_conv_tensor": "conv2d_203/convolution:0", "input_size": 480, "top_percent": .08, }
using this model
running on image: /data/test/0088be53-27f2-4c30-882b-a73a3a5c8c71.png
I get these results
Pneumonia
Normal
COVID-19
It could be that my final convolutional layer name is incorrect, can anyone verify? @lindawangg @haydengunraj
EDIT:
ok so I also tried it with:
{ "weightspath": "path/to/models/COVIDNet-CXR4-A", "metaname":"model.meta" , "ckptname":"model-18540" , "input_tensor": "input_1:0", "output_tensor": "norm_dense_1/Softmax:0", "final_conv_tensor": "conv_7b/convolution:0", "input_size": (480,480,3), "top_percent": .08, }
and actually got some result that looks like an actual heatmap, but I just wanted to confirm that "conv_7b/convolution:0" is the final conv layer and the correct layer for computing gradcams in model COVIDNet-CXR4-A? @lindawangg @haydengunraj @nguyenhoa93
@ankitdata , I tried with the three new models (and also with Large model) and I see the same detection problem with model-A, but not with models B and C, even though the heatmaps are different from Large model. I think the Large model's heatmap is the most accurate, watching at the raw image.
Model B
Model C
@borjaMinano what tensornames did you use for final_conv_tensor for the models CXR3 B and C because they seem to be named different from CXR3 A
Hi Ankit,
Is there any way for you to confirm the layers I posted about and whether they are the final conv layers? I also asked a question in another issue about the training tensors for the small and large models. It would be extremely helpful.
Best, Robbie Sadre
On Sun, Jan 3, 2021 at 10:50 AM Ankit Chilkalwar notifications@github.com wrote:
Thanks for sharing this information.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/lindawangg/COVID-Net/issues/64#issuecomment-753660384, or unsubscribe https://github.com/notifications/unsubscribe-auth/AP7YI3TDWTJFZ57C7WJH7WDSYC37LANCNFSM4NBAZGCQ .
Hi Ankit, Is there any way for you to confirm the layers I posted about and whether they are the final conv layers? I also asked a question in another issue about the training tensors for the small and large models. It would be extremely helpful. Best, Robbie Sadre … On Sun, Jan 3, 2021 at 10:50 AM Ankit Chilkalwar @.***> wrote: Thanks for sharing this information. — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#64 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AP7YI3TDWTJFZ57C7WJH7WDSYC37LANCNFSM4NBAZGCQ .
For Large Model: input tensorname = 'input_1:0', type=str output tensorname = 'dense_3/Softmax:0'
final conv layer for heatmaps conv5_block3_out/add:0
if you want list all tensors use below code. tensors = [t.name for op in tf.get_default_graph().get_operations() for t in op.values()] for t in tensors: print(t)
I am not sure on sharing information about small model.
thanks.!
Hello,
Thank you for sharing your work! I am trying to make the activation map to see the important features from your two trained models (COVIDNet-CXR Small and COVIDNet-CXR Large). To do that I would like to know the name of the final convolutional layer tensor. I have checked your document train_eval_inference.md but have found that tensor name.
I listed all tensor names in your models by this code:
And this is a subset of the tensor names:
Based on that, I guess the final convolutional layer tensor is
conv5_block3_out/add:0
and make the activation map based on that.To confirm what I have done, my question: Is the final convolutional layer tensor is actually
conv5_block3_out/add:0
?Thank you for your time.