valor-lite 0.33.8__tar.gz → 0.33.10__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.

Files changed (95) hide show
  1. valor_lite-0.33.10/PKG-INFO +179 -0
  2. valor_lite-0.33.10/README.md +139 -0
  3. {valor_lite-0.33.8 → valor_lite-0.33.10}/benchmarks/benchmark_classification.py +42 -24
  4. {valor_lite-0.33.8 → valor_lite-0.33.10}/benchmarks/benchmark_objdet.py +85 -29
  5. valor_lite-0.33.10/examples/object-detection.ipynb +3019 -0
  6. valor_lite-0.33.10/examples/tabular_classification.ipynb +618 -0
  7. {valor_lite-0.33.8 → valor_lite-0.33.10}/pyproject.toml +1 -1
  8. {valor_lite-0.33.8 → valor_lite-0.33.10}/tests/classification/test_confusion_matrix.py +7 -19
  9. valor_lite-0.33.10/tests/classification/test_dataloader.py +18 -0
  10. valor_lite-0.33.10/tests/classification/test_evaluator.py +63 -0
  11. {valor_lite-0.33.8/tests/detection → valor_lite-0.33.10/tests/object_detection}/conftest.py +6 -1
  12. {valor_lite-0.33.8/tests/detection → valor_lite-0.33.10/tests/object_detection}/test_average_precision.py +2 -2
  13. {valor_lite-0.33.8/tests/detection → valor_lite-0.33.10/tests/object_detection}/test_average_recall.py +2 -2
  14. {valor_lite-0.33.8/tests/detection → valor_lite-0.33.10/tests/object_detection}/test_confusion_matrix.py +10 -22
  15. {valor_lite-0.33.8/tests/detection → valor_lite-0.33.10/tests/object_detection}/test_counts.py +1 -1
  16. valor_lite-0.33.10/tests/object_detection/test_dataloader.py +93 -0
  17. {valor_lite-0.33.8/tests/detection → valor_lite-0.33.10/tests/object_detection}/test_evaluator.py +33 -19
  18. {valor_lite-0.33.8/tests/detection → valor_lite-0.33.10/tests/object_detection}/test_filtering.py +10 -5
  19. {valor_lite-0.33.8/tests/detection → valor_lite-0.33.10/tests/object_detection}/test_iou.py +1 -1
  20. valor_lite-0.33.10/tests/object_detection/test_pr_curve.py +233 -0
  21. {valor_lite-0.33.8/tests/detection → valor_lite-0.33.10/tests/object_detection}/test_precision.py +1 -1
  22. {valor_lite-0.33.8/tests/detection → valor_lite-0.33.10/tests/object_detection}/test_recall.py +1 -1
  23. {valor_lite-0.33.8/tests/detection → valor_lite-0.33.10/tests/object_detection}/test_schemas.py +6 -1
  24. {valor_lite-0.33.8/tests/detection → valor_lite-0.33.10/tests/object_detection}/test_stability.py +1 -1
  25. {valor_lite-0.33.8/tests/segmentation → valor_lite-0.33.10/tests/semantic_segmentation}/conftest.py +2 -40
  26. {valor_lite-0.33.8/tests/segmentation → valor_lite-0.33.10/tests/semantic_segmentation}/test_accuracy.py +1 -1
  27. {valor_lite-0.33.8/tests/segmentation → valor_lite-0.33.10/tests/semantic_segmentation}/test_annotation.py +1 -1
  28. {valor_lite-0.33.8/tests/segmentation → valor_lite-0.33.10/tests/semantic_segmentation}/test_confusion_matrix.py +13 -9
  29. {valor_lite-0.33.8/tests/segmentation → valor_lite-0.33.10/tests/semantic_segmentation}/test_dataloader.py +1 -1
  30. valor_lite-0.33.10/tests/semantic_segmentation/test_evaluator.py +66 -0
  31. {valor_lite-0.33.8/tests/segmentation → valor_lite-0.33.10/tests/semantic_segmentation}/test_f1.py +6 -1
  32. {valor_lite-0.33.8/tests/segmentation → valor_lite-0.33.10/tests/semantic_segmentation}/test_filtering.py +1 -1
  33. {valor_lite-0.33.8/tests/segmentation → valor_lite-0.33.10/tests/semantic_segmentation}/test_iou.py +1 -1
  34. {valor_lite-0.33.8/tests/segmentation → valor_lite-0.33.10/tests/semantic_segmentation}/test_precision.py +1 -1
  35. {valor_lite-0.33.8/tests/segmentation → valor_lite-0.33.10/tests/semantic_segmentation}/test_recall.py +1 -1
  36. {valor_lite-0.33.8/tests/segmentation → valor_lite-0.33.10/tests/semantic_segmentation}/test_stability.py +1 -1
  37. valor_lite-0.33.10/valor_lite/LICENSE +21 -0
  38. valor_lite-0.33.10/valor_lite/__init__.py +0 -0
  39. valor_lite-0.33.10/valor_lite/classification/annotation.py +41 -0
  40. {valor_lite-0.33.8 → valor_lite-0.33.10}/valor_lite/classification/manager.py +189 -217
  41. valor_lite-0.33.10/valor_lite/classification/metric.py +414 -0
  42. {valor_lite-0.33.8/valor_lite/detection → valor_lite-0.33.10/valor_lite/object_detection}/annotation.py +144 -3
  43. {valor_lite-0.33.8/valor_lite/detection → valor_lite-0.33.10/valor_lite/object_detection}/computation.py +33 -9
  44. {valor_lite-0.33.8/valor_lite/detection → valor_lite-0.33.10/valor_lite/object_detection}/manager.py +289 -368
  45. valor_lite-0.33.10/valor_lite/object_detection/metric.py +795 -0
  46. valor_lite-0.33.10/valor_lite/semantic_segmentation/annotation.py +96 -0
  47. {valor_lite-0.33.8/valor_lite/segmentation → valor_lite-0.33.10/valor_lite/semantic_segmentation}/manager.py +33 -16
  48. valor_lite-0.33.10/valor_lite/semantic_segmentation/metric.py +278 -0
  49. valor_lite-0.33.10/valor_lite/text_generation/__init__.py +0 -0
  50. valor_lite-0.33.10/valor_lite.egg-info/PKG-INFO +179 -0
  51. valor_lite-0.33.10/valor_lite.egg-info/SOURCES.txt +77 -0
  52. valor_lite-0.33.8/PKG-INFO +0 -41
  53. valor_lite-0.33.8/README.md +0 -1
  54. valor_lite-0.33.8/examples/object-detection.ipynb +0 -1088
  55. valor_lite-0.33.8/examples/tabular_classification.ipynb +0 -618
  56. valor_lite-0.33.8/tests/classification/test_dataloader.py +0 -38
  57. valor_lite-0.33.8/tests/classification/test_evaluator.py +0 -25
  58. valor_lite-0.33.8/tests/detection/test_dataloader.py +0 -155
  59. valor_lite-0.33.8/tests/detection/test_pr_curve.py +0 -176
  60. valor_lite-0.33.8/tests/segmentation/test_evaluator.py +0 -29
  61. valor_lite-0.33.8/valor_lite/classification/annotation.py +0 -17
  62. valor_lite-0.33.8/valor_lite/classification/metric.py +0 -175
  63. valor_lite-0.33.8/valor_lite/detection/metric.py +0 -380
  64. valor_lite-0.33.8/valor_lite/segmentation/annotation.py +0 -49
  65. valor_lite-0.33.8/valor_lite/segmentation/metric.py +0 -119
  66. valor_lite-0.33.8/valor_lite.egg-info/PKG-INFO +0 -41
  67. valor_lite-0.33.8/valor_lite.egg-info/SOURCES.txt +0 -74
  68. {valor_lite-0.33.8 → valor_lite-0.33.10}/LICENSE +0 -0
  69. {valor_lite-0.33.8 → valor_lite-0.33.10}/benchmarks/.gitignore +0 -0
  70. {valor_lite-0.33.8 → valor_lite-0.33.10}/examples/.gitignore +0 -0
  71. {valor_lite-0.33.8 → valor_lite-0.33.10}/setup.cfg +0 -0
  72. {valor_lite-0.33.8 → valor_lite-0.33.10}/tests/__init__.py +0 -0
  73. {valor_lite-0.33.8 → valor_lite-0.33.10}/tests/classification/__init__.py +0 -0
  74. {valor_lite-0.33.8 → valor_lite-0.33.10}/tests/classification/conftest.py +0 -0
  75. {valor_lite-0.33.8 → valor_lite-0.33.10}/tests/classification/test_accuracy.py +0 -0
  76. {valor_lite-0.33.8 → valor_lite-0.33.10}/tests/classification/test_counts.py +0 -0
  77. {valor_lite-0.33.8 → valor_lite-0.33.10}/tests/classification/test_f1.py +0 -0
  78. {valor_lite-0.33.8 → valor_lite-0.33.10}/tests/classification/test_filtering.py +0 -0
  79. {valor_lite-0.33.8 → valor_lite-0.33.10}/tests/classification/test_precision.py +0 -0
  80. {valor_lite-0.33.8 → valor_lite-0.33.10}/tests/classification/test_recall.py +0 -0
  81. {valor_lite-0.33.8 → valor_lite-0.33.10}/tests/classification/test_rocauc.py +0 -0
  82. {valor_lite-0.33.8 → valor_lite-0.33.10}/tests/classification/test_schemas.py +0 -0
  83. {valor_lite-0.33.8 → valor_lite-0.33.10}/tests/classification/test_stability.py +0 -0
  84. {valor_lite-0.33.8/tests/detection → valor_lite-0.33.10/tests/object_detection}/__init__.py +0 -0
  85. {valor_lite-0.33.8/tests/segmentation → valor_lite-0.33.10/tests/semantic_segmentation}/__init__.py +0 -0
  86. {valor_lite-0.33.8/valor_lite → valor_lite-0.33.10/tests/text_generation}/__init__.py +0 -0
  87. {valor_lite-0.33.8 → valor_lite-0.33.10}/valor_lite/classification/__init__.py +0 -0
  88. {valor_lite-0.33.8 → valor_lite-0.33.10}/valor_lite/classification/computation.py +0 -0
  89. {valor_lite-0.33.8/valor_lite/detection → valor_lite-0.33.10/valor_lite/object_detection}/__init__.py +0 -0
  90. {valor_lite-0.33.8 → valor_lite-0.33.10}/valor_lite/schemas.py +0 -0
  91. {valor_lite-0.33.8/valor_lite/segmentation → valor_lite-0.33.10/valor_lite/semantic_segmentation}/__init__.py +0 -0
  92. {valor_lite-0.33.8/valor_lite/segmentation → valor_lite-0.33.10/valor_lite/semantic_segmentation}/computation.py +0 -0
  93. {valor_lite-0.33.8 → valor_lite-0.33.10}/valor_lite.egg-info/dependency_links.txt +0 -0
  94. {valor_lite-0.33.8 → valor_lite-0.33.10}/valor_lite.egg-info/requires.txt +0 -0
  95. {valor_lite-0.33.8 → valor_lite-0.33.10}/valor_lite.egg-info/top_level.txt +0 -0
