From 50ab4957c68f8d3675bfe996a497886fd93c1d80 Mon Sep 17 00:00:00 2001 From: Aditya Oke Date: Sun, 10 Oct 2021 19:59:01 +0530 Subject: [PATCH 1/9] Start annotating utils --- mypy.ini | 52 +++++++++++++++++++++++++- torchvision/models/detection/_utils.py | 9 ++--- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/mypy.ini b/mypy.ini index 4820cdf1661..181894506e1 100644 --- a/mypy.ini +++ b/mypy.ini @@ -17,7 +17,57 @@ ignore_errors = True ignore_errors=True -[mypy-torchvision.models.detection.*] +[mypy-torchvision.models.detection.anchor_utils] + +ignore_errors = True + +[mypy-torchvision.models.detection.backbone_utils] + +ignore_errors = True + + +[mypy-torchvision.models.detection.image_list] + +ignore_errors = True + + +[mypy-torchvision.models.detection.transform] + +ignore_errors = True + +[mypy-torchvision.models.detection.rpn] + +ignore_errors = True + +[mypy-torchvision.models.detection.roi_heads] + +ignore_errors = True + +[mypy-torchvision.models.detection.generalized_rcnn] + +ignore_errors = True + +[mypy-torchvision.models.detection.faster_rcnn] + +ignore_errors = True + +[mypy-torchvision.models.detection.mask_rcnn] + +ignore_errors = True + +[mypy-torchvision.models.detection.keypoint_rcnn] + +ignore_errors = True + +[mypy-torchvision.models.detection.retinanet] + +ignore_errors = True + +[mypy-torchvision.models.detection.ssd] + +ignore_errors = True + +[mypy-torchvision.models.detection.ssdlite] ignore_errors = True diff --git a/torchvision/models/detection/_utils.py b/torchvision/models/detection/_utils.py index 130b445874a..194f514d832 100644 --- a/torchvision/models/detection/_utils.py +++ b/torchvision/models/detection/_utils.py @@ -3,7 +3,7 @@ from typing import List, Tuple import torch -from torch import Tensor +from torch import Tensor, nn from torchvision.ops.misc import FrozenBatchNorm2d @@ -12,8 +12,7 @@ class BalancedPositiveNegativeSampler(object): This class samples batches, ensuring that they contain a fixed proportion of positives """ - def __init__(self, batch_size_per_image, positive_fraction): - # type: (int, float) -> None + def __init__(self, batch_size_per_image: int, positive_fraction: float) -> None: """ Args: batch_size_per_image (int): number of elements to be selected per image @@ -350,7 +349,7 @@ def __call__(self, match_quality_matrix): return matches -def overwrite_eps(model, eps): +def overwrite_eps(model: nn.Module, eps: float) -> None: """ This method overwrites the default eps values of all the FrozenBatchNorm2d layers of the model with the provided value. @@ -368,7 +367,7 @@ def overwrite_eps(model, eps): module.eps = eps -def retrieve_out_channels(model, size): +def retrieve_out_channels(model: nn.Module, size: Tuple[int, int]) -> List[int]: """ This method retrieves the number of output channels of a specific model. From dab9402dd6900774798b97e269c587510288cb75 Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Mon, 11 Oct 2021 15:23:43 +0530 Subject: [PATCH 2/9] checking --- torchvision/models/detection/_utils.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/torchvision/models/detection/_utils.py b/torchvision/models/detection/_utils.py index 194f514d832..d7fc8c69ff8 100644 --- a/torchvision/models/detection/_utils.py +++ b/torchvision/models/detection/_utils.py @@ -21,8 +21,7 @@ def __init__(self, batch_size_per_image: int, positive_fraction: float) -> None: self.batch_size_per_image = batch_size_per_image self.positive_fraction = positive_fraction - def __call__(self, matched_idxs): - # type: (List[Tensor]) -> Tuple[List[Tensor], List[Tensor]] + def __call__(self, matched_idxs: List[Tensor]) -> Tuple[List[Tensor], List[Tensor]]: """ Args: matched idxs: list of tensors containing -1, 0 or positive values. @@ -72,8 +71,7 @@ def __call__(self, matched_idxs): @torch.jit._script_if_tracing -def encode_boxes(reference_boxes, proposals, weights): - # type: (torch.Tensor, torch.Tensor, torch.Tensor) -> torch.Tensor +def encode_boxes(reference_boxes: Tensor, proposals: Tensor, weights: Tensor) -> Tensor: """ Encode a set of proposals with respect to some reference boxes @@ -126,7 +124,7 @@ class BoxCoder(object): the representation used for training the regressors. """ - def __init__(self, weights, bbox_xform_clip=math.log(1000.0 / 16)): + def __init__(self, weights: Tuple[float, bbox_xform_clip=math.log(1000.0 / 16)): # type: (Tuple[float, float, float, float], float) -> None """ Args: From 5f7d0d918eef360b061a7c824679adc900dd7e51 Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Mon, 11 Oct 2021 16:10:19 +0530 Subject: [PATCH 3/9] Add annotations at _utils.py --- torchvision/models/detection/_utils.py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/torchvision/models/detection/_utils.py b/torchvision/models/detection/_utils.py index d7fc8c69ff8..e44bce9e00b 100644 --- a/torchvision/models/detection/_utils.py +++ b/torchvision/models/detection/_utils.py @@ -124,8 +124,7 @@ class BoxCoder(object): the representation used for training the regressors. """ - def __init__(self, weights: Tuple[float, bbox_xform_clip=math.log(1000.0 / 16)): - # type: (Tuple[float, float, float, float], float) -> None + def __init__(self, weights: Tuple[float, float, float, float], bbox_xform_clip: float = math.log(1000.0 / 16)) -> None: """ Args: weights (4-element tuple) @@ -134,15 +133,14 @@ def __init__(self, weights: Tuple[float, bbox_xform_clip=math.log(1000.0 / 16)): self.weights = weights self.bbox_xform_clip = bbox_xform_clip - def encode(self, reference_boxes, proposals): - # type: (List[Tensor], List[Tensor]) -> List[Tensor] + def encode(self, reference_boxes: List[Tensor], proposals: List[Tensor]) -> List[Tensor]: boxes_per_image = [len(b) for b in reference_boxes] reference_boxes = torch.cat(reference_boxes, dim=0) proposals = torch.cat(proposals, dim=0) targets = self.encode_single(reference_boxes, proposals) return targets.split(boxes_per_image, 0) - def encode_single(self, reference_boxes, proposals): + def encode_single(self, reference_boxes: Tensor, proposals: Tensor) -> Tensor: """ Encode a set of proposals with respect to some reference boxes @@ -158,7 +156,7 @@ def encode_single(self, reference_boxes, proposals): return targets - def decode(self, rel_codes, boxes): + def decode(self, rel_codes: Tensor, boxes: List[Tensor]) -> Tensor: # type: (Tensor, List[Tensor]) -> Tensor assert isinstance(boxes, (list, tuple)) assert isinstance(rel_codes, torch.Tensor) @@ -174,7 +172,7 @@ def decode(self, rel_codes, boxes): pred_boxes = pred_boxes.reshape(box_sum, -1, 4) return pred_boxes - def decode_single(self, rel_codes, boxes): + def decode_single(self, rel_codes: Tensor, boxes: Tensor) -> Tensor: """ From a set of original boxes and encoded relative box offsets, get the decoded boxes. @@ -241,8 +239,7 @@ class Matcher(object): "BETWEEN_THRESHOLDS": int, } - def __init__(self, high_threshold, low_threshold, allow_low_quality_matches=False): - # type: (float, float, bool) -> None + def __init__(self, high_threshold: float, low_threshold: float, allow_low_quality_matches: bool = False) -> None: """ Args: high_threshold (float): quality values greater than or equal to @@ -263,7 +260,7 @@ def __init__(self, high_threshold, low_threshold, allow_low_quality_matches=Fals self.low_threshold = low_threshold self.allow_low_quality_matches = allow_low_quality_matches - def __call__(self, match_quality_matrix): + def __call__(self, match_quality_matrix: Tensor[float]) -> Tensor[int64]: """ Args: match_quality_matrix (Tensor[float]): an MxN tensor, containing the @@ -301,7 +298,7 @@ def __call__(self, match_quality_matrix): return matches - def set_low_quality_matches_(self, matches, all_matches, match_quality_matrix): + def set_low_quality_matches_(self, matches: Tensor[int64], all_matches: Tensor[int64], match_quality_matrix: Tensor[float]) -> None: """ Produce additional matches for predictions that have only low-quality matches. Specifically, for each ground-truth find the set of predictions that have @@ -335,7 +332,7 @@ class SSDMatcher(Matcher): def __init__(self, threshold): super().__init__(threshold, threshold, allow_low_quality_matches=False) - def __call__(self, match_quality_matrix): + def __call__(self, match_quality_matrix: Tensor[float]) -> Tensor[int64]: matches = super().__call__(match_quality_matrix) # For each gt, find the prediction with which it has the highest quality From d0171615c327518d00cff0ac728c2b1314258c57 Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Mon, 11 Oct 2021 16:20:09 +0530 Subject: [PATCH 4/9] Remove unnecessary comments. --- torchvision/models/detection/_utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/torchvision/models/detection/_utils.py b/torchvision/models/detection/_utils.py index e44bce9e00b..34e14bdc35e 100644 --- a/torchvision/models/detection/_utils.py +++ b/torchvision/models/detection/_utils.py @@ -157,7 +157,6 @@ def encode_single(self, reference_boxes: Tensor, proposals: Tensor) -> Tensor: return targets def decode(self, rel_codes: Tensor, boxes: List[Tensor]) -> Tensor: - # type: (Tensor, List[Tensor]) -> Tensor assert isinstance(boxes, (list, tuple)) assert isinstance(rel_codes, torch.Tensor) boxes_per_image = [b.size(0) for b in boxes] From f6bb4428664f157356326e1ab7386ffcce3a0d50 Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Mon, 11 Oct 2021 23:42:31 +0530 Subject: [PATCH 5/9] re-checked typings --- torchvision/models/detection/_utils.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/torchvision/models/detection/_utils.py b/torchvision/models/detection/_utils.py index 34e14bdc35e..a55802a214e 100644 --- a/torchvision/models/detection/_utils.py +++ b/torchvision/models/detection/_utils.py @@ -124,7 +124,9 @@ class BoxCoder(object): the representation used for training the regressors. """ - def __init__(self, weights: Tuple[float, float, float, float], bbox_xform_clip: float = math.log(1000.0 / 16)) -> None: + def __init__( + self, weights: Tuple[float, float, float, float], bbox_xform_clip: float = math.log(1000.0 / 16) + ) -> None: """ Args: weights (4-element tuple) @@ -259,7 +261,7 @@ def __init__(self, high_threshold: float, low_threshold: float, allow_low_qualit self.low_threshold = low_threshold self.allow_low_quality_matches = allow_low_quality_matches - def __call__(self, match_quality_matrix: Tensor[float]) -> Tensor[int64]: + def __call__(self, match_quality_matrix) -> Tensor: """ Args: match_quality_matrix (Tensor[float]): an MxN tensor, containing the @@ -297,7 +299,7 @@ def __call__(self, match_quality_matrix: Tensor[float]) -> Tensor[int64]: return matches - def set_low_quality_matches_(self, matches: Tensor[int64], all_matches: Tensor[int64], match_quality_matrix: Tensor[float]) -> None: + def set_low_quality_matches_(self, matches: Tensor, all_matches: Tensor, match_quality_matrix: Tensor) -> None: """ Produce additional matches for predictions that have only low-quality matches. Specifically, for each ground-truth find the set of predictions that have @@ -331,7 +333,7 @@ class SSDMatcher(Matcher): def __init__(self, threshold): super().__init__(threshold, threshold, allow_low_quality_matches=False) - def __call__(self, match_quality_matrix: Tensor[float]) -> Tensor[int64]: + def __call__(self, match_quality_matrix: Tensor) -> Tensor: matches = super().__call__(match_quality_matrix) # For each gt, find the prediction with which it has the highest quality From c4c2884226699247f31cc1867918b4634ae2c70a Mon Sep 17 00:00:00 2001 From: Aditya Oke Date: Tue, 12 Oct 2021 00:14:41 +0530 Subject: [PATCH 6/9] Update typing --- mypy.ini | 2 -- torchvision/models/detection/_utils.py | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/mypy.ini b/mypy.ini index 181894506e1..0c46a09610b 100644 --- a/mypy.ini +++ b/mypy.ini @@ -25,12 +25,10 @@ ignore_errors = True ignore_errors = True - [mypy-torchvision.models.detection.image_list] ignore_errors = True - [mypy-torchvision.models.detection.transform] ignore_errors = True diff --git a/torchvision/models/detection/_utils.py b/torchvision/models/detection/_utils.py index a55802a214e..de3c633dee4 100644 --- a/torchvision/models/detection/_utils.py +++ b/torchvision/models/detection/_utils.py @@ -16,7 +16,7 @@ def __init__(self, batch_size_per_image: int, positive_fraction: float) -> None: """ Args: batch_size_per_image (int): number of elements to be selected per image - positive_fraction (float): percentace of positive elements per batch + positive_fraction (float): percentage of positive elements per batch """ self.batch_size_per_image = batch_size_per_image self.positive_fraction = positive_fraction @@ -261,7 +261,7 @@ def __init__(self, high_threshold: float, low_threshold: float, allow_low_qualit self.low_threshold = low_threshold self.allow_low_quality_matches = allow_low_quality_matches - def __call__(self, match_quality_matrix) -> Tensor: + def __call__(self, match_quality_matrix: Tensor) -> Tensor: """ Args: match_quality_matrix (Tensor[float]): an MxN tensor, containing the @@ -330,7 +330,7 @@ def set_low_quality_matches_(self, matches: Tensor, all_matches: Tensor, match_q class SSDMatcher(Matcher): - def __init__(self, threshold): + def __init__(self, threshold: float) -> None: super().__init__(threshold, threshold, allow_low_quality_matches=False) def __call__(self, match_quality_matrix: Tensor) -> Tensor: From f15719077ab6ccf2ed158314e65defaf844ea24e Mon Sep 17 00:00:00 2001 From: Aditya Oke Date: Tue, 12 Oct 2021 00:24:36 +0530 Subject: [PATCH 7/9] Ignore small error --- torchvision/models/detection/_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/torchvision/models/detection/_utils.py b/torchvision/models/detection/_utils.py index de3c633dee4..1bb1be347f9 100644 --- a/torchvision/models/detection/_utils.py +++ b/torchvision/models/detection/_utils.py @@ -285,7 +285,7 @@ def __call__(self, match_quality_matrix: Tensor) -> Tensor: if self.allow_low_quality_matches: all_matches = matches.clone() else: - all_matches = None + all_matches = None # type: ignore[assignment] # Assign candidate matches with low quality to negative (unassigned) values below_low_threshold = matched_vals < self.low_threshold From f1df465ba78158e22bc318500ec4a783354c9c9d Mon Sep 17 00:00:00 2001 From: Aditya Oke Date: Tue, 12 Oct 2021 01:04:13 +0530 Subject: [PATCH 8/9] Use optional tensor --- torchvision/models/detection/_utils.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/torchvision/models/detection/_utils.py b/torchvision/models/detection/_utils.py index 1bb1be347f9..af9007e6944 100644 --- a/torchvision/models/detection/_utils.py +++ b/torchvision/models/detection/_utils.py @@ -1,6 +1,6 @@ import math from collections import OrderedDict -from typing import List, Tuple +from typing import List, Tuple, Optional import torch from torch import Tensor, nn @@ -282,10 +282,11 @@ def __call__(self, match_quality_matrix: Tensor) -> Tensor: # match_quality_matrix is M (gt) x N (predicted) # Max over gt elements (dim 0) to find best gt candidate for each prediction matched_vals, matches = match_quality_matrix.max(dim=0) + all_matches: Optional[Tensor] if self.allow_low_quality_matches: all_matches = matches.clone() else: - all_matches = None # type: ignore[assignment] + all_matches = None # Assign candidate matches with low quality to negative (unassigned) values below_low_threshold = matched_vals < self.low_threshold From f78dd49099c3046f2f9c4330c1b4f6a3df94cd3a Mon Sep 17 00:00:00 2001 From: Aditya Oke Date: Tue, 12 Oct 2021 01:11:13 +0530 Subject: [PATCH 9/9] Ignore for JIT --- torchvision/models/detection/_utils.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/torchvision/models/detection/_utils.py b/torchvision/models/detection/_utils.py index af9007e6944..1bb1be347f9 100644 --- a/torchvision/models/detection/_utils.py +++ b/torchvision/models/detection/_utils.py @@ -1,6 +1,6 @@ import math from collections import OrderedDict -from typing import List, Tuple, Optional +from typing import List, Tuple import torch from torch import Tensor, nn @@ -282,11 +282,10 @@ def __call__(self, match_quality_matrix: Tensor) -> Tensor: # match_quality_matrix is M (gt) x N (predicted) # Max over gt elements (dim 0) to find best gt candidate for each prediction matched_vals, matches = match_quality_matrix.max(dim=0) - all_matches: Optional[Tensor] if self.allow_low_quality_matches: all_matches = matches.clone() else: - all_matches = None + all_matches = None # type: ignore[assignment] # Assign candidate matches with low quality to negative (unassigned) values below_low_threshold = matched_vals < self.low_threshold