cs-mixer / pytorch_grad_cam /score_cam.py
crrrr30's picture
Upload folder using huggingface_hub
da716ed
import torch
import tqdm
from pytorch_grad_cam.base_cam import BaseCAM
class ScoreCAM(BaseCAM):
def __init__(
self,
model,
target_layers,
use_cuda=False,
reshape_transform=None):
super(ScoreCAM, self).__init__(model,
target_layers,
use_cuda,
reshape_transform=reshape_transform,
uses_gradients=False)
def get_cam_weights(self,
input_tensor,
target_layer,
targets,
activations,
grads):
with torch.no_grad():
upsample = torch.nn.UpsamplingBilinear2d(
size=input_tensor.shape[-2:])
activation_tensor = torch.from_numpy(activations)
if self.cuda:
activation_tensor = activation_tensor.cuda()
upsampled = upsample(activation_tensor)
maxs = upsampled.view(upsampled.size(0),
upsampled.size(1), -1).max(dim=-1)[0]
mins = upsampled.view(upsampled.size(0),
upsampled.size(1), -1).min(dim=-1)[0]
maxs, mins = maxs[:, :, None, None], mins[:, :, None, None]
upsampled = (upsampled - mins) / (maxs - mins)
input_tensors = input_tensor[:, None,
:, :] * upsampled[:, :, None, :, :]
if hasattr(self, "batch_size"):
BATCH_SIZE = self.batch_size
else:
BATCH_SIZE = 16
scores = []
for target, tensor in zip(targets, input_tensors):
for i in tqdm.tqdm(range(0, tensor.size(0), BATCH_SIZE)):
batch = tensor[i: i + BATCH_SIZE, :]
outputs = [target(o).cpu().item()
for o in self.model(batch)]
scores.extend(outputs)
scores = torch.Tensor(scores)
scores = scores.view(activations.shape[0], activations.shape[1])
weights = torch.nn.Softmax(dim=-1)(scores).numpy()
return weights