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.
- deepview/modelpack/utils/argmax.py +16 -0
- edgefirst/validator/__init__.py +1 -0
- edgefirst/validator/__main__.py +375 -0
- edgefirst/validator/datasets/__init__.py +118 -0
- edgefirst/validator/datasets/cache.py +296 -0
- edgefirst/validator/datasets/core.py +250 -0
- edgefirst/validator/datasets/darknet.py +446 -0
- edgefirst/validator/datasets/database.py +1067 -0
- edgefirst/validator/datasets/instance/__init__.py +4 -0
- edgefirst/validator/datasets/instance/core.py +222 -0
- edgefirst/validator/datasets/instance/detection.py +145 -0
- edgefirst/validator/datasets/instance/multitask.py +80 -0
- edgefirst/validator/datasets/instance/segmentation.py +120 -0
- edgefirst/validator/datasets/utils/fetch.py +682 -0
- edgefirst/validator/datasets/utils/readers.py +425 -0
- edgefirst/validator/datasets/utils/transformations.py +1695 -0
- edgefirst/validator/evaluators/__init__.py +17 -0
- edgefirst/validator/evaluators/callbacks/__init__.py +3 -0
- edgefirst/validator/evaluators/callbacks/core.py +192 -0
- edgefirst/validator/evaluators/callbacks/plots.py +900 -0
- edgefirst/validator/evaluators/callbacks/studio.py +234 -0
- edgefirst/validator/evaluators/core.py +257 -0
- edgefirst/validator/evaluators/detection.py +749 -0
- edgefirst/validator/evaluators/multitask.py +270 -0
- edgefirst/validator/evaluators/parameters/__init__.py +53 -0
- edgefirst/validator/evaluators/parameters/core.py +554 -0
- edgefirst/validator/evaluators/parameters/dataset.py +239 -0
- edgefirst/validator/evaluators/parameters/model.py +338 -0
- edgefirst/validator/evaluators/parameters/validation.py +528 -0
- edgefirst/validator/evaluators/segmentation.py +729 -0
- edgefirst/validator/evaluators/utils/__init__.py +3 -0
- edgefirst/validator/evaluators/utils/classify.py +292 -0
- edgefirst/validator/evaluators/utils/match.py +262 -0
- edgefirst/validator/evaluators/utils/timer.py +132 -0
- edgefirst/validator/metrics/__init__.py +9 -0
- edgefirst/validator/metrics/data/__init__.py +7 -0
- edgefirst/validator/metrics/data/label.py +668 -0
- edgefirst/validator/metrics/data/metrics.py +759 -0
- edgefirst/validator/metrics/data/plots.py +476 -0
- edgefirst/validator/metrics/data/stats.py +507 -0
- edgefirst/validator/metrics/detection.py +595 -0
- edgefirst/validator/metrics/segmentation.py +173 -0
- edgefirst/validator/metrics/utils/math.py +717 -0
- edgefirst/validator/publishers/__init__.py +3 -0
- edgefirst/validator/publishers/console.py +147 -0
- edgefirst/validator/publishers/studio.py +128 -0
- edgefirst/validator/publishers/tensorboard.py +119 -0
- edgefirst/validator/publishers/utils/logger.py +111 -0
- edgefirst/validator/publishers/utils/table.py +403 -0
- edgefirst/validator/runners/__init__.py +8 -0
- edgefirst/validator/runners/core.py +727 -0
- edgefirst/validator/runners/deepviewrt.py +177 -0
- edgefirst/validator/runners/hailo.py +263 -0
- edgefirst/validator/runners/keras.py +150 -0
- edgefirst/validator/runners/kinara.py +265 -0
- edgefirst/validator/runners/offline.py +228 -0
- edgefirst/validator/runners/onnx.py +241 -0
- edgefirst/validator/runners/processing/decode.py +320 -0
- edgefirst/validator/runners/processing/dvapi.py +4192 -0
- edgefirst/validator/runners/processing/nms.py +637 -0
- edgefirst/validator/runners/processing/outputs.py +507 -0
- edgefirst/validator/runners/tensorrt.py +321 -0
- edgefirst/validator/runners/tflite.py +221 -0
- edgefirst/validator/validate.py +843 -0
- edgefirst/validator/visualize/__init__.py +3 -0
- edgefirst/validator/visualize/detection.py +623 -0
- edgefirst/validator/visualize/segmentation.py +281 -0
- edgefirst/validator/visualize/utils/plots.py +635 -0
- edgefirst_validator-4.2.1.dist-info/METADATA +111 -0
- edgefirst_validator-4.2.1.dist-info/RECORD +73 -0
- edgefirst_validator-4.2.1.dist-info/WHEEL +5 -0
- edgefirst_validator-4.2.1.dist-info/entry_points.txt +2 -0
- 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
|
+
}
|