Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

#546 Features/sg 409 check all params used

Merged
Ghost merged 1 commits into Deci-AI:master from deci-ai:features/SG-409-check-all-params-used
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
  1. import itertools
  2. from math import sqrt
  3. from typing import List
  4. import numpy as np
  5. import torch
  6. from super_gradients.training.utils.detection_utils import non_max_suppression, NMS_Type, matrix_non_max_suppression, DetectionPostPredictionCallback
  7. class DefaultBoxes(object):
  8. """
  9. Default Boxes, (aka: anchor boxes or priors boxes) used by SSD model
  10. """
  11. def __init__(self, fig_size: int, feat_size: List[int], scales: List[int], aspect_ratios: List[List[int]], scale_xy=0.1, scale_wh=0.2):
  12. """
  13. For each feature map i (each predicting level, grids) the anchors (a.k.a. default boxes) will be:
  14. [
  15. [s, s], [sqrt(s * s_next), sqrt(s * s_next)],
  16. [s * sqrt(alpha1), s / sqrt(alpha1)], [s / sqrt(alpha1), s * sqrt(alpha1)],
  17. ...
  18. [s * sqrt(alphaN), s / sqrt(alphaN)], [s / sqrt(alphaN), s * sqrt(alphaN)]
  19. ] / fig_size
  20. where:
  21. * s = scale[i] - this level's scale
  22. * s_next = scale[i + 1] - next level's scale
  23. * alpha1, ... alphaN - this level's alphas, e.g. [2, 3]
  24. * fig_size - input image resolution
  25. Because of division by image resolution, the anchors will be in image coordinates normalized to [0, 1]
  26. :param fig_size: input image resolution
  27. :param feat_size: resolution of all feature maps with predictions (grids)
  28. :param scales: anchor sizes in pixels for each feature level;
  29. one value per level will be used to generate anchors based on the formula above
  30. :param aspect_ratios: lists of alpha values for each feature map
  31. :param scale_xy: predicted boxes will be with a factor scale_xy
  32. so will be multiplied by scale_xy during post-prediction processing;
  33. e.g. scale 0.1 means that prediction will be 10 times bigger
  34. (improves predictions quality)
  35. :param scale_wh: same logic as in scale_xy, but for width and height.
  36. """
  37. self.feat_size = feat_size
  38. self.fig_size = fig_size
  39. self.scale_xy_ = scale_xy
  40. self.scale_wh_ = scale_wh
  41. # According to https://github.com/weiliu89/caffe
  42. # Calculation method slightly different from paper
  43. self.scales = scales
  44. self.aspect_ratios = aspect_ratios
  45. self.default_boxes = []
  46. self.num_anchors = []
  47. # size of feature and number of feature
  48. for idx, sfeat in enumerate(self.feat_size):
  49. sk1 = scales[idx]
  50. sk2 = scales[idx + 1]
  51. sk3 = sqrt(sk1 * sk2)
  52. all_sizes = [(sk1, sk1), (sk3, sk3)]
  53. for alpha in aspect_ratios[idx]:
  54. w, h = sk1 * sqrt(alpha), sk1 / sqrt(alpha)
  55. all_sizes.append((w, h))
  56. all_sizes.append((h, w))
  57. all_sizes = np.array(all_sizes) / fig_size
  58. self.num_anchors.append(len(all_sizes))
  59. for w, h in all_sizes:
  60. for i, j in itertools.product(range(sfeat), repeat=2):
  61. cx, cy = (j + 0.5) / sfeat, (i + 0.5) / sfeat
  62. self.default_boxes.append((cx, cy, w, h))
  63. self.dboxes = torch.tensor(self.default_boxes, dtype=torch.float)
  64. self.dboxes.clamp_(min=0, max=1)
  65. # For IoU calculation
  66. self.dboxes_xyxy = self.dboxes.clone()
  67. self.dboxes_xyxy[:, 0] = self.dboxes[:, 0] - 0.5 * self.dboxes[:, 2]
  68. self.dboxes_xyxy[:, 1] = self.dboxes[:, 1] - 0.5 * self.dboxes[:, 3]
  69. self.dboxes_xyxy[:, 2] = self.dboxes[:, 0] + 0.5 * self.dboxes[:, 2]
  70. self.dboxes_xyxy[:, 3] = self.dboxes[:, 1] + 0.5 * self.dboxes[:, 3]
  71. @property
  72. def scale_xy(self):
  73. return self.scale_xy_
  74. @property
  75. def scale_wh(self):
  76. return self.scale_wh_
  77. def __call__(self, order="xyxy"):
  78. if order == "xyxy":
  79. return self.dboxes_xyxy
  80. if order == "xywh":
  81. return self.dboxes
  82. class SSDPostPredictCallback(DetectionPostPredictionCallback):
  83. """
  84. post prediction callback module to convert and filter predictions coming from the SSD net to a format
  85. used by all other detection models
  86. """
  87. def __init__(
  88. self,
  89. conf: float = 0.001,
  90. iou: float = 0.6,
  91. classes: list = None,
  92. max_predictions: int = 300,
  93. nms_type: NMS_Type = NMS_Type.ITERATIVE,
  94. multi_label_per_box=True,
  95. ):
  96. """
  97. Predictions of SSD contain unnormalized probabilities for a background class,
  98. together with confidences for all the dataset classes. Background will be utilized and discarded,
  99. so this callback will return 0-based classes without background
  100. :param conf: confidence threshold
  101. :param iou: IoU threshold
  102. :param classes: (optional list) filter by class
  103. :param nms_type: the type of nms to use (iterative or matrix)
  104. :param multi_label_per_box: whether to use re-use each box with all possible labels
  105. (instead of the maximum confidence all confidences above threshold
  106. will be sent to NMS)
  107. """
  108. super(SSDPostPredictCallback, self).__init__()
  109. self.conf = conf
  110. self.iou = iou
  111. self.nms_type = nms_type
  112. self.classes = classes
  113. self.max_predictions = max_predictions
  114. self.multi_label_per_box = multi_label_per_box
  115. def forward(self, predictions, device=None):
  116. nms_input = predictions[0]
  117. if self.nms_type == NMS_Type.ITERATIVE:
  118. nms_res = non_max_suppression(
  119. nms_input, conf_thres=self.conf, iou_thres=self.iou, multi_label_per_box=self.multi_label_per_box, with_confidence=True
  120. )
  121. else:
  122. nms_res = matrix_non_max_suppression(nms_input, conf_thres=self.conf, max_num_of_detections=self.max_predictions)
  123. return self._filter_max_predictions(nms_res)
  124. def _filter_max_predictions(self, res: List) -> List:
  125. res[:] = [im[: self.max_predictions] if (im is not None and im.shape[0] > self.max_predictions) else im for im in res]
  126. return res
Discard
Tip!

Press p or to see the previous file or, n or to see the next file