33 lines
1.2 KiB
Python
33 lines
1.2 KiB
Python
import numpy as np
|
|
from pytorch_grad_cam.base_cam import BaseCAM
|
|
|
|
# https://arxiv.org/abs/1710.11063
|
|
|
|
|
|
class GradCAMPlusPlus(BaseCAM):
|
|
def __init__(self, model, target_layers, use_cuda=False,
|
|
reshape_transform=None):
|
|
super(GradCAMPlusPlus, self).__init__(model, target_layers, use_cuda,
|
|
reshape_transform)
|
|
|
|
def get_cam_weights(self,
|
|
input_tensor,
|
|
target_layers,
|
|
target_category,
|
|
activations,
|
|
grads):
|
|
grads_power_2 = grads**2
|
|
grads_power_3 = grads_power_2 * grads
|
|
# Equation 19 in https://arxiv.org/abs/1710.11063
|
|
sum_activations = np.sum(activations, axis=(2, 3))
|
|
eps = 0.000001
|
|
aij = grads_power_2 / (2 * grads_power_2 +
|
|
sum_activations[:, :, None, None] * grads_power_3 + eps)
|
|
# Now bring back the ReLU from eq.7 in the paper,
|
|
# And zero out aijs where the activations are 0
|
|
aij = np.where(grads != 0, aij, 0)
|
|
|
|
weights = np.maximum(grads, 0) * aij
|
|
weights = np.sum(weights, axis=(2, 3))
|
|
return weights
|