valor-lite 0.33.16__tar.gz → 0.33.17__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 (120) hide show
  1. {valor_lite-0.33.16 → valor_lite-0.33.17}/PKG-INFO +1 -1
  2. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/test_dataloader.py +55 -4
  3. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/semantic_segmentation/test_confusion_matrix.py +62 -0
  4. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/object_detection/annotation.py +0 -24
  5. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/object_detection/manager.py +71 -80
  6. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/semantic_segmentation/computation.py +2 -2
  7. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite.egg-info/PKG-INFO +1 -1
  8. {valor_lite-0.33.16 → valor_lite-0.33.17}/LICENSE +0 -0
  9. {valor_lite-0.33.16 → valor_lite-0.33.17}/README.md +0 -0
  10. {valor_lite-0.33.16 → valor_lite-0.33.17}/benchmarks/.gitignore +0 -0
  11. {valor_lite-0.33.16 → valor_lite-0.33.17}/benchmarks/benchmark_classification.py +0 -0
  12. {valor_lite-0.33.16 → valor_lite-0.33.17}/benchmarks/benchmark_objdet.py +0 -0
  13. {valor_lite-0.33.16 → valor_lite-0.33.17}/examples/.gitignore +0 -0
  14. {valor_lite-0.33.16 → valor_lite-0.33.17}/examples/object-detection.ipynb +0 -0
  15. {valor_lite-0.33.16 → valor_lite-0.33.17}/examples/tabular_classification.ipynb +0 -0
  16. {valor_lite-0.33.16 → valor_lite-0.33.17}/examples/text_generation.ipynb +0 -0
  17. {valor_lite-0.33.16 → valor_lite-0.33.17}/pyproject.toml +0 -0
  18. {valor_lite-0.33.16 → valor_lite-0.33.17}/setup.cfg +0 -0
  19. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/__init__.py +0 -0
  20. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/classification/__init__.py +0 -0
  21. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/classification/conftest.py +0 -0
  22. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/classification/test_accuracy.py +0 -0
  23. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/classification/test_confusion_matrix.py +0 -0
  24. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/classification/test_counts.py +0 -0
  25. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/classification/test_dataloader.py +0 -0
  26. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/classification/test_evaluator.py +0 -0
  27. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/classification/test_f1.py +0 -0
  28. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/classification/test_filtering.py +0 -0
  29. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/classification/test_metric.py +0 -0
  30. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/classification/test_precision.py +0 -0
  31. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/classification/test_recall.py +0 -0
  32. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/classification/test_rocauc.py +0 -0
  33. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/classification/test_schemas.py +0 -0
  34. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/classification/test_stability.py +0 -0
  35. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/__init__.py +0 -0
  36. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/conftest.py +0 -0
  37. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/test_accuracy.py +0 -0
  38. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/test_average_precision.py +0 -0
  39. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/test_average_recall.py +0 -0
  40. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/test_confusion_matrix.py +0 -0
  41. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/test_counts.py +0 -0
  42. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/test_evaluator.py +0 -0
  43. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/test_f1.py +0 -0
  44. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/test_filtering.py +0 -0
  45. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/test_iou.py +0 -0
  46. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/test_metric.py +0 -0
  47. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/test_pr_curve.py +0 -0
  48. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/test_precision.py +0 -0
  49. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/test_recall.py +0 -0
  50. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/test_schemas.py +0 -0
  51. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/object_detection/test_stability.py +0 -0
  52. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/semantic_segmentation/__init__.py +0 -0
  53. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/semantic_segmentation/conftest.py +0 -0
  54. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/semantic_segmentation/test_accuracy.py +0 -0
  55. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/semantic_segmentation/test_annotation.py +0 -0
  56. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/semantic_segmentation/test_dataloader.py +0 -0
  57. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/semantic_segmentation/test_evaluator.py +0 -0
  58. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/semantic_segmentation/test_f1.py +0 -0
  59. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/semantic_segmentation/test_filtering.py +0 -0
  60. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/semantic_segmentation/test_iou.py +0 -0
  61. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/semantic_segmentation/test_metric.py +0 -0
  62. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/semantic_segmentation/test_precision.py +0 -0
  63. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/semantic_segmentation/test_recall.py +0 -0
  64. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/semantic_segmentation/test_stability.py +0 -0
  65. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/__init__.py +0 -0
  66. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/conftest.py +0 -0
  67. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/llm/__init__.py +0 -0
  68. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/llm/test_generation.py +0 -0
  69. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/llm/test_integrations.py +0 -0
  70. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/llm/test_utilities.py +0 -0
  71. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/llm/test_validators.py +0 -0
  72. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/metrics/test_answer_correctness.py +0 -0
  73. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/metrics/test_answer_relevance.py +0 -0
  74. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/metrics/test_bias.py +0 -0
  75. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/metrics/test_context_precision.py +0 -0
  76. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/metrics/test_context_recall.py +0 -0
  77. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/metrics/test_context_relevance.py +0 -0
  78. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/metrics/test_faithfulness.py +0 -0
  79. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/metrics/test_hallucination.py +0 -0
  80. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/metrics/test_metric.py +0 -0
  81. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/metrics/test_rouge.py +0 -0
  82. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/metrics/test_sentence_bleu.py +0 -0
  83. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/metrics/test_summary_coherence.py +0 -0
  84. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/metrics/test_toxicity.py +0 -0
  85. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/test_evaluator.py +0 -0
  86. {valor_lite-0.33.16 → valor_lite-0.33.17}/tests/text_generation/test_manager.py +0 -0
  87. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/LICENSE +0 -0
  88. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/__init__.py +0 -0
  89. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/classification/__init__.py +0 -0
  90. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/classification/annotation.py +0 -0
  91. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/classification/computation.py +0 -0
  92. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/classification/manager.py +0 -0
  93. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/classification/metric.py +0 -0
  94. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/classification/utilities.py +0 -0
  95. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/object_detection/__init__.py +0 -0
  96. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/object_detection/computation.py +0 -0
  97. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/object_detection/metric.py +0 -0
  98. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/object_detection/utilities.py +0 -0
  99. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/schemas.py +0 -0
  100. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/semantic_segmentation/__init__.py +0 -0
  101. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/semantic_segmentation/annotation.py +0 -0
  102. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/semantic_segmentation/manager.py +0 -0
  103. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/semantic_segmentation/metric.py +0 -0
  104. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/semantic_segmentation/utilities.py +0 -0
  105. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/text_generation/__init__.py +0 -0
  106. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/text_generation/annotation.py +0 -0
  107. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/text_generation/computation.py +0 -0
  108. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/text_generation/llm/__init__.py +0 -0
  109. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/text_generation/llm/exceptions.py +0 -0
  110. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/text_generation/llm/generation.py +0 -0
  111. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/text_generation/llm/instructions.py +0 -0
  112. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/text_generation/llm/integrations.py +0 -0
  113. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/text_generation/llm/utilities.py +0 -0
  114. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/text_generation/llm/validators.py +0 -0
  115. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/text_generation/manager.py +0 -0
  116. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite/text_generation/metric.py +0 -0
  117. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite.egg-info/SOURCES.txt +0 -0
  118. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite.egg-info/dependency_links.txt +0 -0
  119. {valor_lite-0.33.16 → valor_lite-0.33.17}/valor_lite.egg-info/requires.txt +0 -0
  120. {valor_lite-0.33.16 → valor_lite-0.33.17}/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.16
