| 741 | |
| 742 | |
| 743 | class FasterRCNN(nn.Module): |
| 744 | def __init__(self, model_config, num_classes): |
| 745 | super(FasterRCNN, self).__init__() |
| 746 | self.model_config = model_config |
| 747 | vgg16 = torchvision.models.vgg16(pretrained=True) |
| 748 | self.backbone = vgg16.features[:-1] |
| 749 | self.rpn = RegionProposalNetwork(model_config['backbone_out_channels'], |
| 750 | scales=model_config['scales'], |
| 751 | aspect_ratios=model_config['aspect_ratios'], |
| 752 | model_config=model_config) |
| 753 | self.roi_head = ROIHead(model_config, num_classes, in_channels=model_config['backbone_out_channels']) |
| 754 | for layer in self.backbone[:10]: |
| 755 | for p in layer.parameters(): |
| 756 | p.requires_grad = False |
| 757 | self.image_mean = [0.485, 0.456, 0.406] |
| 758 | self.image_std = [0.229, 0.224, 0.225] |
| 759 | self.min_size = model_config['min_im_size'] |
| 760 | self.max_size = model_config['max_im_size'] |
| 761 | |
| 762 | def normalize_resize_image_and_boxes(self, image, bboxes): |
| 763 | dtype, device = image.dtype, image.device |
| 764 | |
| 765 | # Normalize |
| 766 | mean = torch.as_tensor(self.image_mean, dtype=dtype, device=device) |
| 767 | std = torch.as_tensor(self.image_std, dtype=dtype, device=device) |
| 768 | image = (image - mean[:, None, None]) / std[:, None, None] |
| 769 | ############# |
| 770 | |
| 771 | # Resize to 1000x600 such that lowest size dimension is scaled upto 600 |
| 772 | # but larger dimension is not more than 1000 |
| 773 | # So compute scale factor for both and scale is minimum of these two |
| 774 | h, w = image.shape[-2:] |
| 775 | im_shape = torch.tensor(image.shape[-2:]) |
| 776 | min_size = torch.min(im_shape).to(dtype=torch.float32) |
| 777 | max_size = torch.max(im_shape).to(dtype=torch.float32) |
| 778 | scale = torch.min(float(self.min_size) / min_size, float(self.max_size) / max_size) |
| 779 | scale_factor = scale.item() |
| 780 | |
| 781 | # Resize image based on scale computed |
| 782 | image = torch.nn.functional.interpolate( |
| 783 | image, |
| 784 | size=None, |
| 785 | scale_factor=scale_factor, |
| 786 | mode="bilinear", |
| 787 | recompute_scale_factor=True, |
| 788 | align_corners=False, |
| 789 | ) |
| 790 | |
| 791 | if bboxes is not None: |
| 792 | # Resize boxes by |
| 793 | ratios = [ |
| 794 | torch.tensor(s, dtype=torch.float32, device=bboxes.device) |
| 795 | / torch.tensor(s_orig, dtype=torch.float32, device=bboxes.device) |
| 796 | for s, s_orig in zip(image.shape[-2:], (h, w)) |
| 797 | ] |
| 798 | ratio_height, ratio_width = ratios |
| 799 | xmin, ymin, xmax, ymax = bboxes.unbind(2) |
| 800 | xmin = xmin * ratio_width |
no outgoing calls
no test coverage detected