11import torch
22from .backprop import VanillaGradExplainer
33
4-
54def _get_layer (model , key_list ):
65 if key_list is None :
76 return None
87
98 a = model
109 for key in key_list :
1110 a = a ._modules [key ]
11+
1212 return a
1313
1414class GradCAMExplainer (VanillaGradExplainer ):
@@ -18,45 +18,47 @@ def __init__(self, model, target_layer_name_keys=None, use_inp=False):
1818 self .use_inp = use_inp
1919 self .intermediate_act = []
2020 self .intermediate_grad = []
21+ self .handle_forward_hook = None
22+ self .handle_backward_hook = None
2123 self ._register_forward_backward_hook ()
2224
2325 def _register_forward_backward_hook (self ):
2426 def forward_hook_input (m , i , o ):
2527 self .intermediate_act .append (i [0 ].data .clone ())
26-
28+
2729 def forward_hook_output (m , i , o ):
2830 self .intermediate_act .append (o .data .clone ())
29-
31+
3032 def backward_hook (m , grad_i , grad_o ):
3133 self .intermediate_grad .append (grad_o [0 ].data .clone ())
3234
3335 if self .target_layer is not None :
3436 if self .use_inp :
35- self .target_layer .register_forward_hook (forward_hook_input )
37+ self .handle_forward_hook = self . target_layer .register_forward_hook (forward_hook_input )
3638 else :
37- self .target_layer .register_forward_hook (forward_hook_output )
38-
39- self .target_layer .register_backward_hook (backward_hook )
39+ self .handle_forward_hook = self . target_layer .register_forward_hook (forward_hook_output )
40+
41+ self .handle_backward_hook = self . target_layer .register_backward_hook (backward_hook )
4042
4143 def _reset_intermediate_lists (self ):
4244 self .intermediate_act = []
4345 self .intermediate_grad = []
4446
4547 def explain (self , inp , ind = None , raw_inp = None ):
4648 self ._reset_intermediate_lists ()
47-
4849 _ = super (GradCAMExplainer , self )._backprop (inp , ind )
49-
50+ self .handle_forward_hook .remove ()
51+ self .handle_backward_hook .remove ()
5052 if len (self .intermediate_grad ):
5153 grad = self .intermediate_grad [0 ]
5254 act = self .intermediate_act [0 ]
53-
55+
5456 weights = grad .sum (- 1 ).sum (- 1 ).unsqueeze (- 1 ).unsqueeze (- 1 )
5557 cam = weights * act
5658 cam = cam .sum (1 ).unsqueeze (1 )
5759
5860 cam = torch .clamp (cam , min = 0 )
59-
6061 return cam
6162 else :
6263 return None
64+
0 commit comments