@@ -78,3 +78,45 @@ def __call__(self, inputs, index):
78
78
# resize to 224*224
79
79
cam = cv2 .resize (cam , (224 , 224 ))
80
80
return cam
81
+
82
+
83
+ class GradCamPlusPlus (GradCAM ):
84
+ def __init__ (self , net , layer_name ):
85
+ super (GradCamPlusPlus , self ).__init__ (net , layer_name )
86
+
87
+ def __call__ (self , inputs , index ):
88
+ """
89
+
90
+ :param inputs: [1,3,H,W]
91
+ :param index: class id
92
+ :return:
93
+ """
94
+ self .net .zero_grad ()
95
+ output = self .net (inputs ) # [1,num_classes]
96
+ if index is None :
97
+ index = np .argmax (output .cpu ().data .numpy ())
98
+ target = output [0 ][index ]
99
+ target .backward ()
100
+
101
+ gradient = self .gradient [0 ].cpu ().data .numpy () # [C,H,W]
102
+ gradient = np .maximum (gradient , 0. ) # ReLU
103
+ indicate = np .where (gradient > 0 , 1. , 0. ) # 示性函数
104
+ norm_factor = np .sum (gradient , axis = (1 , 2 )) # [C]归一化
105
+ for i in range (len (norm_factor )):
106
+ norm_factor [i ] = 1. / norm_factor [i ] if norm_factor [i ] > 0. else 0. # 避免除零
107
+ alpha = indicate * norm_factor [:, np .newaxis , np .newaxis ] # [C,H,W]
108
+
109
+ weight = np .sum (gradient * alpha , axis = (1 , 2 )) # [C] alpha*ReLU(gradient)
110
+
111
+ feature = self .feature [0 ].cpu ().data .numpy () # [C,H,W]
112
+
113
+ cam = feature * weight [:, np .newaxis , np .newaxis ] # [C,H,W]
114
+ cam = np .sum (cam , axis = 0 ) # [H,W]
115
+ # cam = np.maximum(cam, 0) # ReLU
116
+
117
+ # 数值归一化
118
+ cam -= np .min (cam )
119
+ cam /= np .max (cam )
120
+ # resize to 224*224
121
+ cam = cv2 .resize (cam , (224 , 224 ))
122
+ return cam
0 commit comments