edgefirst-validator 4.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. deepview/modelpack/utils/argmax.py +16 -0
  2. edgefirst/validator/__init__.py +1 -0
  3. edgefirst/validator/__main__.py +375 -0
  4. edgefirst/validator/datasets/__init__.py +118 -0
  5. edgefirst/validator/datasets/cache.py +296 -0
  6. edgefirst/validator/datasets/core.py +250 -0
  7. edgefirst/validator/datasets/darknet.py +446 -0
  8. edgefirst/validator/datasets/database.py +1067 -0
  9. edgefirst/validator/datasets/instance/__init__.py +4 -0
  10. edgefirst/validator/datasets/instance/core.py +222 -0
  11. edgefirst/validator/datasets/instance/detection.py +145 -0
  12. edgefirst/validator/datasets/instance/multitask.py +80 -0
  13. edgefirst/validator/datasets/instance/segmentation.py +120 -0
  14. edgefirst/validator/datasets/utils/fetch.py +682 -0
  15. edgefirst/validator/datasets/utils/readers.py +425 -0
  16. edgefirst/validator/datasets/utils/transformations.py +1695 -0
  17. edgefirst/validator/evaluators/__init__.py +17 -0
  18. edgefirst/validator/evaluators/callbacks/__init__.py +3 -0
  19. edgefirst/validator/evaluators/callbacks/core.py +192 -0
  20. edgefirst/validator/evaluators/callbacks/plots.py +900 -0
  21. edgefirst/validator/evaluators/callbacks/studio.py +234 -0
  22. edgefirst/validator/evaluators/core.py +257 -0
  23. edgefirst/validator/evaluators/detection.py +749 -0
  24. edgefirst/validator/evaluators/multitask.py +270 -0
  25. edgefirst/validator/evaluators/parameters/__init__.py +53 -0
  26. edgefirst/validator/evaluators/parameters/core.py +554 -0
  27. edgefirst/validator/evaluators/parameters/dataset.py +239 -0
  28. edgefirst/validator/evaluators/parameters/model.py +338 -0
  29. edgefirst/validator/evaluators/parameters/validation.py +528 -0
  30. edgefirst/validator/evaluators/segmentation.py +729 -0
  31. edgefirst/validator/evaluators/utils/__init__.py +3 -0
  32. edgefirst/validator/evaluators/utils/classify.py +292 -0
  33. edgefirst/validator/evaluators/utils/match.py +262 -0
  34. edgefirst/validator/evaluators/utils/timer.py +132 -0
  35. edgefirst/validator/metrics/__init__.py +9 -0
  36. edgefirst/validator/metrics/data/__init__.py +7 -0
  37. edgefirst/validator/metrics/data/label.py +668 -0
  38. edgefirst/validator/metrics/data/metrics.py +759 -0
  39. edgefirst/validator/metrics/data/plots.py +476 -0
  40. edgefirst/validator/metrics/data/stats.py +507 -0
  41. edgefirst/validator/metrics/detection.py +595 -0
  42. edgefirst/validator/metrics/segmentation.py +173 -0
  43. edgefirst/validator/metrics/utils/math.py +717 -0
  44. edgefirst/validator/publishers/__init__.py +3 -0
  45. edgefirst/validator/publishers/console.py +147 -0
  46. edgefirst/validator/publishers/studio.py +128 -0
  47. edgefirst/validator/publishers/tensorboard.py +119 -0
  48. edgefirst/validator/publishers/utils/logger.py +111 -0
  49. edgefirst/validator/publishers/utils/table.py +403 -0
  50. edgefirst/validator/runners/__init__.py +8 -0
  51. edgefirst/validator/runners/core.py +727 -0
  52. edgefirst/validator/runners/deepviewrt.py +177 -0
  53. edgefirst/validator/runners/hailo.py +263 -0
  54. edgefirst/validator/runners/keras.py +150 -0
  55. edgefirst/validator/runners/kinara.py +265 -0
  56. edgefirst/validator/runners/offline.py +228 -0
  57. edgefirst/validator/runners/onnx.py +241 -0
  58. edgefirst/validator/runners/processing/decode.py +320 -0
  59. edgefirst/validator/runners/processing/dvapi.py +4192 -0
  60. edgefirst/validator/runners/processing/nms.py +637 -0
  61. edgefirst/validator/runners/processing/outputs.py +507 -0
  62. edgefirst/validator/runners/tensorrt.py +321 -0
  63. edgefirst/validator/runners/tflite.py +221 -0
  64. edgefirst/validator/validate.py +843 -0
  65. edgefirst/validator/visualize/__init__.py +3 -0
  66. edgefirst/validator/visualize/detection.py +623 -0
  67. edgefirst/validator/visualize/segmentation.py +281 -0
  68. edgefirst/validator/visualize/utils/plots.py +635 -0
  69. edgefirst_validator-4.2.1.dist-info/METADATA +111 -0
  70. edgefirst_validator-4.2.1.dist-info/RECORD +73 -0
  71. edgefirst_validator-4.2.1.dist-info/WHEEL +5 -0
  72. edgefirst_validator-4.2.1.dist-info/entry_points.txt +2 -0
  73. edgefirst_validator-4.2.1.dist-info/top_level.txt +2 -0
