RashiAgarwal commited on
Commit
f58c0a4
·
1 Parent(s): 57418a4

Update utils.py

Browse files
Files changed (1) hide show
  1. utils.py +68 -1
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)