valor-lite 0.33.2__tar.gz → 0.33.4__tar.gz
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.
Potentially problematic release.
This version of valor-lite might be problematic. Click here for more details.
- {valor_lite-0.33.2 → valor_lite-0.33.4}/PKG-INFO +2 -1
- {valor_lite-0.33.2 → valor_lite-0.33.4}/benchmarks/benchmark_objdet.py +39 -15
- {valor_lite-0.33.2 → valor_lite-0.33.4}/pyproject.toml +1 -0
- {valor_lite-0.33.2 → valor_lite-0.33.4}/tests/detection/conftest.py +214 -13
- {valor_lite-0.33.2 → valor_lite-0.33.4}/tests/detection/test_average_precision.py +302 -280
- {valor_lite-0.33.2 → valor_lite-0.33.4}/tests/detection/test_average_recall.py +212 -190
- {valor_lite-0.33.2 → valor_lite-0.33.4}/tests/detection/test_counts.py +220 -200
- valor_lite-0.33.4/tests/detection/test_dataloader.py +171 -0
- {valor_lite-0.33.2 → valor_lite-0.33.4}/tests/detection/test_detailed_counts.py +494 -639
- {valor_lite-0.33.2 → valor_lite-0.33.4}/tests/detection/test_evaluator.py +25 -3
- {valor_lite-0.33.2 → valor_lite-0.33.4}/tests/detection/test_filtering.py +115 -4
- valor_lite-0.33.4/tests/detection/test_iou.py +522 -0
- {valor_lite-0.33.2 → valor_lite-0.33.4}/tests/detection/test_pr_curve.py +1 -1
- {valor_lite-0.33.2 → valor_lite-0.33.4}/tests/detection/test_precision.py +102 -96
- {valor_lite-0.33.2 → valor_lite-0.33.4}/tests/detection/test_recall.py +102 -96
- {valor_lite-0.33.2 → valor_lite-0.33.4}/tests/detection/test_schemas.py +60 -4
- {valor_lite-0.33.2 → valor_lite-0.33.4}/tests/detection/test_stability.py +2 -2
- {valor_lite-0.33.2 → valor_lite-0.33.4}/valor_lite/detection/__init__.py +3 -3
- valor_lite-0.33.4/valor_lite/detection/annotation.py +98 -0
- {valor_lite-0.33.2 → valor_lite-0.33.4}/valor_lite/detection/computation.py +165 -76
- {valor_lite-0.33.2 → valor_lite-0.33.4}/valor_lite/detection/manager.py +610 -286
- {valor_lite-0.33.2 → valor_lite-0.33.4}/valor_lite/detection/metric.py +32 -7
- {valor_lite-0.33.2 → valor_lite-0.33.4}/valor_lite.egg-info/PKG-INFO +2 -1
- {valor_lite-0.33.2 → valor_lite-0.33.4}/valor_lite.egg-info/requires.txt +1 -0
- valor_lite-0.33.2/tests/detection/test_dataloader.py +0 -34
- valor_lite-0.33.2/tests/detection/test_iou.py +0 -30
- valor_lite-0.33.2/valor_lite/detection/annotation.py +0 -54
- {valor_lite-0.33.2 → valor_lite-0.33.4}/LICENSE +0 -0
- {valor_lite-0.33.2 → valor_lite-0.33.4}/README.md +0 -0
- {valor_lite-0.33.2 → valor_lite-0.33.4}/benchmarks/.gitignore +0 -0
- {valor_lite-0.33.2 → valor_lite-0.33.4}/examples/.gitignore +0 -0
- {valor_lite-0.33.2 → valor_lite-0.33.4}/examples/coco-yolo.ipynb +0 -0
- {valor_lite-0.33.2 → valor_lite-0.33.4}/setup.cfg +0 -0
- {valor_lite-0.33.2 → valor_lite-0.33.4}/tests/detection/__init__.py +0 -0
- {valor_lite-0.33.2 → valor_lite-0.33.4}/valor_lite/__init__.py +0 -0
- {valor_lite-0.33.2 → valor_lite-0.33.4}/valor_lite/schemas.py +0 -0
- {valor_lite-0.33.2 → valor_lite-0.33.4}/valor_lite.egg-info/SOURCES.txt +0 -0
- {valor_lite-0.33.2 → valor_lite-0.33.4}/valor_lite.egg-info/dependency_links.txt +0 -0
- {valor_lite-0.33.2 → valor_lite-0.33.4}/valor_lite.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: valor-lite
|
|
3
|
-
Version: 0.33.
|
|
3
|
+
Version: 0.33.4
|
|
4
4
|
Summary: Compute valor metrics directly in your client.
|
|
5
5
|
License: MIT License
|
|
6
6
|
|
|
@@ -33,6 +33,7 @@ Requires-Dist: importlib_metadata; python_version < "3.8"
|
|
|
33
33
|
Requires-Dist: tqdm
|
|
34
34
|
Requires-Dist: requests
|
|
35
35
|
Requires-Dist: numpy
|
|
36
|
+
Requires-Dist: shapely
|
|
36
37
|
Provides-Extra: test
|
|
37
38
|
Requires-Dist: pytest; extra == "test"
|
|
38
39
|
Requires-Dist: coverage; extra == "test"
|
|
@@ -8,7 +8,7 @@ from time import time
|
|
|
8
8
|
|
|
9
9
|
import requests
|
|
10
10
|
from tqdm import tqdm
|
|
11
|
-
from valor_lite.detection import DataLoader
|
|
11
|
+
from valor_lite.detection import DataLoader, MetricType
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class AnnotationType(str, Enum):
|
|
@@ -113,7 +113,7 @@ def ingest(
|
|
|
113
113
|
elif len(groundtruths) < chunk_size or chunk_size == -1:
|
|
114
114
|
continue
|
|
115
115
|
|
|
116
|
-
timer, _ = time_it(manager.
|
|
116
|
+
timer, _ = time_it(manager.add_bounding_boxes_from_valor_dict)(
|
|
117
117
|
zip(groundtruths, predictions), True
|
|
118
118
|
)
|
|
119
119
|
accumulated_time += timer
|
|
@@ -121,7 +121,7 @@ def ingest(
|
|
|
121
121
|
predictions = []
|
|
122
122
|
|
|
123
123
|
if groundtruths:
|
|
124
|
-
timer, _ = time_it(manager.
|
|
124
|
+
timer, _ = time_it(manager.add_bounding_boxes_from_valor_dict)(
|
|
125
125
|
zip(groundtruths, predictions), True
|
|
126
126
|
)
|
|
127
127
|
accumulated_time += timer
|
|
@@ -258,24 +258,48 @@ def run_benchmarking_analysis(
|
|
|
258
258
|
f"Base precomputation timed out with limit of {limit}."
|
|
259
259
|
)
|
|
260
260
|
|
|
261
|
-
#
|
|
262
|
-
detailed_counts_time_no_samples, _ = time_it(
|
|
263
|
-
evaluator.compute_detailed_counts
|
|
264
|
-
)()
|
|
265
|
-
|
|
266
|
-
# test detailed counts with 3 samples
|
|
267
|
-
detailed_counts_time_three_samples, _ = time_it(
|
|
268
|
-
evaluator.compute_detailed_counts
|
|
269
|
-
)(n_samples=3)
|
|
270
|
-
|
|
271
|
-
# evaluate
|
|
261
|
+
# evaluate - base metrics only
|
|
272
262
|
eval_time, metrics = time_it(evaluator.evaluate)()
|
|
273
|
-
# print(metrics)
|
|
274
263
|
if eval_time > evaluation_timeout and evaluation_timeout != -1:
|
|
275
264
|
raise TimeoutError(
|
|
276
265
|
f"Base evaluation timed out with {evaluator.n_datums} datums."
|
|
277
266
|
)
|
|
278
267
|
|
|
268
|
+
# evaluate - base metrics + detailed counts with no samples
|
|
269
|
+
detailed_counts_time_no_samples, metrics = time_it(
|
|
270
|
+
evaluator.evaluate
|
|
271
|
+
)(
|
|
272
|
+
[
|
|
273
|
+
MetricType.DetailedCounts,
|
|
274
|
+
*MetricType.base_metrics(),
|
|
275
|
+
]
|
|
276
|
+
)
|
|
277
|
+
if (
|
|
278
|
+
detailed_counts_time_no_samples > evaluation_timeout
|
|
279
|
+
and evaluation_timeout != -1
|
|
280
|
+
):
|
|
281
|
+
raise TimeoutError(
|
|
282
|
+
f"Detailed evaluation w/ no samples timed out with {evaluator.n_datums} datums."
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
# evaluate - base metrics + detailed counts with 3 samples
|
|
286
|
+
detailed_counts_time_three_samples, metrics = time_it(
|
|
287
|
+
evaluator.evaluate
|
|
288
|
+
)(
|
|
289
|
+
[
|
|
290
|
+
MetricType.DetailedCounts,
|
|
291
|
+
*MetricType.base_metrics(),
|
|
292
|
+
],
|
|
293
|
+
number_of_examples=3,
|
|
294
|
+
)
|
|
295
|
+
if (
|
|
296
|
+
detailed_counts_time_three_samples > evaluation_timeout
|
|
297
|
+
and evaluation_timeout != -1
|
|
298
|
+
):
|
|
299
|
+
raise TimeoutError(
|
|
300
|
+
f"Detailed w/ 3 samples evaluation timed out with {evaluator.n_datums} datums."
|
|
301
|
+
)
|
|
302
|
+
|
|
279
303
|
results.append(
|
|
280
304
|
Benchmark(
|
|
281
305
|
limit=limit,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import numpy as np
|
|
1
2
|
import pytest
|
|
2
|
-
from
|
|
3
|
+
from shapely.geometry import Polygon as ShapelyPolygon
|
|
4
|
+
from valor_lite.detection import Bitmask, BoundingBox, Detection, Polygon
|
|
3
5
|
|
|
4
6
|
|
|
5
7
|
@pytest.fixture
|
|
@@ -32,6 +34,42 @@ def rect5() -> tuple[float, float, float, float]:
|
|
|
32
34
|
return (87, 158, 10, 400)
|
|
33
35
|
|
|
34
36
|
|
|
37
|
+
@pytest.fixture
|
|
38
|
+
def rect1_rotated_5_degrees_around_origin() -> list[tuple[float, float]]:
|
|
39
|
+
"""Box with area = 1500."""
|
|
40
|
+
return [
|
|
41
|
+
(9.090389553440874, 10.833504408394036),
|
|
42
|
+
(58.90012445802815, 15.191291545776945),
|
|
43
|
+
(56.28545217559841, 45.07713248852931),
|
|
44
|
+
(6.475717271011129, 40.7193453511464),
|
|
45
|
+
(9.090389553440874, 10.833504408394036),
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@pytest.fixture
|
|
50
|
+
def rect2_rotated_5_degrees_around_origin() -> list[tuple[float, float]]:
|
|
51
|
+
"""Box with area = 1100."""
|
|
52
|
+
return [
|
|
53
|
+
(14.942920471376183, 1.3073361412148725),
|
|
54
|
+
(69.7336288664222, 6.1009019923360714),
|
|
55
|
+
(67.99051401146903, 26.024795954170983),
|
|
56
|
+
(13.19980561642302, 21.231230103049782),
|
|
57
|
+
(14.942920471376183, 1.3073361412148725),
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@pytest.fixture
|
|
62
|
+
def rect3_rotated_5_degrees_around_origin() -> list[tuple[float, float]]:
|
|
63
|
+
"""Box with area = 57,510."""
|
|
64
|
+
return [
|
|
65
|
+
(85.79738130650527, 17.544496599963715),
|
|
66
|
+
(156.52720487101922, 23.732554335047446),
|
|
67
|
+
(85.9310532454161, 830.6502597893614),
|
|
68
|
+
(15.20122968090216, 824.4622020542777),
|
|
69
|
+
(85.79738130650527, 17.544496599963715),
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
|
|
35
73
|
@pytest.fixture
|
|
36
74
|
def basic_detections(
|
|
37
75
|
rect1: tuple[float, float, float, float],
|
|
@@ -93,6 +131,62 @@ def basic_detections(
|
|
|
93
131
|
]
|
|
94
132
|
|
|
95
133
|
|
|
134
|
+
@pytest.fixture
|
|
135
|
+
def basic_rotated_detections(
|
|
136
|
+
rect1_rotated_5_degrees_around_origin: tuple[float, float, float, float],
|
|
137
|
+
rect2_rotated_5_degrees_around_origin: tuple[float, float, float, float],
|
|
138
|
+
rect3_rotated_5_degrees_around_origin: tuple[float, float, float, float],
|
|
139
|
+
) -> list[Detection]:
|
|
140
|
+
return [
|
|
141
|
+
Detection(
|
|
142
|
+
uid="uid1",
|
|
143
|
+
groundtruths=[
|
|
144
|
+
Polygon(
|
|
145
|
+
shape=ShapelyPolygon(
|
|
146
|
+
rect1_rotated_5_degrees_around_origin
|
|
147
|
+
),
|
|
148
|
+
labels=[("k1", "v1")],
|
|
149
|
+
),
|
|
150
|
+
Polygon(
|
|
151
|
+
shape=ShapelyPolygon(
|
|
152
|
+
rect3_rotated_5_degrees_around_origin
|
|
153
|
+
),
|
|
154
|
+
labels=[("k2", "v2")],
|
|
155
|
+
),
|
|
156
|
+
],
|
|
157
|
+
predictions=[
|
|
158
|
+
Polygon(
|
|
159
|
+
shape=ShapelyPolygon(
|
|
160
|
+
rect1_rotated_5_degrees_around_origin
|
|
161
|
+
),
|
|
162
|
+
labels=[("k1", "v1")],
|
|
163
|
+
scores=[0.3],
|
|
164
|
+
),
|
|
165
|
+
],
|
|
166
|
+
),
|
|
167
|
+
Detection(
|
|
168
|
+
uid="uid2",
|
|
169
|
+
groundtruths=[
|
|
170
|
+
Polygon(
|
|
171
|
+
shape=ShapelyPolygon(
|
|
172
|
+
rect2_rotated_5_degrees_around_origin
|
|
173
|
+
),
|
|
174
|
+
labels=[("k1", "v1")],
|
|
175
|
+
),
|
|
176
|
+
],
|
|
177
|
+
predictions=[
|
|
178
|
+
Polygon(
|
|
179
|
+
shape=ShapelyPolygon(
|
|
180
|
+
rect2_rotated_5_degrees_around_origin
|
|
181
|
+
),
|
|
182
|
+
labels=[("k2", "v2")],
|
|
183
|
+
scores=[0.98],
|
|
184
|
+
),
|
|
185
|
+
],
|
|
186
|
+
),
|
|
187
|
+
]
|
|
188
|
+
|
|
189
|
+
|
|
96
190
|
@pytest.fixture
|
|
97
191
|
def torchmetrics_detections() -> list[Detection]:
|
|
98
192
|
"""Creates a model called "test_model" with some predicted
|
|
@@ -309,9 +403,9 @@ def false_negatives_single_datum_detections() -> list[Detection]:
|
|
|
309
403
|
|
|
310
404
|
|
|
311
405
|
@pytest.fixture
|
|
312
|
-
def false_negatives_two_datums_one_empty_low_confidence_of_fp_detections() ->
|
|
313
|
-
Detection
|
|
314
|
-
|
|
406
|
+
def false_negatives_two_datums_one_empty_low_confidence_of_fp_detections() -> (
|
|
407
|
+
list[Detection]
|
|
408
|
+
):
|
|
315
409
|
|
|
316
410
|
return [
|
|
317
411
|
Detection(
|
|
@@ -354,9 +448,9 @@ def false_negatives_two_datums_one_empty_low_confidence_of_fp_detections() -> li
|
|
|
354
448
|
|
|
355
449
|
|
|
356
450
|
@pytest.fixture
|
|
357
|
-
def false_negatives_two_datums_one_empty_high_confidence_of_fp_detections() ->
|
|
358
|
-
Detection
|
|
359
|
-
|
|
451
|
+
def false_negatives_two_datums_one_empty_high_confidence_of_fp_detections() -> (
|
|
452
|
+
list[Detection]
|
|
453
|
+
):
|
|
360
454
|
|
|
361
455
|
return [
|
|
362
456
|
Detection(
|
|
@@ -399,9 +493,9 @@ def false_negatives_two_datums_one_empty_high_confidence_of_fp_detections() -> l
|
|
|
399
493
|
|
|
400
494
|
|
|
401
495
|
@pytest.fixture
|
|
402
|
-
def false_negatives_two_datums_one_only_with_different_class_low_confidence_of_fp_detections() ->
|
|
403
|
-
Detection
|
|
404
|
-
|
|
496
|
+
def false_negatives_two_datums_one_only_with_different_class_low_confidence_of_fp_detections() -> (
|
|
497
|
+
list[Detection]
|
|
498
|
+
):
|
|
405
499
|
|
|
406
500
|
return [
|
|
407
501
|
Detection(
|
|
@@ -452,9 +546,9 @@ def false_negatives_two_datums_one_only_with_different_class_low_confidence_of_f
|
|
|
452
546
|
|
|
453
547
|
|
|
454
548
|
@pytest.fixture
|
|
455
|
-
def false_negatives_two_images_one_only_with_different_class_high_confidence_of_fp_detections() ->
|
|
456
|
-
Detection
|
|
457
|
-
|
|
549
|
+
def false_negatives_two_images_one_only_with_different_class_high_confidence_of_fp_detections() -> (
|
|
550
|
+
list[Detection]
|
|
551
|
+
):
|
|
458
552
|
|
|
459
553
|
return [
|
|
460
554
|
Detection(
|
|
@@ -674,6 +768,113 @@ def detection_ranked_pair_ordering() -> Detection:
|
|
|
674
768
|
)
|
|
675
769
|
|
|
676
770
|
|
|
771
|
+
@pytest.fixture
|
|
772
|
+
def detection_ranked_pair_ordering_with_bitmasks() -> Detection:
|
|
773
|
+
|
|
774
|
+
gts = {
|
|
775
|
+
"bitmasks": [
|
|
776
|
+
np.ones((80, 32), dtype=bool),
|
|
777
|
+
np.ones((80, 32), dtype=bool),
|
|
778
|
+
np.ones((80, 32), dtype=bool),
|
|
779
|
+
],
|
|
780
|
+
"label_values": ["label1", "label2", "label3"],
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
# labels 1 and 2 have IOU==1, labels 3 and 4 have IOU==0
|
|
784
|
+
preds = {
|
|
785
|
+
"bitmasks": [
|
|
786
|
+
np.ones((80, 32), dtype=bool),
|
|
787
|
+
np.ones((80, 32), dtype=bool),
|
|
788
|
+
np.zeros((80, 32), dtype=bool),
|
|
789
|
+
np.zeros((80, 32), dtype=bool),
|
|
790
|
+
],
|
|
791
|
+
"label_values": ["label1", "label2", "label3", "label4"],
|
|
792
|
+
"scores": [
|
|
793
|
+
0.3,
|
|
794
|
+
0.93,
|
|
795
|
+
0.92,
|
|
796
|
+
0.94,
|
|
797
|
+
],
|
|
798
|
+
}
|
|
799
|
+
groundtruths = [
|
|
800
|
+
Bitmask(
|
|
801
|
+
mask=mask,
|
|
802
|
+
labels=[("class", label_value)],
|
|
803
|
+
)
|
|
804
|
+
for mask, label_value in zip(gts["bitmasks"], gts["label_values"])
|
|
805
|
+
]
|
|
806
|
+
|
|
807
|
+
predictions = [
|
|
808
|
+
Bitmask(
|
|
809
|
+
mask=mask,
|
|
810
|
+
labels=[("class", label_value)],
|
|
811
|
+
scores=[score],
|
|
812
|
+
)
|
|
813
|
+
for mask, label_value, score in zip(
|
|
814
|
+
preds["bitmasks"], preds["label_values"], preds["scores"]
|
|
815
|
+
)
|
|
816
|
+
]
|
|
817
|
+
|
|
818
|
+
return Detection(
|
|
819
|
+
uid="uid1", groundtruths=groundtruths, predictions=predictions
|
|
820
|
+
)
|
|
821
|
+
|
|
822
|
+
|
|
823
|
+
@pytest.fixture
|
|
824
|
+
def detection_ranked_pair_ordering_with_polygons(
|
|
825
|
+
rect1_rotated_5_degrees_around_origin: list[tuple[float, float]],
|
|
826
|
+
rect3_rotated_5_degrees_around_origin: list[tuple[float, float]],
|
|
827
|
+
) -> Detection:
|
|
828
|
+
gts = {
|
|
829
|
+
"polygons": [
|
|
830
|
+
rect1_rotated_5_degrees_around_origin,
|
|
831
|
+
rect1_rotated_5_degrees_around_origin,
|
|
832
|
+
rect1_rotated_5_degrees_around_origin,
|
|
833
|
+
],
|
|
834
|
+
"label_values": ["label1", "label2", "label3"],
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
# labels 1 and 2 have IOU==1, labels 3 and 4 have IOU==0
|
|
838
|
+
preds = {
|
|
839
|
+
"polygons": [
|
|
840
|
+
rect1_rotated_5_degrees_around_origin,
|
|
841
|
+
rect1_rotated_5_degrees_around_origin,
|
|
842
|
+
rect3_rotated_5_degrees_around_origin,
|
|
843
|
+
rect3_rotated_5_degrees_around_origin,
|
|
844
|
+
],
|
|
845
|
+
"label_values": ["label1", "label2", "label3", "label4"],
|
|
846
|
+
"scores": [
|
|
847
|
+
0.3,
|
|
848
|
+
0.93,
|
|
849
|
+
0.92,
|
|
850
|
+
0.94,
|
|
851
|
+
],
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
groundtruths = [
|
|
855
|
+
Polygon(
|
|
856
|
+
shape=ShapelyPolygon(polygon),
|
|
857
|
+
labels=[("class", label_value)],
|
|
858
|
+
)
|
|
859
|
+
for polygon, label_value in zip(gts["polygons"], gts["label_values"])
|
|
860
|
+
]
|
|
861
|
+
|
|
862
|
+
predictions = [
|
|
863
|
+
Polygon(
|
|
864
|
+
shape=ShapelyPolygon(polygon),
|
|
865
|
+
labels=[("class", label_value)],
|
|
866
|
+
scores=[score],
|
|
867
|
+
)
|
|
868
|
+
for polygon, label_value, score in zip(
|
|
869
|
+
preds["polygons"], preds["label_values"], preds["scores"]
|
|
870
|
+
)
|
|
871
|
+
]
|
|
872
|
+
|
|
873
|
+
return Detection(
|
|
874
|
+
uid="uid1", groundtruths=groundtruths, predictions=predictions
|
|
875
|
+
)
|
|
876
|
+
|
|
877
|
+
|
|
677
878
|
@pytest.fixture
|
|
678
879
|
def detections_no_groundtruths() -> list[Detection]:
|
|
679
880
|
return [
|