@@ -0,0 +1,270 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Tuple
4
+
5
+ import numpy as np
6
+
7
+ from edgefirst.validator.evaluators import Evaluator
8
+ from edgefirst.validator.datasets import MultitaskInstance
9
+ from edgefirst.validator.evaluators import (YOLOValidator, EdgeFirstValidator,
10
+ SegmentationValidator)
11
+ from edgefirst.validator.metrics import MultitaskMetrics, MultitaskPlots
12
+
13
+ if TYPE_CHECKING:
14
+ from edgefirst.validator.evaluators import CombinedParameters
15
+ from edgefirst.validator.datasets import Dataset
16
+ from edgefirst.validator.runners import Runner
17
+
18
+
19
+ class MultitaskValidator(Evaluator):
20
+ """
21
+ This class handles validation of Vision models that outputs
22
+ bounding boxes and segmentation masks on an image.
23
+ This class is only intended for EdgeFirst validation. The multitask
24
+ validation from Ultralytics is implemented under
25
+ `YOLOSegmentationValidator`.
26
+
27
+ Parameters
28
+ ----------
29
+ parameters: CombinedParameters
30
+ This is a container for the model, dataset, and validation parameters
31
+ set from the command line.
32
+ runner: Runner
33
+ A type of model runner object responsible for running the model
34
+ for inference provided with an input image to produce bounding boxes.
35
+ dataset: Dataset
36
+ A type of dataset object responsible for reading different types
37
+ of datasets such as Darknet, TFRecords, or EdgeFirst Datasets.
38
+ """
39
+
40
+ def __init__(
41
+ self,
42
+ parameters: CombinedParameters,
43
+ runner: Runner = None,
44
+ dataset: Dataset = None,
45
+ ):
46
+ super(MultitaskValidator, self).__init__(
47
+ parameters=parameters, runner=runner, dataset=dataset)
48
+
49
+ if self.parameters.validation.method in ["ultralytics", "yolov7"]:
50
+ self.detection_evaluator = YOLOValidator(
51
+ parameters=parameters,
52
+ runner=None,
53
+ dataset=dataset
54
+ )
55
+ else:
56
+ self.detection_evaluator = EdgeFirstValidator(
57
+ parameters=parameters,
58
+ runner=None,
59
+ dataset=dataset
60
+ )
61
+
62
+ self.segmentation_evaluator = SegmentationValidator(
63
+ parameters=parameters,
64
+ runner=None,
65
+ dataset=dataset
66
+ )
67
+ self.parameters.model.common.semantic = True
68
+
69
+ self.metrics = MultitaskMetrics(
70
+ detection_metrics=self.detection_evaluator.metrics.metrics,
71
+ segmentation_metrics=self.segmentation_evaluator.metrics.metrics
72
+ )
73
+ self.plots = MultitaskPlots(
74
+ detection_plots=self.detection_evaluator.metrics.plots,
75
+ segmentation_plots=self.segmentation_evaluator.metrics.plots
76
+ )
77
+
78
+ def instance_collector(self):
79
+ """
80
+ Collects the Multitask instances from the ground truth and runs
81
+ model inference on a single image to collect the instance for
82
+ the model predictions.
83
+
84
+ Yields
85
+ ------
86
+ dict
87
+ This yields one image instance from the ground truth
88
+ and model predictions for multitask with keys
89
+ "gt_instance", "dt_instance".
90
+ """
91
+
92
+ gt_instance: MultitaskInstance
93
+ for gt_instance in self.dataset:
94
+ detections = self.runner.run_single_instance(
95
+ image=gt_instance.image
96
+ )
97
+ self.detection_evaluator.filter_gt(gt_instance)
98
+
99
+ if detections is None:
100
+ yield {
101
+ "gt_instance": gt_instance,
102
+ "dt_instance": None,
103
+ }
104
+
105
+ dt_instance = MultitaskInstance(gt_instance.image_path)
106
+ boxes, labels, scores, mask = detections
107
+ dt_instance.height = gt_instance.height
108
+ dt_instance.width = gt_instance.width
109
+ dt_instance.boxes = boxes
110
+ dt_instance.labels = labels
111
+ dt_instance.scores = scores
112
+ dt_instance.mask = self.segmentation_evaluator.calibrate_mask(
113
+ mask, dt_labels=dt_instance.labels)
114
+ self.detection_evaluator.filter_dt(dt_instance)
115
+
116
+ yield {
117
+ "gt_instance": gt_instance,
118
+ "dt_instance": dt_instance,
119
+ }
120
+
121
+ def single_evaluation(
122
+ self,
123
+ instance: dict,
124
+ epoch: int = 0,
125
+ save_image: bool = False
126
+ ):
127
+ """
128
+ Run model evaluation on a single image/sample for both
129
+ detection and segmentation.
130
+
131
+ Parameters
132
+ ----------
133
+ instance: dict
134
+ This contains the ground truth
135
+ and model predictions for multitask with keys
136
+ "gt_instance", "dt_instance".
137
+ epoch: int
138
+ This is the training epoch number. This
139
+ parameter is internal for ModelPack usage.
140
+ Standalone validation does not use this parameter.
141
+ save_image: bool
142
+ If set to True, this will save the image
143
+ with drawn bounding box results.
144
+ """
145
+ self.detection_evaluator.single_evaluation(
146
+ instance=instance,
147
+ epoch=epoch,
148
+ save_image=False
149
+ )
150
+ self.segmentation_evaluator.single_evaluation(
151
+ instance=instance,
152
+ epoch=epoch,
153
+ save_image=False
154
+ )
155
+
156
+ super().single_evaluation(instance=instance,
157
+ epoch=epoch,
158
+ save_image=save_image)
159
+
160
+ def visualize(
161
+ self,
162
+ gt_instance: MultitaskInstance,
163
+ dt_instance: MultitaskInstance,
164
+ epoch: int = 0
165
+ ):
166
+ """
167
+ Visualize the multi-task outputs for detection
168
+ and segmentation on the image.
169
+
170
+ Parameters
171
+ ----------
172
+ gt_instance: DetectionInstance
173
+ This is the ground truth instance which contains the
174
+ masks, bounding boxes and labels to draw.
175
+ dt_instance: DetectionInstance
176
+ This is the model detection instance which contains the
177
+ masks, bounding boxes, labels, and confidence scores to draw.
178
+ epoch: int
179
+ This is the training epoch number. This
180
+ parameter is internal for ModelPack usage.
181
+ Standalone validation does not use this parameter.
182
+
183
+ """
184
+ # Separate results for the ground truth and detection.
185
+ dt_instance.visual_image = gt_instance.visual_image.copy()
186
+
187
+ # Draw ground truth on the ground truth image.
188
+ image = self.detection_evaluator.drawer.draw_2d_gt_boxes(
189
+ image=gt_instance.visual_image,
190
+ gt_instance=gt_instance
191
+ )
192
+ gt_instance.visual_image = np.asarray(image)
193
+
194
+ # Draw detections on the detection image.
195
+ image = self.detection_evaluator.drawer.draw_2d_dt_boxes(
196
+ image=dt_instance.visual_image,
197
+ gt_instance=gt_instance,
198
+ dt_instance=dt_instance,
199
+ matcher=self.detection_evaluator.matcher,
200
+ validation_iou=self.parameters.validation.iou_threshold,
201
+ method=self.parameters.validation.method
202
+ )
203
+ dt_instance.visual_image = np.asarray(image)
204
+
205
+ # Draw segmentation results on the image.
206
+ self.segmentation_evaluator.visualize(
207
+ gt_instance=gt_instance,
208
+ dt_instance=dt_instance,
209
+ epoch=epoch
210
+ )
211
+
212
+ def end(
213
+ self,
214
+ epoch: int = 0,
215
+ reset: bool = True
216
+ ) -> Tuple[MultitaskMetrics, MultitaskPlots]:
217
+ """
218
+ Computes the final metrics for detection and segmentation and
219
+ generates the validation plots to save the results in disk or
220
+ publishes to Tensorboard.
221
+
222
+ Parameters
223
+ ----------
224
+ epoch: int
225
+ This is the training epoch number. This
226
+ parameter is internal for ModelPack usage.
227
+ Standalone validation does not use this parameter.
228
+ reset: bool
229
+ This is an optional parameter that controls the reset state.
230
+ By default, it will reset at the end of validation to erase
231
+ the data in the containers.
232
+
233
+ Returns
234
+ -------
235
+ metrics: MultitaskMetrics
236
+ This is a container for the detection and segmentation metrics.
237
+ plots: MultitaskPlots
238
+ This is a container for the validation data for plotting.
239
+ """
240
+ if hasattr(self.runner, "stop"):
241
+ self.runner.stop()
242
+
243
+ if self.runner:
244
+ timings = self.runner.timer.to_dict()
245
+
246
+ self.metrics.timings = timings
247
+ detection_metrics, detection_plots = self.detection_evaluator.end(
248
+ epoch=epoch, reset=reset, publish=False)
249
+ segmentation_metrics, segmentation_plots = self.segmentation_evaluator.end(
250
+ epoch=epoch, reset=reset, publish=False)
251
+
252
+ self.metrics.detection_metrics = detection_metrics
253
+ self.metrics.segmentation_metrics = segmentation_metrics
254
+ self.plots.detection_plots = detection_plots
255
+ self.plots.segmentation_plots = segmentation_plots
256
+
257
+ if self.tensorboard_writer:
258
+ self.tensorboard_writer.publish_metrics(
259
+ metrics=self.metrics,
260
+ parameters=self.parameters,
261
+ step=epoch,
262
+ )
263
+ else:
264
+ table = self.console_writer(metrics=self.metrics,
265
+ parameters=self.parameters)
266
+
267
+ if self.parameters.validation.visualize:
268
+ self.console_writer.save_metrics(table)
269
+
270
+ return self.metrics, self.plots
@@ -0,0 +1,53 @@
1
+ from edgefirst.validator.evaluators.parameters.core import Parameters, CommonParameters
2
+ from edgefirst.validator.evaluators.parameters.model import ModelParameters
3
+ from edgefirst.validator.evaluators.parameters.dataset import DatasetParameters
4
+ from edgefirst.validator.evaluators.parameters.validation import ValidationParameters
5
+
6
+
7
+ class CombinedParameters:
8
+ """
9
+ Container for both model and validation parameters.
10
+
11
+ Parameters
12
+ -----------
13
+ model_parameters: ModelParameters
14
+ This is a container of the model parameters.
15
+ dataset_parameters: DatasetParameters
16
+ This is a container of teh dataset parameters.
17
+ validation_parameters: ValidationParameters
18
+ This is a containter of the validation parameters.
19
+ """
20
+
21
+ def __init__(
22
+ self,
23
+ model_parameters: ModelParameters = None,
24
+ dataset_parameters: DatasetParameters = None,
25
+ validation_parameters: ValidationParameters = None
26
+ ):
27
+ common_parameters = CommonParameters()
28
+ if model_parameters is None:
29
+ model_parameters = ModelParameters(
30
+ common_parameters=common_parameters)
31
+ if dataset_parameters is None:
32
+ dataset_parameters = DatasetParameters(
33
+ common_parameters=common_parameters)
34
+ if validation_parameters is None:
35
+ validation_parameters = ValidationParameters()
36
+
37
+ self.model = model_parameters
38
+ self.dataset = dataset_parameters
39
+ self.validation = validation_parameters
40
+
41
+ def to_dict(self):
42
+ """
43
+ Store the parameters as a dictionary.
44
+ """
45
+ return {
46
+ "nms": self.model.nms,
47
+ "nms_max_detections": self.model.max_detections,
48
+ "nms_iou_threshold": self.model.iou_threshold,
49
+ "nms_score_threshold": self.model.score_threshold,
50
+ "normalization": self.model.common.norm,
51
+ "preprocessing": self.model.common.preprocessing,
52
+ "method": self.validation.method
53
+ }