@@ -0,0 +1,179 @@
1
+ Metadata-Version: 2.1
2
+ Name: valor-lite
3
+ Version: 0.33.10
4
+ Summary: Compute valor metrics locally.
5
+ License: MIT License
6
+
7
+ Copyright (c) 2023 Striveworks
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+
27
+ Project-URL: homepage, https://www.striveworks.com
28
+ Requires-Python: >=3.10
29
+ Description-Content-Type: text/markdown
30
+ License-File: LICENSE
31
+ Requires-Dist: Pillow>=9.1.0
32
+ Requires-Dist: importlib_metadata; python_version < "3.8"
33
+ Requires-Dist: tqdm
34
+ Requires-Dist: requests
35
+ Requires-Dist: numpy
36
+ Requires-Dist: shapely
37
+ Provides-Extra: test
38
+ Requires-Dist: pytest; extra == "test"
39
+ Requires-Dist: coverage; extra == "test"
40
+
41
+ # valor-lite: Fast, local machine learning evaluation.
42
+
43
+ valor-lite is a lightweight, numpy-based library designed for fast and seamless evaluation of machine learning models. It is optimized for environments where quick, responsive evaluations are essential, whether as part of a larger service or embedded within user-facing tools.
44
+
45
+ valor-lite is maintained by Striveworks, a cutting-edge MLOps company based in Austin, Texas. If you'd like to learn more or have questions, we invite you to connect with us on [Slack](https://striveworks-public.slack.com/join/shared_invite/zt-1a0jx768y-2J1fffN~b4fXYM8GecvOhA#/shared-invite/email) or explore our [GitHub repository](https://github.com/striveworks/valor).
46
+
47
+ For additional details, be sure to check out our user [documentation](https://striveworks.github.io/valor/). We're excited to support you in making the most of Valor!
48
+
49
+ ## Usage
50
+
51
+ ### Classification
52
+
53
+ ```python
54
+ from valor_lite.classification import DataLoader, Classification, MetricType
55
+
56
+ classifications = [
57
+ Classification(
58
+ uid="uid0",
59
+ groundtruth="dog",
60
+ predictions=["dog", "cat", "bird"],
61
+ scores=[0.75, 0.2, 0.05],
62
+ ),
63
+ Classification(
64
+ uid="uid1",
65
+ groundtruth="cat",
66
+ predictions=["dog", "cat", "bird"],
67
+ scores=[0.41, 0.39, 0.1],
68
+ ),
69
+ ]
70
+
71
+ loader = DataLoader()
72
+ loader.add_data(classifications)
73
+ evaluator = loader.finalize()
74
+
75
+ metrics = evaluator.evaluate()
76
+
77
+ assert metrics[MetricType.Precision][0].to_dict() == {
78
+ 'type': 'Precision',
79
+ 'value': [0.5],
80
+ 'parameters': {
81
+ 'score_thresholds': [0.0],
82
+ 'hardmax': True,
83
+ 'label': 'dog'
84
+ }
85
+ }
86
+ ```
87
+
88
+ ### Object Detection
89
+
90
+ ```python
91
+ from valor_lite.object_detection import DataLoader, Detection, BoundingBox, MetricType
92
+
93
+ detections = [
94
+ Detection(
95
+ uid="uid0",
96
+ groundtruths=[
97
+ BoundingBox(
98
+ xmin=0, xmax=10,
99
+ ymin=0, ymax=10,
100
+ labels=["dog"]
101
+ ),
102
+ BoundingBox(
103
+ xmin=20, xmax=30,
104
+ ymin=20, ymax=30,
105
+ labels=["cat"]
106
+ ),
107
+ ],
108
+ predictions=[
109
+ BoundingBox(
110
+ xmin=1, xmax=11,
111
+ ymin=1, ymax=11,
112
+ labels=["dog", "cat", "bird"],
113
+ scores=[0.85, 0.1, 0.05]
114
+ ),
115
+ BoundingBox(
116
+ xmin=21, xmax=31,
117
+ ymin=21, ymax=31,
118
+ labels=["dog", "cat", "bird"],
119
+ scores=[0.34, 0.33, 0.33]
120
+ ),
121
+ ],
122
+ ),
123
+ ]
124
+
125
+ loader = DataLoader()
126
+ loader.add_bounding_boxes(detections)
127
+ evaluator = loader.finalize()
128
+
129
+ metrics = evaluator.evaluate()
130
+
131
+ assert metrics[MetricType.Precision][0].to_dict() == {
132
+ 'type': 'Precision',
133
+ 'value': 0.5,
134
+ 'parameters': {
135
+ 'iou_threshold': 0.5,
136
+ 'score_threshold': 0.5,
137
+ 'label': 'dog'
138
+ }
139
+ }
140
+ ```
141
+
142
+ ### Semantic Segmentation
143
+
144
+ ```python
145
+ import numpy as np
146
+ from valor_lite.semantic_segmentation import DataLoader, Segmentation, Bitmask, MetricType
147
+
148
+ segmentations = [
149
+ Segmentation(
150
+ uid="uid0",
151
+ groundtruths=[
152
+ Bitmask(
153
+ mask=np.random.randint(2, size=(10,10), dtype=np.bool_),
154
+ label="sky",
155
+ ),
156
+ Bitmask(
157
+ mask=np.random.randint(2, size=(10,10), dtype=np.bool_),
158
+ label="ground",
159
+ )
160
+ ],
161
+ predictions=[
162
+ Bitmask(
163
+ mask=np.random.randint(2, size=(10,10), dtype=np.bool_),
164
+ label="sky",
165
+ ),
166
+ Bitmask(
167
+ mask=np.random.randint(2, size=(10,10), dtype=np.bool_),
168
+ label="ground",
169
+ )
170
+ ]
171
+ ),
172
+ ]
173
+
174
+ loader = DataLoader()
175
+ loader.add_data(segmentations)
176
+ evaluator = loader.finalize()
177
+
178
+ print(metrics[MetricType.Precision][0])
179
+ ```
@@ -0,0 +1,139 @@
1
+ # valor-lite: Fast, local machine learning evaluation.
2
+
3
+ valor-lite is a lightweight, numpy-based library designed for fast and seamless evaluation of machine learning models. It is optimized for environments where quick, responsive evaluations are essential, whether as part of a larger service or embedded within user-facing tools.
4
+
5
+ valor-lite is maintained by Striveworks, a cutting-edge MLOps company based in Austin, Texas. If you'd like to learn more or have questions, we invite you to connect with us on [Slack](https://striveworks-public.slack.com/join/shared_invite/zt-1a0jx768y-2J1fffN~b4fXYM8GecvOhA#/shared-invite/email) or explore our [GitHub repository](https://github.com/striveworks/valor).
6
+
7
+ For additional details, be sure to check out our user [documentation](https://striveworks.github.io/valor/). We're excited to support you in making the most of Valor!
8
+
9
+ ## Usage
10
+
11
+ ### Classification
12
+
13
+ ```python
14
+ from valor_lite.classification import DataLoader, Classification, MetricType
15
+
16
+ classifications = [
17
+ Classification(
18
+ uid="uid0",
19
+ groundtruth="dog",
20
+ predictions=["dog", "cat", "bird"],
21
+ scores=[0.75, 0.2, 0.05],
22
+ ),
23
+ Classification(
24
+ uid="uid1",
25
+ groundtruth="cat",
26
+ predictions=["dog", "cat", "bird"],
27
+ scores=[0.41, 0.39, 0.1],
28
+ ),
29
+ ]
30
+
31
+ loader = DataLoader()
32
+ loader.add_data(classifications)
33
+ evaluator = loader.finalize()
34
+
35
+ metrics = evaluator.evaluate()
36
+
37
+ assert metrics[MetricType.Precision][0].to_dict() == {
38
+ 'type': 'Precision',
39
+ 'value': [0.5],
40
+ 'parameters': {
41
+ 'score_thresholds': [0.0],
42
+ 'hardmax': True,
43
+ 'label': 'dog'
44
+ }
45
+ }
46
+ ```
47
+
48
+ ### Object Detection
49
+
50
+ ```python
51
+ from valor_lite.object_detection import DataLoader, Detection, BoundingBox, MetricType
52
+
53
+ detections = [
54
+ Detection(
55
+ uid="uid0",
56
+ groundtruths=[
57
+ BoundingBox(
58
+ xmin=0, xmax=10,
59
+ ymin=0, ymax=10,
60
+ labels=["dog"]
61
+ ),
62
+ BoundingBox(
63
+ xmin=20, xmax=30,
64
+ ymin=20, ymax=30,
65
+ labels=["cat"]
66
+ ),
67
+ ],
68
+ predictions=[
69
+ BoundingBox(
70
+ xmin=1, xmax=11,
71
+ ymin=1, ymax=11,
72
+ labels=["dog", "cat", "bird"],
73
+ scores=[0.85, 0.1, 0.05]
74
+ ),
75
+ BoundingBox(
76
+ xmin=21, xmax=31,
77
+ ymin=21, ymax=31,
78
+ labels=["dog", "cat", "bird"],
79
+ scores=[0.34, 0.33, 0.33]
80
+ ),
81
+ ],
82
+ ),
83
+ ]
84
+
85
+ loader = DataLoader()
86
+ loader.add_bounding_boxes(detections)
87
+ evaluator = loader.finalize()
88
+
89
+ metrics = evaluator.evaluate()
90
+
91
+ assert metrics[MetricType.Precision][0].to_dict() == {
92
+ 'type': 'Precision',
93
+ 'value': 0.5,
94
+ 'parameters': {
95
+ 'iou_threshold': 0.5,
96
+ 'score_threshold': 0.5,
97
+ 'label': 'dog'
98
+ }
99
+ }
100
+ ```
101
+
102
+ ### Semantic Segmentation
103
+
104
+ ```python
105
+ import numpy as np
106
+ from valor_lite.semantic_segmentation import DataLoader, Segmentation, Bitmask, MetricType
107
+
108
+ segmentations = [
109
+ Segmentation(
110
+ uid="uid0",
111
+ groundtruths=[
112
+ Bitmask(
113
+ mask=np.random.randint(2, size=(10,10), dtype=np.bool_),
114
+ label="sky",
115
+ ),
116
+ Bitmask(
117
+ mask=np.random.randint(2, size=(10,10), dtype=np.bool_),
118
+ label="ground",
119
+ )
120
+ ],
121
+ predictions=[
122
+ Bitmask(
123
+ mask=np.random.randint(2, size=(10,10), dtype=np.bool_),
124
+ label="sky",
125
+ ),
126
+ Bitmask(
127
+ mask=np.random.randint(2, size=(10,10), dtype=np.bool_),
128
+ label="ground",
129
+ )
130
+ ]
131
+ ),
132
+ ]
133
+
134
+ loader = DataLoader()
135
+ loader.add_data(segmentations)
136
+ evaluator = loader.finalize()
137
+
138
+ print(metrics[MetricType.Precision][0])
139
+ ```
@@ -7,7 +7,29 @@ from time import time
7
7
 
8
8
  import requests
9
9
  from tqdm import tqdm
10
- from valor_lite.classification import DataLoader, MetricType
10
+ from valor_lite.classification import Classification, DataLoader
11
+
12
+
13
+ def _convert_valor_dicts_into_Classification(gt_dict: dict, pd_dict: dict):
14
+ """Convert a groundtruth dictionary and prediction dictionary into a valor_lite Classification object."""
15
+ pds = []
16
+ scores = []
17
+
18
+ # there's only one annotation / label per groundtruth in the benchmarking data
19
+ gt = gt_dict["annotations"][0]["labels"][0]["value"]
20
+ pds = []
21
+ scores = []
22
+ for pann in pd_dict["annotations"]:
23
+ for valor_label in pann["labels"]:
24
+ pds.append(valor_label["value"])
25
+ scores.append(valor_label["score"])
26
+
27
+ return Classification(
28
+ uid=gt_dict["datum"]["uid"],
29
+ groundtruth=gt,
30
+ predictions=pds,
31
+ scores=scores,
32
+ )
11
33
 
12
34
 
13
35
  def time_it(fn):
@@ -76,35 +98,28 @@ def ingest(
76
98
  with open(gt_path, "r") as gf:
77
99
  with open(pd_path, "r") as pf:
78
100
  count = 0
79
- groundtruths = []
80
- predictions = []
101
+ classifications = []
81
102
  for gline, pline in zip(gf, pf):
82
103
 
83
- # groundtruth
84
104
  gt_dict = json.loads(gline)
85
- groundtruths.append(gt_dict)
86
-
87
- # prediction
88
105
  pd_dict = json.loads(pline)
89
- predictions.append(pd_dict)
90
-
106
+ classifications.append(
107
+ _convert_valor_dicts_into_Classification(
108
+ gt_dict=gt_dict, pd_dict=pd_dict
109
+ )
110
+ )
91
111
  count += 1
92
112
  if count >= limit and limit > 0:
93
113
  break
94
- elif len(groundtruths) < chunk_size or chunk_size == -1:
114
+ elif len(classifications) < chunk_size or chunk_size == -1:
95
115
  continue
96
116
 
97
- timer, _ = time_it(loader.add_data_from_valor_dict)(
98
- zip(groundtruths, predictions), True
99
- )
117
+ timer, _ = time_it(loader.add_data)(classifications)
100
118
  accumulated_time += timer
101
- groundtruths = []
102
- predictions = []
119
+ classifications = []
103
120
 
104
- if groundtruths:
105
- timer, _ = time_it(loader.add_data_from_valor_dict)(
106
- zip(groundtruths, predictions), True
107
- )
121
+ if classifications:
122
+ timer, _ = time_it(loader.add_data)(classifications)
108
123
  accumulated_time += timer
109
124
 
110
125
  return accumulated_time
@@ -196,14 +211,16 @@ def run_benchmarking_analysis(
196
211
  )
197
212
 
198
213
  # evaluate
199
- eval_time, _ = time_it(evaluator.evaluate)()
214
+ eval_time, _ = time_it(evaluator.compute_precision_recall)()
200
215
  if eval_time > evaluation_timeout and evaluation_timeout != -1:
201
216
  raise TimeoutError(
202
217
  f"Base evaluation timed out with {evaluator.n_datums} datums."
203
218
  )
204
219
 
205
- detail_no_examples_time, _ = time_it(evaluator.evaluate)(
206
- metrics_to_return=[*MetricType.base(), MetricType.ConfusionMatrix],
220
+ detail_no_examples_time, _ = time_it(
221
+ evaluator.compute_confusion_matrix
222
+ )(
223
+ number_of_examples=0,
207
224
  )
208
225
  if (
209
226
  detail_no_examples_time > evaluation_timeout
@@ -213,8 +230,9 @@ def run_benchmarking_analysis(
213
230
  f"Base evaluation timed out with {evaluator.n_datums} datums."
214
231
  )
215
232
 
216
- detail_three_examples_time, _ = time_it(evaluator.evaluate)(
217
- metrics_to_return=[*MetricType.base(), MetricType.ConfusionMatrix],
233
+ detail_three_examples_time, _ = time_it(
234
+ evaluator.compute_confusion_matrix
235
+ )(
218
236
  number_of_examples=3,
219
237
  )
220
238
  if (
@@ -8,7 +8,76 @@ from time import time
8
8
 
9
9
  import requests
10
10
  from tqdm import tqdm
11
- from valor_lite.detection import DataLoader, MetricType
11
+ from valor_lite.object_detection import BoundingBox, DataLoader, Detection
12
+
13
+
14
+ def _get_bbox_extrema(
15
+ data: list,
16
+ ) -> tuple[float, float, float, float]:
17
+ """Get the bounding box coordinates from a valor Annotation object."""
18
+ x = [point[0] for shape in data for point in shape]
19
+ y = [point[1] for shape in data for point in shape]
20
+ return (min(x), max(x), min(y), max(y))
21
+
22
+
23
+ def _convert_valor_dicts_into_Detection(gt_dict: dict, pd_dict: dict):
24
+ """Convert a groundtruth dictionary and prediction dictionary into a valor_lite Detection object."""
25
+ gts = []
26
+ pds = []
27
+
28
+ for gann in gt_dict["annotations"]:
29
+ labels = []
30
+ for valor_label in gann["labels"]:
31
+ # NOTE: we only include labels where the key is "name"
32
+ if valor_label["key"] != "name":
33
+ continue
34
+
35
+ labels.append(valor_label["value"])
36
+
37
+ # if the annotation doesn't contain any labels that aren't key == 'name', then we skip that annotation
38
+ if not labels:
39
+ continue
40
+
41
+ x_min, x_max, y_min, y_max = _get_bbox_extrema(gann["bounding_box"])
42
+
43
+ gts.append(
44
+ BoundingBox(
45
+ xmin=x_min,
46
+ xmax=x_max,
47
+ ymin=y_min,
48
+ ymax=y_max,
49
+ labels=labels,
50
+ )
51
+ )
52
+
53
+ for pann in pd_dict["annotations"]:
54
+ labels, scores = [], []
55
+ for valor_label in pann["labels"]:
56
+ if valor_label["key"] != "name":
57
+ continue
58
+ labels.append(valor_label["value"])
59
+ scores.append(valor_label["score"])
60
+ if not labels:
61
+ continue
62
+
63
+ x_min, x_max, y_min, y_max = _get_bbox_extrema(pann["bounding_box"])
64
+
65
+ pds.append(
66
+ BoundingBox(
67
+ xmin=x_min,
68
+ xmax=x_max,
69
+ ymin=y_min,
70
+ ymax=y_max,
71
+ labels=labels,
72
+ scores=scores,
73
+ )
74
+ )
75
+
76
+ return Detection(
77
+ uid=gt_dict["datum"]["uid"],
78
+ groundtruths=gts,
79
+ predictions=pds,
80
+ )
12
81
 
13
82
 
14
83
  class AnnotationType(str, Enum):
@@ -95,35 +164,29 @@ def ingest(
95
164
  with open(pd_path, "r") as pf:
96
165
 
97
166
  count = 0
98
- groundtruths = []
99
- predictions = []
167
+ detections = []
100
168
  for gline, pline in zip(gf, pf):
101
169
 
102
- # groundtruth
103
170
  gt_dict = json.loads(gline)
104
- groundtruths.append(gt_dict)
105
-
106
- # prediction
107
171
  pd_dict = json.loads(pline)
108
- predictions.append(pd_dict)
172
+ detections.append(
173
+ _convert_valor_dicts_into_Detection(
174
+ gt_dict=gt_dict, pd_dict=pd_dict
175
+ )
176
+ )
109
177
 
110
178
  count += 1
111
179
  if count >= limit and limit > 0:
112
180
  break
113
- elif len(groundtruths) < chunk_size or chunk_size == -1:
181
+ elif len(detections) < chunk_size or chunk_size == -1:
114
182
  continue
115
183
 
116
- timer, _ = time_it(manager.add_bounding_boxes_from_valor_dict)(
117
- zip(groundtruths, predictions), True
118
- )
184
+ timer, _ = time_it(manager.add_bounding_boxes)(detections)
119
185
  accumulated_time += timer
120
- groundtruths = []
121
- predictions = []
186
+ detections = []
122
187
 
123
- if groundtruths:
124
- timer, _ = time_it(manager.add_bounding_boxes_from_valor_dict)(
125
- zip(groundtruths, predictions), True
126
- )
188
+ if detections:
189
+ timer, _ = time_it(manager.add_bounding_boxes)(detections)
127
190
  accumulated_time += timer
128
191
 
129
192
  return accumulated_time
@@ -259,7 +322,7 @@ def run_benchmarking_analysis(
259
322
  )
260
323
 
261
324
  # evaluate - base metrics only
262
- eval_time, metrics = time_it(evaluator.evaluate)()
325
+ eval_time, metrics = time_it(evaluator.compute_precision_recall)()
263
326
  if eval_time > evaluation_timeout and evaluation_timeout != -1:
264
327
  raise TimeoutError(
265
328
  f"Base evaluation timed out with {evaluator.n_datums} datums."
@@ -267,12 +330,9 @@ def run_benchmarking_analysis(
267
330
 
268
331
  # evaluate - base metrics + detailed counts with no samples
269
332
  detailed_counts_time_no_samples, metrics = time_it(
270
- evaluator.evaluate
333
+ evaluator.compute_confusion_matrix
271
334
  )(
272
- [
273
- MetricType.ConfusionMatrix,
274
- *MetricType.base_metrics(),
275
- ]
335
+ number_of_examples=0,
276
336
  )
277
337
  if (
278
338
  detailed_counts_time_no_samples > evaluation_timeout
@@ -284,12 +344,8 @@ def run_benchmarking_analysis(
284
344
 
285
345
  # evaluate - base metrics + detailed counts with 3 samples
286
346
  detailed_counts_time_three_samples, metrics = time_it(
287
- evaluator.evaluate
347
+ evaluator.compute_confusion_matrix
288
348
  )(
289
- [
290
- MetricType.ConfusionMatrix,
291
- *MetricType.base_metrics(),
292
- ],
293
349
  number_of_examples=3,
294
350
  )
295
351
  if (