| 202 | self.gradient = grad_out[0].detach() |
| 203 | |
| 204 | def gradCam(self, x): |
| 205 | model = self.model.eval() |
| 206 | image_size = (x.size(-1), x.size(-2)) |
| 207 | datas = Variable(x, requires_grad=True) |
| 208 | heat_maps = [] |
| 209 | for i in range(datas.size(0)): |
| 210 | feature = datas[i].unsqueeze(0) |
| 211 | |
| 212 | img = datas[i].data.cpu().numpy() |
| 213 | img = img - np.min(img) |
| 214 | if np.max(img) != 0: |
| 215 | img = img / np.max(img) |
| 216 | |
| 217 | for name, module in self.model.named_modules(): |
| 218 | |
| 219 | if name == self.feature_name: |
| 220 | module.register_forward_hook(self.save_feature) |
| 221 | module.register_backward_hook(self.save_gradient) |
| 222 | |
| 223 | feature = model(feature) |
| 224 | |
| 225 | classes = F.softmax(feature, dim=1) |
| 226 | |
| 227 | one_hot, _ = classes.max(dim=-1) |
| 228 | one_hot.backward() |
| 229 | |
| 230 | weight = self.gradient.mean(dim=-1, keepdim=True).mean(dim=-2, keepdim=True) |
| 231 | |
| 232 | mask = F.relu((weight * self.feature).sum(dim=1)).squeeze(0) |
| 233 | |
| 234 | mask = cv2.resize(mask.data.cpu().numpy().astype(np.float32), image_size) |
| 235 | mask = mask - np.min(mask) |
| 236 | if np.max(mask) != 0: |
| 237 | mask = mask / np.max(mask) |
| 238 | heat_map = np.float32(cv2.applyColorMap(np.uint8(255 * mask), cv2.COLORMAP_JET)) |
| 239 | cam = heat_map + np.float32((np.uint8(img.transpose((1, 2, 0)) * 255))) |
| 240 | cam = cam - np.min(cam) |
| 241 | if np.max(cam) != 0: |
| 242 | cam = cam / np.max(cam) |
| 243 | heat_maps.append(transforms.ToPILImage()(transforms.ToTensor()( |
| 244 | cv2.cvtColor(np.uint8(255 * cam), cv2.COLOR_BGR2RGB)))) |
| 245 | return heat_maps |
| 246 | |
| 247 | |
| 248 | @link_dist |