RashiAgarwal
commited on
Commit
·
f58c0a4
1
Parent(s):
57418a4
Update utils.py
Browse files
utils.py
CHANGED
@@ -9,6 +9,9 @@ import torch
|
|
9 |
from collections import Counter
|
10 |
from torch.utils.data import DataLoader
|
11 |
from tqdm import tqdm
|
|
|
|
|
|
|
12 |
|
13 |
|
14 |
def iou_width_height(boxes1, boxes2):
|
@@ -634,4 +637,68 @@ def clip_boxes(boxes, shape):
|
|
634 |
boxes[..., 3].clamp_(0, shape[0]) # y2
|
635 |
else: # np.array (faster grouped)
|
636 |
boxes[..., [0, 2]] = boxes[..., [0, 2]].clip(0, shape[1]) # x1, x2
|
637 |
-
boxes[..., [1, 3]] = boxes[..., [1, 3]].clip(0, shape[0]) # y1, y2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
from collections import Counter
|
10 |
from torch.utils.data import DataLoader
|
11 |
from tqdm import tqdm
|
12 |
+
from pytorch_grad_cam.base_cam import BaseCAM
|
13 |
+
from pytorch_grad_cam.utils.model_targets import ClassifierOutputTarget
|
14 |
+
from pytorch_grad_cam.utils.svd_on_activations import get_2d_projection
|
15 |
|
16 |
|
17 |
def iou_width_height(boxes1, boxes2):
|
|
|
637 |
boxes[..., 3].clamp_(0, shape[0]) # y2
|
638 |
else: # np.array (faster grouped)
|
639 |
boxes[..., [0, 2]] = boxes[..., [0, 2]].clip(0, shape[1]) # x1, x2
|
640 |
+
boxes[..., [1, 3]] = boxes[..., [1, 3]].clip(0, shape[0]) # y1, y2
|
641 |
+
|
642 |
+
|
643 |
+
|
644 |
+
|
645 |
+
class YoloCAM(BaseCAM):
|
646 |
+
def __init__(self, model, target_layers, use_cuda=False, reshape_transform=None):
|
647 |
+
super().__init__(
|
648 |
+
model, target_layers, use_cuda, reshape_transform, uses_gradients=False
|
649 |
+
)
|
650 |
+
|
651 |
+
def forward(
|
652 |
+
self,
|
653 |
+
input_tensor: torch.Tensor,
|
654 |
+
scaled_anchors: torch.Tensor,
|
655 |
+
targets: List[torch.nn.Module],
|
656 |
+
eigen_smooth: bool = False,
|
657 |
+
) -> np.ndarray:
|
658 |
+
if self.cuda:
|
659 |
+
input_tensor = input_tensor.cuda()
|
660 |
+
|
661 |
+
if self.compute_input_gradient:
|
662 |
+
input_tensor = torch.autograd.Variable(input_tensor, requires_grad=True)
|
663 |
+
|
664 |
+
outputs = self.activations_and_grads(input_tensor)
|
665 |
+
if targets is None:
|
666 |
+
bboxes = [[] for _ in range(1)]
|
667 |
+
for i in range(3):
|
668 |
+
batch_size, A, S, _, _ = outputs[i].shape
|
669 |
+
anchor = scaled_anchors[i]
|
670 |
+
boxes_scale_i = cells_to_bboxes(outputs[i], anchor, S=S, is_preds=True)
|
671 |
+
for idx, (box) in enumerate(boxes_scale_i):
|
672 |
+
bboxes[idx] += box
|
673 |
+
|
674 |
+
nms_boxes = non_max_suppression(
|
675 |
+
bboxes[0],
|
676 |
+
iou_threshold=0.5,
|
677 |
+
threshold=0.4,
|
678 |
+
box_format="midpoint",
|
679 |
+
)
|
680 |
+
# target_categories = np.argmax(outputs.cpu().data.numpy(), axis=-1)
|
681 |
+
target_categories = [box[0] for box in nms_boxes]
|
682 |
+
targets = [ClassifierOutputTarget(category) for category in target_categories]
|
683 |
+
|
684 |
+
if self.uses_gradients:
|
685 |
+
self.model.zero_grad()
|
686 |
+
loss = sum([target(output) for target, output in zip(targets, outputs)])
|
687 |
+
loss.backward(retain_graph=True)
|
688 |
+
|
689 |
+
# In most of the saliency attribution papers, the saliency is
|
690 |
+
# computed with a single target layer.
|
691 |
+
# Commonly it is the last convolutional layer.
|
692 |
+
# Here we support passing a list with multiple target layers.
|
693 |
+
# It will compute the saliency image for every image,
|
694 |
+
# and then aggregate them (with a default mean aggregation).
|
695 |
+
# This gives you more flexibility in case you just want to
|
696 |
+
# use all conv layers for example, all Batchnorm layers,
|
697 |
+
# or something else.
|
698 |
+
cam_per_layer = self.compute_cam_per_layer(input_tensor, targets, eigen_smooth)
|
699 |
+
return self.aggregate_multi_layers(cam_per_layer)
|
700 |
+
|
701 |
+
def get_cam_image(
|
702 |
+
self, input_tensor, target_layer, target_category, activations, grads, eigen_smooth
|
703 |
+
):
|
704 |
+
return get_2d_projection(activations)
|