Computes Gradient-weighted Class Activation Mapping (Grad-CAM++). This implementation is based on: Chattopadhyay et al., Grad-CAM++: Improved Visual Explanations for Deep Convolutional Networks, https://arxiv.org/abs/1710.11063 See Also: - :py:class:`monai.vis
| 385 | |
| 386 | |
| 387 | class GradCAMpp(GradCAM): |
| 388 | """ |
| 389 | Computes Gradient-weighted Class Activation Mapping (Grad-CAM++). |
| 390 | This implementation is based on: |
| 391 | |
| 392 | Chattopadhyay et al., Grad-CAM++: Improved Visual Explanations for Deep Convolutional Networks, |
| 393 | https://arxiv.org/abs/1710.11063 |
| 394 | |
| 395 | See Also: |
| 396 | |
| 397 | - :py:class:`monai.visualize.class_activation_maps.GradCAM` |
| 398 | |
| 399 | """ |
| 400 | |
| 401 | def compute_map(self, x, class_idx=None, retain_graph=False, layer_idx=-1, **kwargs): # type: ignore[override] |
| 402 | _, acti, grad = self.nn_module(x, class_idx=class_idx, retain_graph=retain_graph, **kwargs) |
| 403 | acti, grad = acti[layer_idx], grad[layer_idx] |
| 404 | b, c, *spatial = grad.shape |
| 405 | alpha_nr = grad.pow(2) |
| 406 | alpha_dr = alpha_nr.mul(2) + acti.mul(grad.pow(3)).view(b, c, -1).sum(-1).view(b, c, *[1] * len(spatial)) |
| 407 | alpha_dr = torch.where(alpha_dr != 0.0, alpha_dr, torch.ones_like(alpha_dr)) |
| 408 | alpha = alpha_nr.div(alpha_dr + 1e-7) |
| 409 | relu_grad = F.relu(cast(torch.Tensor, self.nn_module.score).exp() * grad) |
| 410 | weights = (alpha * relu_grad).view(b, c, -1).sum(-1).view(b, c, *[1] * len(spatial)) |
| 411 | acti_map = (weights * acti).sum(1, keepdim=True) |
| 412 | return F.relu(acti_map) |
no outgoing calls
no test coverage detected
searching dependent graphs…