3
+ Version: 0.33.17
4
4
  Summary: Compute valor metrics locally.
5
5
  License: MIT License
6
6
 
@@ -16,6 +16,49 @@ def test_no_data():
16
16
  loader.finalize()
17
17
 
18
18
 
19
+ def test_iou_computation():
20
+
21
+ detection = Detection(
22
+ uid="uid",
23
+ groundtruths=[
24
+ BoundingBox(xmin=0, xmax=10, ymin=0, ymax=10, labels=["0"]),
25
+ BoundingBox(xmin=100, xmax=110, ymin=100, ymax=110, labels=["0"]),
26
+ BoundingBox(
27
+ xmin=1000, xmax=1100, ymin=1000, ymax=1100, labels=["0"]
28
+ ),
29
+ ],
30
+ predictions=[
31
+ BoundingBox(
32
+ xmin=1,
33
+ xmax=11,
34
+ ymin=1,
35
+ ymax=11,
36
+ labels=["0", "1", "2"],
37
+ scores=[0.5, 0.25, 0.25],
38
+ ),
39
+ BoundingBox(
40
+ xmin=105,
41
+ xmax=116,
42
+ ymin=105,
43
+ ymax=116,
44
+ labels=["0", "1", "2"],
45
+ scores=[0.5, 0.25, 0.25],
46
+ ),
47
+ ],
48
+ )
49
+
50
+ loader = DataLoader()
51
+ loader.add_bounding_boxes([detection])
52
+
53
+ assert len(loader.pairs) == 1
54
+
55
+ # show that three unique IOUs exist
56
+ unique_ious = np.unique(loader.pairs[0][:, 3])
57
+ assert np.isclose(
58
+ unique_ious, np.array([0.0, 0.12755102, 0.68067227])
59
+ ).all()
60
+
61
+
19
62
  def test_mixed_annotations(
20
63
  rect1: tuple[float, float, float, float],
21
64
  rect1_rotated_5_degrees_around_origin: tuple[float, float, float, float],
@@ -87,7 +130,15 @@ def test_mixed_annotations(
87
130
 
88
131
  loader = DataLoader()
89
132
 
90
- for input_ in mixed_detections:
91
- with pytest.raises(ValueError) as e:
92
- loader.add_bounding_boxes([input_])
93
- assert "but annotation is of type" in str(e)
133
+ for detection in mixed_detections:
134
+
135
+ # anything can be converted to a bbox
136
+ loader.add_bounding_boxes([detection])
137
+
138
+ with pytest.raises(AttributeError) as e:
139
+ loader.add_polygons([detection])
140
+ assert "no attribute 'shape'" in str(e)
141
+
142
+ with pytest.raises(AttributeError) as e:
143
+ loader.add_bitmasks([detection])
144
+ assert "no attribute 'mask'" in str(e)
@@ -1,4 +1,6 @@
1
+ import numpy as np
1
2
  from valor_lite.semantic_segmentation import (
3
+ Bitmask,
2
4
  DataLoader,
3
5
  MetricType,
4
6
  Segmentation,
@@ -89,3 +91,63 @@ def test_confusion_matrix_segmentations_from_boxes(
89
91
  assert m in expected_metrics
90
92
  for m in expected_metrics:
91
93
  assert m in actual_metrics
94
+
95
+
96
+ def test_confusion_matrix_intermediate_counting():
97
+
98
+ segmentation = Segmentation(
99
+ uid="uid1",
100
+ groundtruths=[
101
+ Bitmask(
102
+ mask=np.array([[False, False], [True, False]]),
103
+ label="a",
104
+ ),
105
+ Bitmask(
106
+ mask=np.array([[False, False], [False, True]]),
107
+ label="b",
108
+ ),
109
+ Bitmask(
110
+ mask=np.array([[True, False], [False, False]]),
111
+ label="c",
112
+ ),
113
+ Bitmask(
114
+ mask=np.array([[False, True], [False, False]]),
115
+ label="d",
116
+ ),
117
+ ],
118
+ predictions=[
119
+ Bitmask(
120
+ mask=np.array([[False, False], [False, False]]),
121
+ label="a",
122
+ ),
123
+ Bitmask(
124
+ mask=np.array([[False, False], [False, False]]),
125
+ label="b",
126
+ ),
127
+ Bitmask(
128
+ mask=np.array([[True, True], [True, True]]),
129
+ label="c",
130
+ ),
131
+ Bitmask(
132
+ mask=np.array([[False, False], [False, False]]),
133
+ label="d",
134
+ ),
135
+ ],
136
+ )
137
+
138
+ loader = DataLoader()
139
+ loader.add_data([segmentation])
140
+
141
+ assert len(loader.matrices) == 1
142
+ assert (
143
+ loader.matrices[0]
144
+ == np.array(
145
+ [
146
+ [0, 0, 0, 0, 0],
147
+ [0, 0, 0, 1, 0],
148
+ [0, 0, 0, 1, 0],
149
+ [0, 0, 0, 1, 0],
150
+ [0, 0, 0, 1, 0],
151
+ ]
152
+ )
153
+ ).all()
@@ -142,18 +142,6 @@ class Polygon:
142
142
  xmin, ymin, xmax, ymax = self.shape.bounds
143
143
  return (xmin, xmax, ymin, ymax)
144
144
 
145
- @property
146
- def annotation(self) -> ShapelyPolygon:
147
- """
148
- Returns the annotation's data representation.
149
-
150
- Returns
151
- -------
152
- shapely.geometry.Polygon
153
- The polygon shape.
154
- """
155
- return self.shape
156
-
157
145
 
158
146
  @dataclass
159
147
  class Bitmask:
@@ -222,18 +210,6 @@ class Bitmask:
222
210
  rows, cols = np.nonzero(self.mask)
223
211
  return (cols.min(), cols.max(), rows.min(), rows.max())
224
212
 
225
- @property
226
- def annotation(self) -> NDArray[np.bool_]:
227
- """
228
- Returns the annotation's data representation.
229
-
230
- Returns
231
- -------
232
- NDArray[np.bool_]
233
- The binary mask array.
234
- """
235
- return self.mask
236
-
237
213
 
238
214
  @dataclass
239
215
  class Detection:
@@ -1,17 +1,10 @@
1
1
  from collections import defaultdict
2
2
  from dataclasses import dataclass
3
- from typing import Type
4
3
 
5
4
  import numpy as np
6
- import valor_lite.object_detection.annotation as annotation
7
5
  from numpy.typing import NDArray
8
6
  from tqdm import tqdm
9
- from valor_lite.object_detection.annotation import (
10
- Bitmask,
11
- BoundingBox,
12
- Detection,
13
- Polygon,
14
- )
7
+ from valor_lite.object_detection.annotation import Detection
15
8
  from valor_lite.object_detection.computation import (
16
9
  compute_bbox_iou,
17
10
  compute_bitmask_iou,
@@ -396,74 +389,47 @@ class DataLoader:
396
389
 
397
390
  return self._evaluator.label_to_index[label]
398
391
 
399
- def _compute_ious_and_cache_pairs(
392
+ def _cache_pairs(
400
393
  self,
401
394
  uid_index: int,
402
395
  groundtruths: list,
403
396
  predictions: list,
404
- annotation_type: Type[BoundingBox] | Type[Polygon] | Type[Bitmask],
397
+ ious: NDArray[np.float64],
405
398
  ) -> None:
406
399
  """
407
400
  Compute IOUs between groundtruths and preditions before storing as pairs.
408
401
 
409
402
  Parameters
410
403
  ----------
411
- uid_index: int
404
+ uid_index : int
412
405
  The index of the detection.
413
- groundtruths: list
406
+ groundtruths : list
414
407
  A list of groundtruths.
415
- predictions: list
408
+ predictions : list
416
409
  A list of predictions.
417
- annotation_type: type[BoundingBox] | type[Polygon] | type[Bitmask]
418
- The type of annotation to compute IOUs for.
410
+ ious : NDArray[np.float64]
411
+ An array with shape (n_preds, n_gts) containing IOUs.
419
412
  """
420
413
 
421
- pairs = list()
422
- n_predictions = len(predictions)
423
- n_groundtruths = len(groundtruths)
424
-
425
- all_pairs = np.array(
426
- [
427
- np.array([gann, pann])
428
- for _, _, _, pann in predictions
429
- for _, _, gann in groundtruths
430
- ]
431
- )
432
-
433
- match annotation_type:
434
- case annotation.BoundingBox:
435
- ious = compute_bbox_iou(all_pairs)
436
- case annotation.Polygon:
437
- ious = compute_polygon_iou(all_pairs)
438
- case annotation.Bitmask:
439
- ious = compute_bitmask_iou(all_pairs)
440
- case _:
441
- raise ValueError(
442
- f"Invalid annotation type `{annotation_type}`."
443
- )
444
-
445
- ious = ious.reshape(n_predictions, n_groundtruths)
446
414
  predictions_with_iou_of_zero = np.where((ious < 1e-9).all(axis=1))[0]
447
415
  groundtruths_with_iou_of_zero = np.where((ious < 1e-9).all(axis=0))[0]
448
416
 
449
- pairs.extend(
450
- [
451
- np.array(
452
- [
453
- float(uid_index),
454
- float(gidx),
455
- float(pidx),
456
- ious[pidx, gidx],
457
- float(glabel),
458
- float(plabel),
459
- float(score),
460
- ]
461
- )
462
- for pidx, plabel, score, _ in predictions
463
- for gidx, glabel, _ in groundtruths
464
- if ious[pidx, gidx] >= 1e-9
465
- ]
466
- )
417
+ pairs = [
418
+ np.array(
419
+ [
420
+ float(uid_index),
421
+ float(gidx),
422
+ float(pidx),
423
+ ious[pidx, gidx],
424
+ float(glabel),
425
+ float(plabel),
426
+ float(score),
427
+ ]
428
+ )
429
+ for pidx, plabel, score in predictions
430
+ for gidx, glabel in groundtruths
431
+ if ious[pidx, gidx] >= 1e-9
432
+ ]
467
433
  pairs.extend(
468
434
  [
469
435
  np.array(
@@ -496,13 +462,12 @@ class DataLoader:
496
462
  for index in groundtruths_with_iou_of_zero
497
463
  ]
498
464
  )
499
-
500
465
  self.pairs.append(np.array(pairs))
501
466
 
502
467
  def _add_data(
503
468
  self,
504
469
  detections: list[Detection],
505
- annotation_type: type[Bitmask] | type[BoundingBox] | type[Polygon],
470
+ detection_ious: list[NDArray[np.float64]],
506
471
  show_progress: bool = False,
507
472
  ):
508
473
  """
@@ -512,13 +477,15 @@ class DataLoader:
512
477
  ----------
513
478
  detections : list[Detection]
514
479
  A list of Detection objects.
515
- annotation_type : type[Bitmask] | type[BoundingBox] | type[Polygon]
516
- The annotation type to process.
480
+ detection_ious : list[NDArray[np.float64]]
481
+ A list of arrays containing IOUs per detection.
517
482
  show_progress : bool, default=False
518
483
  Toggle for tqdm progress bar.
519
484
  """
520
485
  disable_tqdm = not show_progress
521
- for detection in tqdm(detections, disable=disable_tqdm):
486
+ for detection, ious in tqdm(
487
+ zip(detections, detection_ious), disable=disable_tqdm
488
+ ):
522
489
 
523
490
  # update metadata
524
491
  self._evaluator.n_datums += 1
@@ -541,11 +508,6 @@ class DataLoader:
541
508
  predictions = list()
542
509
 
543
510
  for gidx, gann in enumerate(detection.groundtruths):
544
- if not isinstance(gann, annotation_type):
545
- raise ValueError(
546
- f"Expected {annotation_type}, but annotation is of type {type(gann)}."
547
- )
548
-
549
511
  self._evaluator.groundtruth_examples[uid_index][
550
512
  gidx
551
513
  ] = gann.extrema
@@ -556,16 +518,10 @@ class DataLoader:
556
518
  (
557
519
  gidx,
558
520
  label_idx,
559
- gann.annotation,
560
521
  )
561
522
  )
562
523
 
563
524
  for pidx, pann in enumerate(detection.predictions):
564
- if not isinstance(pann, annotation_type):
565
- raise ValueError(
566
- f"Expected {annotation_type}, but annotation is of type {type(pann)}."
567
- )
568
-
569
525
  self._evaluator.prediction_examples[uid_index][
570
526
  pidx
571
527
  ] = pann.extrema
@@ -577,15 +533,14 @@ class DataLoader:
577
533
  pidx,
578
534
  label_idx,
579
535
  pscore,
580
- pann.annotation,
581
536
  )
582
537
  )
583
538
 
584
- self._compute_ious_and_cache_pairs(
539
+ self._cache_pairs(
585
540
  uid_index=uid_index,
586
541
  groundtruths=groundtruths,
587
542
  predictions=predictions,
588
- annotation_type=annotation_type,
543
+ ious=ious,
589
544
  )
590
545
 
591
546
  def add_bounding_boxes(
@@ -603,10 +558,22 @@ class DataLoader:
603
558
  show_progress : bool, default=False
604
559
  Toggle for tqdm progress bar.
605
560
  """
561
+ ious = [
562
+ compute_bbox_iou(
563
+ np.array(
564
+ [
565
+ [gt.extrema, pd.extrema]
566
+ for pd in detection.predictions
567
+ for gt in detection.groundtruths
568
+ ]
569
+ )
570
+ ).reshape(len(detection.predictions), len(detection.groundtruths))
571
+ for detection in detections
572
+ ]
606
573
  return self._add_data(
607
574
  detections=detections,
575
+ detection_ious=ious,
608
576
  show_progress=show_progress,
609
- annotation_type=BoundingBox,
610
577
  )
611
578
 
612
579
  def add_polygons(
@@ -624,10 +591,22 @@ class DataLoader:
624
591
  show_progress : bool, default=False
625
592
  Toggle for tqdm progress bar.
626
593
  """
594
+ ious = [
595
+ compute_polygon_iou(
596
+ np.array(
597
+ [
598
+ [gt.shape, pd.shape] # type: ignore - using the AttributeError as a validator
599
+ for pd in detection.predictions
600
+ for gt in detection.groundtruths
601
+ ]
602
+ )
603
+ ).reshape(len(detection.predictions), len(detection.groundtruths))
604
+ for detection in detections
605
+ ]
627
606
  return self._add_data(
628
607
  detections=detections,
608
+ detection_ious=ious,
629
609
  show_progress=show_progress,
630
- annotation_type=Polygon,
631
610
  )
632
611
 
633
612
  def add_bitmasks(
@@ -645,10 +624,22 @@ class DataLoader:
645
624
  show_progress : bool, default=False
646
625
  Toggle for tqdm progress bar.
647
626
  """
627
+ ious = [
628
+ compute_bitmask_iou(
629
+ np.array(
630
+ [
631
+ [gt.mask, pd.mask] # type: ignore - using the AttributeError as a validator
632
+ for pd in detection.predictions
633
+ for gt in detection.groundtruths
634
+ ]
635
+ )
636
+ ).reshape(len(detection.predictions), len(detection.groundtruths))
637
+ for detection in detections
638
+ ]
648
639
  return self._add_data(
649
640
  detections=detections,
641
+ detection_ious=ious,
650
642
  show_progress=show_progress,
651
- annotation_type=Bitmask,
652
643
  )
653
644
 
654
645
  def finalize(self) -> Evaluator:
@@ -46,8 +46,8 @@ def compute_intermediate_confusion_matrices(
46
46
  predictions.reshape(1, n_pd_labels, -1),
47
47
  ).sum(axis=2)
48
48
 
49
- intersected_groundtruth_counts = intersection_counts.sum(axis=0)
50
- intersected_prediction_counts = intersection_counts.sum(axis=1)
49
+ intersected_groundtruth_counts = intersection_counts.sum(axis=1)
50
+ intersected_prediction_counts = intersection_counts.sum(axis=0)
51
51
 
52
52
  confusion_matrix = np.zeros((n_labels + 1, n_labels + 1), dtype=np.int32)
53
53
  confusion_matrix[0, 0] = background_counts
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: valor-lite
3
- Version: 0.33.16
3
+ Version: 0.33.17
4
4
  Summary: Compute valor metrics locally.
5
5
  License: MIT License
6
6
 
File without changes
File without changes
File without changes