scale-nucleus 0.12b1__py3-none-any.whl → 0.14.14b0__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.
- cli/slices.py +14 -28
- nucleus/__init__.py +211 -18
- nucleus/annotation.py +28 -5
- nucleus/connection.py +9 -1
- nucleus/constants.py +9 -3
- nucleus/dataset.py +197 -59
- nucleus/dataset_item.py +11 -1
- nucleus/job.py +1 -1
- nucleus/metrics/__init__.py +2 -1
- nucleus/metrics/base.py +34 -56
- nucleus/metrics/categorization_metrics.py +6 -2
- nucleus/metrics/cuboid_utils.py +4 -6
- nucleus/metrics/errors.py +4 -0
- nucleus/metrics/filtering.py +369 -19
- nucleus/metrics/polygon_utils.py +3 -3
- nucleus/metrics/segmentation_loader.py +30 -0
- nucleus/metrics/segmentation_metrics.py +256 -195
- nucleus/metrics/segmentation_to_poly_metrics.py +229 -105
- nucleus/metrics/segmentation_utils.py +239 -8
- nucleus/model.py +66 -10
- nucleus/model_run.py +1 -1
- nucleus/{shapely_not_installed.py → package_not_installed.py} +3 -3
- nucleus/payload_constructor.py +4 -0
- nucleus/prediction.py +6 -3
- nucleus/scene.py +7 -0
- nucleus/slice.py +160 -16
- nucleus/utils.py +51 -12
- nucleus/validate/__init__.py +1 -0
- nucleus/validate/client.py +57 -8
- nucleus/validate/constants.py +1 -0
- nucleus/validate/data_transfer_objects/eval_function.py +22 -0
- nucleus/validate/data_transfer_objects/scenario_test_evaluations.py +13 -5
- nucleus/validate/eval_functions/available_eval_functions.py +33 -20
- nucleus/validate/eval_functions/config_classes/segmentation.py +2 -46
- nucleus/validate/scenario_test.py +71 -13
- nucleus/validate/scenario_test_evaluation.py +21 -21
- nucleus/validate/utils.py +1 -1
- {scale_nucleus-0.12b1.dist-info → scale_nucleus-0.14.14b0.dist-info}/LICENSE +0 -0
- {scale_nucleus-0.12b1.dist-info → scale_nucleus-0.14.14b0.dist-info}/METADATA +13 -11
- {scale_nucleus-0.12b1.dist-info → scale_nucleus-0.14.14b0.dist-info}/RECORD +42 -41
- {scale_nucleus-0.12b1.dist-info → scale_nucleus-0.14.14b0.dist-info}/WHEEL +1 -1
- {scale_nucleus-0.12b1.dist-info → scale_nucleus-0.14.14b0.dist-info}/entry_points.txt +0 -0
@@ -1,7 +1,6 @@
|
|
1
1
|
import itertools
|
2
2
|
from typing import Callable, Dict, List, Optional, Union
|
3
3
|
|
4
|
-
from nucleus.logger import logger
|
5
4
|
from nucleus.validate.eval_functions.base_eval_function import (
|
6
5
|
EvalFunctionConfig,
|
7
6
|
)
|
@@ -10,7 +9,6 @@ from ...metrics.filtering import ListOfAndFilters, ListOfOrAndFilters
|
|
10
9
|
from ..data_transfer_objects.eval_function import EvalFunctionEntry
|
11
10
|
from ..errors import EvalFunctionNotAvailableError
|
12
11
|
from .config_classes.segmentation import (
|
13
|
-
SegmentationAveragePrecisionConfig,
|
14
12
|
SegmentationFWAVACCConfig,
|
15
13
|
SegmentationIOUConfig,
|
16
14
|
SegmentationMAPConfig,
|
@@ -344,7 +342,7 @@ class SegmentationToPolyIOUConfig(EvalFunctionConfig):
|
|
344
342
|
class SegmentationToPolyMAPConfig(EvalFunctionConfig):
|
345
343
|
def __call__(
|
346
344
|
self,
|
347
|
-
|
345
|
+
iou_thresholds: Union[List[float], str] = "coco",
|
348
346
|
annotation_filters: Optional[
|
349
347
|
Union[ListOfOrAndFilters, ListOfAndFilters]
|
350
348
|
] = None,
|
@@ -389,7 +387,7 @@ class SegmentationToPolyMAPConfig(EvalFunctionConfig):
|
|
389
387
|
Finally, the most outer list combines these filters as a disjunction (OR).
|
390
388
|
"""
|
391
389
|
return super().__call__(
|
392
|
-
|
390
|
+
iou_thresholds=iou_thresholds,
|
393
391
|
annotation_filters=annotation_filters,
|
394
392
|
prediction_filters=prediction_filters,
|
395
393
|
**kwargs,
|
@@ -1139,22 +1137,24 @@ class CustomEvalFunction(EvalFunctionConfig):
|
|
1139
1137
|
@classmethod
|
1140
1138
|
def expected_name(cls) -> str:
|
1141
1139
|
raise NotImplementedError(
|
1142
|
-
"
|
1140
|
+
"Custom evaluation functions are coming soon"
|
1143
1141
|
) # Placeholder: See super().eval_func_entry for actual name
|
1144
1142
|
|
1145
1143
|
|
1144
|
+
class ExternalEvalFunction(EvalFunctionConfig):
|
1145
|
+
def __call__(self, **kwargs):
|
1146
|
+
raise NotImplementedError("Cannot call an external function")
|
1147
|
+
|
1148
|
+
@classmethod
|
1149
|
+
def expected_name(cls) -> str:
|
1150
|
+
return "external_function"
|
1151
|
+
|
1152
|
+
|
1146
1153
|
class StandardEvalFunction(EvalFunctionConfig):
|
1147
1154
|
"""Class for standard Model CI eval functions that have not been added as attributes on
|
1148
1155
|
AvailableEvalFunctions yet.
|
1149
1156
|
"""
|
1150
1157
|
|
1151
|
-
def __init__(self, eval_function_entry: EvalFunctionEntry):
|
1152
|
-
logger.warning(
|
1153
|
-
"Standard function %s not implemented as an attribute on AvailableEvalFunctions",
|
1154
|
-
eval_function_entry.name,
|
1155
|
-
)
|
1156
|
-
super().__init__(eval_function_entry)
|
1157
|
-
|
1158
1158
|
@classmethod
|
1159
1159
|
def expected_name(cls) -> str:
|
1160
1160
|
return "public_function" # Placeholder: See super().eval_func_entry for actual name
|
@@ -1194,6 +1194,7 @@ EvalFunction = Union[
|
|
1194
1194
|
CuboidPrecisionConfig,
|
1195
1195
|
CategorizationF1Config,
|
1196
1196
|
CustomEvalFunction,
|
1197
|
+
ExternalEvalFunction,
|
1197
1198
|
EvalFunctionNotAvailable,
|
1198
1199
|
StandardEvalFunction,
|
1199
1200
|
PolygonMAPConfig,
|
@@ -1205,7 +1206,6 @@ EvalFunction = Union[
|
|
1205
1206
|
SegmentationToPolyMAPConfig,
|
1206
1207
|
SegmentationToPolyPrecisionConfig,
|
1207
1208
|
SegmentationToPolyAveragePrecisionConfig,
|
1208
|
-
SegmentationAveragePrecisionConfig,
|
1209
1209
|
SegmentationFWAVACCConfig,
|
1210
1210
|
SegmentationIOUConfig,
|
1211
1211
|
SegmentationPrecisionConfig,
|
@@ -1243,7 +1243,12 @@ class AvailableEvalFunctions:
|
|
1243
1243
|
self._custom_to_function: Dict[str, CustomEvalFunction] = {
|
1244
1244
|
f.name: CustomEvalFunction(f)
|
1245
1245
|
for f in available_functions
|
1246
|
-
if not f.is_public
|
1246
|
+
if not f.is_public and not f.is_external_function
|
1247
|
+
}
|
1248
|
+
self._external_to_function: Dict[str, ExternalEvalFunction] = {
|
1249
|
+
f.name: ExternalEvalFunction(f)
|
1250
|
+
for f in available_functions
|
1251
|
+
if f.is_external_function
|
1247
1252
|
}
|
1248
1253
|
self.bbox_iou: BoundingBoxIOUConfig = (
|
1249
1254
|
self._assign_eval_function_if_defined(BoundingBoxIOUConfig)
|
@@ -1297,9 +1302,6 @@ class AvailableEvalFunctions:
|
|
1297
1302
|
self.seg_iou: SegmentationIOUConfig = self._assign_eval_function_if_defined(
|
1298
1303
|
SegmentationIOUConfig # type: ignore
|
1299
1304
|
)
|
1300
|
-
self.seg_ap: SegmentationAveragePrecisionConfig = self._assign_eval_function_if_defined(
|
1301
|
-
SegmentationAveragePrecisionConfig # type: ignore
|
1302
|
-
)
|
1303
1305
|
self.seg_recall: SegmentationRecallConfig = self._assign_eval_function_if_defined(
|
1304
1306
|
SegmentationRecallConfig # type: ignore
|
1305
1307
|
)
|
@@ -1326,8 +1328,9 @@ class AvailableEvalFunctions:
|
|
1326
1328
|
str(name).lower() for name in self._public_func_entries.keys()
|
1327
1329
|
]
|
1328
1330
|
return (
|
1329
|
-
f"<AvailableEvaluationFunctions: public:{functions_lower} "
|
1330
|
-
f"private: {list(self._custom_to_function.keys())}"
|
1331
|
+
f"<AvailableEvaluationFunctions: public: {functions_lower} "
|
1332
|
+
f"private: {list(self._custom_to_function.keys())} "
|
1333
|
+
f"external: {list(self._external_to_function.keys())}"
|
1331
1334
|
)
|
1332
1335
|
|
1333
1336
|
@property
|
@@ -1344,13 +1347,22 @@ class AvailableEvalFunctions:
|
|
1344
1347
|
|
1345
1348
|
@property
|
1346
1349
|
def private_functions(self) -> Dict[str, CustomEvalFunction]:
|
1347
|
-
"""
|
1350
|
+
"""Private functions uploaded to Model CI
|
1348
1351
|
|
1349
1352
|
Returns:
|
1350
1353
|
Dict of function name to :class:`CustomEvalFunction`.
|
1351
1354
|
"""
|
1352
1355
|
return self._custom_to_function
|
1353
1356
|
|
1357
|
+
@property
|
1358
|
+
def external_functions(self) -> Dict[str, ExternalEvalFunction]:
|
1359
|
+
"""External functions uploaded to Model CI
|
1360
|
+
|
1361
|
+
Returns:
|
1362
|
+
Dict of function name to :class:`ExternalEvalFunction`.
|
1363
|
+
"""
|
1364
|
+
return self._external_to_function
|
1365
|
+
|
1354
1366
|
def _assign_eval_function_if_defined(
|
1355
1367
|
self,
|
1356
1368
|
eval_function_constructor: Callable[[EvalFunctionEntry], EvalFunction],
|
@@ -1372,6 +1384,7 @@ class AvailableEvalFunctions:
|
|
1372
1384
|
for eval_func in itertools.chain(
|
1373
1385
|
self._public_to_function.values(),
|
1374
1386
|
self._custom_to_function.values(),
|
1387
|
+
self._external_to_function.values(),
|
1375
1388
|
):
|
1376
1389
|
if eval_func.id == eval_function_id:
|
1377
1390
|
return eval_func
|
@@ -80,12 +80,12 @@ class SegmentationMAPConfig(EvalFunctionConfig):
|
|
80
80
|
import nucleus
|
81
81
|
|
82
82
|
client = nucleus.NucleusClient(YOUR_SCALE_API_KEY)
|
83
|
-
|
83
|
+
seg_map: SegmentationMAP= client.validate.eval_functions.seg_map
|
84
84
|
slice_id = "slc_<your_slice>"
|
85
85
|
scenario_test = client.validate.create_scenario_test(
|
86
86
|
"Example test",
|
87
87
|
slice_id=slice_id,
|
88
|
-
evaluation_criteria=[
|
88
|
+
evaluation_criteria=[seg_map(iou_threshold=0.6) > 0.8]
|
89
89
|
)
|
90
90
|
|
91
91
|
Args:
|
@@ -231,50 +231,6 @@ class SegmentationPrecisionConfig(EvalFunctionConfig):
|
|
231
231
|
return "seg_precision"
|
232
232
|
|
233
233
|
|
234
|
-
class SegmentationAveragePrecisionConfig(EvalFunctionConfig):
|
235
|
-
def __call__(
|
236
|
-
self,
|
237
|
-
annotation_filters: Optional[
|
238
|
-
Union[ListOfOrAndFilters, ListOfAndFilters]
|
239
|
-
] = None,
|
240
|
-
prediction_filters: Optional[
|
241
|
-
Union[ListOfOrAndFilters, ListOfAndFilters]
|
242
|
-
] = None,
|
243
|
-
**kwargs,
|
244
|
-
):
|
245
|
-
"""Initializes SegmentationAveragePrecision object.
|
246
|
-
|
247
|
-
Args:
|
248
|
-
annotation_filters: Filter predicates. Allowed formats are:
|
249
|
-
ListOfAndFilters where each Filter forms a chain of AND predicates.
|
250
|
-
or
|
251
|
-
ListOfOrAndFilters where Filters are expressed in disjunctive normal form (DNF), like
|
252
|
-
[[MetadataFilter("short_haired", "==", True), FieldFilter("label", "in", ["cat", "dog"]), ...].
|
253
|
-
DNF allows arbitrary boolean logical combinations of single field predicates. The innermost structures
|
254
|
-
each describe a single column predicate. The list of inner predicates is interpreted as a conjunction
|
255
|
-
(AND), forming a more selective `and` multiple field predicate.
|
256
|
-
Finally, the most outer list combines these filters as a disjunction (OR).
|
257
|
-
prediction_filters: Filter predicates. Allowed formats are:
|
258
|
-
ListOfAndFilters where each Filter forms a chain of AND predicates.
|
259
|
-
or
|
260
|
-
ListOfOrAndFilters where Filters are expressed in disjunctive normal form (DNF), like
|
261
|
-
[[MetadataFilter("short_haired", "==", True), FieldFilter("label", "in", ["cat", "dog"]), ...].
|
262
|
-
DNF allows arbitrary boolean logical combinations of single field predicates. The innermost structures
|
263
|
-
each describe a single column predicate. The list of inner predicates is interpreted as a conjunction
|
264
|
-
(AND), forming a more selective `and` multiple field predicate.
|
265
|
-
Finally, the most outer list combines these filters as a disjunction (OR).
|
266
|
-
"""
|
267
|
-
return super().__call__(
|
268
|
-
annotation_filters=annotation_filters,
|
269
|
-
prediction_filters=prediction_filters,
|
270
|
-
**kwargs,
|
271
|
-
)
|
272
|
-
|
273
|
-
@classmethod
|
274
|
-
def expected_name(cls) -> str:
|
275
|
-
return "seg_ap"
|
276
|
-
|
277
|
-
|
278
234
|
class SegmentationFWAVACCConfig(EvalFunctionConfig):
|
279
235
|
def __call__(
|
280
236
|
self,
|
@@ -18,9 +18,12 @@ from .constants import (
|
|
18
18
|
THRESHOLD_KEY,
|
19
19
|
ThresholdComparison,
|
20
20
|
)
|
21
|
-
from .data_transfer_objects.scenario_test_evaluations import
|
21
|
+
from .data_transfer_objects.scenario_test_evaluations import EvaluationResult
|
22
22
|
from .data_transfer_objects.scenario_test_metric import AddScenarioTestFunction
|
23
|
-
from .eval_functions.available_eval_functions import
|
23
|
+
from .eval_functions.available_eval_functions import (
|
24
|
+
EvalFunction,
|
25
|
+
ExternalEvalFunction,
|
26
|
+
)
|
24
27
|
from .scenario_test_evaluation import ScenarioTestEvaluation
|
25
28
|
from .scenario_test_metric import ScenarioTestMetric
|
26
29
|
|
@@ -46,13 +49,24 @@ class ScenarioTest:
|
|
46
49
|
slice_id: str = field(init=False)
|
47
50
|
baseline_model_id: Optional[str] = None
|
48
51
|
|
49
|
-
|
52
|
+
@classmethod
|
53
|
+
def from_id(cls, unit_test_id: str, connection: Connection):
|
50
54
|
# TODO(gunnar): Remove this pattern. It's too slow. We should get all the info required in one call
|
51
|
-
response =
|
52
|
-
f"validate/scenario_test/{
|
55
|
+
response = connection.get(
|
56
|
+
f"validate/scenario_test/{unit_test_id}/info",
|
53
57
|
)
|
54
|
-
|
55
|
-
|
58
|
+
instance = cls(unit_test_id, connection)
|
59
|
+
instance.name = response[NAME_KEY]
|
60
|
+
instance.slice_id = response[SLICE_ID_KEY]
|
61
|
+
return instance
|
62
|
+
|
63
|
+
@classmethod
|
64
|
+
def from_response(cls, response, connection: Connection):
|
65
|
+
instance = cls(response["id"], connection)
|
66
|
+
instance.name = response[NAME_KEY]
|
67
|
+
instance.slice_id = response[SLICE_ID_KEY]
|
68
|
+
instance.baseline_model_id = response.get("baseline_model_id", None)
|
69
|
+
return instance
|
56
70
|
|
57
71
|
def add_eval_function(
|
58
72
|
self, eval_function: EvalFunction
|
@@ -83,9 +97,13 @@ class ScenarioTest:
|
|
83
97
|
Args:
|
84
98
|
eval_function: :class:`EvalFunction`
|
85
99
|
|
100
|
+
Raises:
|
101
|
+
NucleusAPIError: By adding this function, the scenario test mixes external with non-external functions which is not permitted.
|
102
|
+
|
86
103
|
Returns:
|
87
104
|
The created ScenarioTestMetric object.
|
88
105
|
"""
|
106
|
+
|
89
107
|
response = self.connection.post(
|
90
108
|
AddScenarioTestFunction(
|
91
109
|
scenario_test_name=self.name,
|
@@ -93,7 +111,7 @@ class ScenarioTest:
|
|
93
111
|
).dict(),
|
94
112
|
"validate/scenario_test_eval_function",
|
95
113
|
)
|
96
|
-
|
114
|
+
|
97
115
|
return ScenarioTestMetric(
|
98
116
|
scenario_test_id=response[SCENARIO_TEST_ID_KEY],
|
99
117
|
eval_function_id=response[EVAL_FUNCTION_ID_KEY],
|
@@ -138,13 +156,13 @@ class ScenarioTest:
|
|
138
156
|
A list of :class:`ScenarioTestEvaluation` objects.
|
139
157
|
"""
|
140
158
|
response = self.connection.get(
|
141
|
-
f"validate/scenario_test/{self.id}/eval_history",
|
159
|
+
f"validate/scenario_test/{self.id}/eval_history/details",
|
142
160
|
)
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
for evaluation in eval_history.evaluations
|
161
|
+
evaluations = [
|
162
|
+
ScenarioTestEvaluation.from_request(eval_payload, self.connection)
|
163
|
+
for eval_payload in response
|
147
164
|
]
|
165
|
+
return evaluations
|
148
166
|
|
149
167
|
def get_items(self) -> List[DatasetItem]:
|
150
168
|
response = self.connection.get(
|
@@ -174,3 +192,43 @@ class ScenarioTest:
|
|
174
192
|
)
|
175
193
|
self.baseline_model_id = response.get("baseline_model_id")
|
176
194
|
return self.baseline_model_id
|
195
|
+
|
196
|
+
def upload_external_evaluation_results(
|
197
|
+
self,
|
198
|
+
eval_fn: ExternalEvalFunction,
|
199
|
+
results: List[EvaluationResult],
|
200
|
+
model_id: str,
|
201
|
+
):
|
202
|
+
assert (
|
203
|
+
eval_fn.eval_func_entry.is_external_function
|
204
|
+
), "Submitting evaluation results is only available for external functions."
|
205
|
+
|
206
|
+
assert (
|
207
|
+
len(results) > 0
|
208
|
+
), "Submitting evaluation requires at least one result."
|
209
|
+
|
210
|
+
metric_per_ref_id = {}
|
211
|
+
weight_per_ref_id = {}
|
212
|
+
aggregate_weighted_sum = 0.0
|
213
|
+
aggregate_weight = 0.0
|
214
|
+
# aggregation based on https://en.wikipedia.org/wiki/Weighted_arithmetic_mean
|
215
|
+
for r in results:
|
216
|
+
metric_per_ref_id[r.item_ref_id] = r.score
|
217
|
+
weight_per_ref_id[r.item_ref_id] = r.weight
|
218
|
+
aggregate_weighted_sum += r.score * r.weight
|
219
|
+
aggregate_weight += r.weight
|
220
|
+
|
221
|
+
payload = {
|
222
|
+
"unit_test_id": self.id,
|
223
|
+
"eval_function_id": eval_fn.id,
|
224
|
+
"result_per_ref_id": metric_per_ref_id,
|
225
|
+
"weight_per_ref_id": weight_per_ref_id,
|
226
|
+
"overall_metric": aggregate_weighted_sum / aggregate_weight,
|
227
|
+
"model_id": model_id,
|
228
|
+
"slice_id": self.slice_id,
|
229
|
+
}
|
230
|
+
response = self.connection.post(
|
231
|
+
payload,
|
232
|
+
"validate/scenario_test/upload_results",
|
233
|
+
)
|
234
|
+
return response
|
@@ -1,5 +1,5 @@
|
|
1
1
|
"""Data types for Scenario Test Evaluation results."""
|
2
|
-
from dataclasses import
|
2
|
+
from dataclasses import dataclass, field
|
3
3
|
from enum import Enum
|
4
4
|
from typing import List, Optional
|
5
5
|
|
@@ -77,31 +77,30 @@ class ScenarioTestEvaluation:
|
|
77
77
|
status: ScenarioTestEvaluationStatus = field(init=False)
|
78
78
|
result: Optional[float] = field(init=False)
|
79
79
|
passed: bool = field(init=False)
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
def
|
84
|
-
|
85
|
-
|
86
|
-
|
80
|
+
connection: Connection = field(init=False, repr=False)
|
81
|
+
|
82
|
+
@classmethod
|
83
|
+
def from_request(cls, response, connection):
|
84
|
+
instance = cls(response["id"])
|
85
|
+
instance.connection = connection
|
86
|
+
|
87
|
+
instance.scenario_test_id = response[SCENARIO_TEST_ID_KEY]
|
88
|
+
instance.eval_function_id = response[EVAL_FUNCTION_ID_KEY]
|
89
|
+
instance.model_id = response[MODEL_ID_KEY]
|
90
|
+
instance.status = ScenarioTestEvaluationStatus(response[STATUS_KEY])
|
91
|
+
instance.result = try_convert_float(response[RESULT_KEY])
|
92
|
+
instance.passed = bool(response[PASS_KEY])
|
93
|
+
return instance
|
94
|
+
|
95
|
+
@property
|
96
|
+
def item_evals(self) -> List[ScenarioTestItemEvaluation]:
|
97
|
+
response = self.connection.make_request(
|
87
98
|
{},
|
88
99
|
f"validate/eval/{self.id}/info",
|
89
100
|
requests_command=requests.get,
|
90
101
|
)
|
91
|
-
eval_response = response[SCENARIO_TEST_EVAL_KEY]
|
92
102
|
items_response = response[ITEM_EVAL_KEY]
|
93
|
-
|
94
|
-
self.scenario_test_id: str = eval_response[SCENARIO_TEST_ID_KEY]
|
95
|
-
self.eval_function_id: str = eval_response[EVAL_FUNCTION_ID_KEY]
|
96
|
-
self.model_id: str = eval_response[MODEL_ID_KEY]
|
97
|
-
self.status: ScenarioTestEvaluationStatus = (
|
98
|
-
ScenarioTestEvaluationStatus(eval_response[STATUS_KEY])
|
99
|
-
)
|
100
|
-
self.result: Optional[float] = try_convert_float(
|
101
|
-
eval_response[RESULT_KEY]
|
102
|
-
)
|
103
|
-
self.passed: bool = bool(eval_response[PASS_KEY])
|
104
|
-
self.item_evals: List[ScenarioTestItemEvaluation] = [
|
103
|
+
items = [
|
105
104
|
ScenarioTestItemEvaluation(
|
106
105
|
evaluation_id=res[EVALUATION_ID_KEY],
|
107
106
|
scenario_test_id=res[SCENARIO_TEST_ID_KEY],
|
@@ -112,3 +111,4 @@ class ScenarioTestEvaluation:
|
|
112
111
|
)
|
113
112
|
for res in items_response
|
114
113
|
]
|
114
|
+
return items
|
nucleus/validate/utils.py
CHANGED
File without changes
|
@@ -1,31 +1,33 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: scale-nucleus
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.14.14b0
|
4
4
|
Summary: The official Python client library for Nucleus, the Data Platform for AI
|
5
5
|
Home-page: https://scale.com/nucleus
|
6
6
|
License: MIT
|
7
7
|
Author: Scale AI Nucleus Team
|
8
8
|
Author-email: nucleusapi@scaleapi.com
|
9
|
-
Requires-Python: >=3.6.2,<4.0
|
9
|
+
Requires-Python: >=3.6.2,<4.0
|
10
10
|
Classifier: License :: OSI Approved :: MIT License
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
12
12
|
Classifier: Programming Language :: Python :: 3.10
|
13
13
|
Classifier: Programming Language :: Python :: 3.7
|
14
14
|
Classifier: Programming Language :: Python :: 3.8
|
15
15
|
Classifier: Programming Language :: Python :: 3.9
|
16
|
-
Provides-Extra:
|
17
|
-
|
18
|
-
Requires-Dist:
|
16
|
+
Provides-Extra: launch
|
17
|
+
Provides-Extra: metrics
|
18
|
+
Requires-Dist: Pillow (>=7.1.2)
|
19
|
+
Requires-Dist: Shapely (>=1.8.0); extra == "metrics"
|
19
20
|
Requires-Dist: aiohttp (>=3.7.4,<4.0.0)
|
20
21
|
Requires-Dist: click (>=7.1.2,<9.0)
|
21
22
|
Requires-Dist: dataclasses (>=0.7,<0.8); python_full_version >= "3.6.1" and python_version < "3.7"
|
22
23
|
Requires-Dist: nest-asyncio (>=1.5.1,<2.0.0)
|
23
|
-
Requires-Dist: numpy (>=1.19.5
|
24
|
+
Requires-Dist: numpy (>=1.19.5); python_version >= "3.6" and python_version < "3.10"
|
25
|
+
Requires-Dist: numpy (>=1.22.0); python_version >= "3.10"
|
24
26
|
Requires-Dist: pydantic (>=1.8.2,<2.0.0)
|
25
|
-
Requires-Dist: rasterio (>=1.2.
|
27
|
+
Requires-Dist: rasterio (>=1.2.0); extra == "metrics"
|
26
28
|
Requires-Dist: requests (>=2.23.0,<3.0.0)
|
27
|
-
Requires-Dist: rich (>=10.15.2
|
28
|
-
Requires-Dist:
|
29
|
+
Requires-Dist: rich (>=10.15.2)
|
30
|
+
Requires-Dist: scale-launch (>=0.1.0); (python_version >= "3.7" and python_version < "4.0") and (extra == "launch")
|
29
31
|
Requires-Dist: scikit-learn (>=0.24.0)
|
30
32
|
Requires-Dist: scipy (>=1.4.1)
|
31
33
|
Requires-Dist: shellingham (>=1.4.0,<2.0.0)
|
@@ -224,7 +226,7 @@ sphinx-autobuild . ./_build/html --watch ../nucleus
|
|
224
226
|
|
225
227
|
## Custom Metrics using Shapely in scale-validate
|
226
228
|
|
227
|
-
Certain metrics use `
|
229
|
+
Certain metrics use `Shapely` and `rasterio` which is added as optional dependencies.
|
228
230
|
|
229
231
|
```bash
|
230
232
|
pip install scale-nucleus[metrics]
|
@@ -241,5 +243,5 @@ apt-get install libgeos-dev
|
|
241
243
|
|
242
244
|
To develop it locally use
|
243
245
|
|
244
|
-
`poetry install --extras
|
246
|
+
`poetry install --extras metrics`
|
245
247
|
|
@@ -8,77 +8,78 @@ cli/jobs.py,sha256=v-ArlqUyK3iPose2ihlzk7rq2W3uf5gOKmN0npNULKU,1176
|
|
8
8
|
cli/models.py,sha256=IWJyL9EJZXlpul0aW2qRgZG9rhFO59M8Ux-u-yMofzI,1039
|
9
9
|
cli/nu.py,sha256=0f71zPq4fe3I1ghhiSRQi39ENhAzoLPdhz_vh8vxSI8,2074
|
10
10
|
cli/reference.py,sha256=RuHVhmGTZNe0MfwpL96YjJdaH0OJzg98rz4xeIu4hJU,256
|
11
|
-
cli/slices.py,sha256=
|
11
|
+
cli/slices.py,sha256=1qAeX3-50-aBEDQxz0M8REwlTg9taLExS0a4PA3r3-U,1520
|
12
12
|
cli/tests.py,sha256=q90eo3l8yn0VxRwjWB821E709y_9xWqvFdEgPwV8vTY,4508
|
13
|
-
nucleus/__init__.py,sha256=
|
14
|
-
nucleus/annotation.py,sha256=
|
13
|
+
nucleus/__init__.py,sha256=P9mw2bqIjffa8Ys7RlB-KznxsouPDwrRcKcrdvku5jQ,39897
|
14
|
+
nucleus/annotation.py,sha256=yAmK734BhhuJitdKvoV8FGILKCUjc72d_fEtwjjyCV4,36189
|
15
15
|
nucleus/annotation_uploader.py,sha256=v9mlvKs1nV3LzZC5rL_gu8O366SSbvKzn9fvpkpRdpc,9477
|
16
16
|
nucleus/async_utils.py,sha256=RhHymn-GvP9cEs-nerbjrUmGxwqvWES4yWmf_9nr-qs,6709
|
17
17
|
nucleus/autocurate.py,sha256=Juw8V5CYKp3T-15u1QZOWaT6_fhXqGITf80eqtBNIqY,1074
|
18
18
|
nucleus/camera_params.py,sha256=fl17aaSAZDAJIWo6F2HFvM6HKGcQh9fXvo4t3RzGMc4,3726
|
19
|
-
nucleus/connection.py,sha256=
|
20
|
-
nucleus/constants.py,sha256=
|
19
|
+
nucleus/connection.py,sha256=xl6Dz8io57GOn02Fbg5btnlMslEgNbijpht7JekZoD4,2862
|
20
|
+
nucleus/constants.py,sha256=ohLj4T9EjWYoh9zeVs9MmNmuKGjVrPkNJuNMUf1fH6g,4245
|
21
21
|
nucleus/data_transfer_object/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
22
|
nucleus/data_transfer_object/dataset_details.py,sha256=1YGvfKkPSqDrXK_y5mBXyRThY07tU-nwOCYTkYCSl6k,214
|
23
23
|
nucleus/data_transfer_object/dataset_info.py,sha256=5P_gpvAyaqXxj2ZQuzLkGN2XROaN9Me56OLybCmO3R4,940
|
24
24
|
nucleus/data_transfer_object/dataset_size.py,sha256=oe-dXaMLpsQRDcJQRZ9Ja8JTagYz4dviZuTognEylp0,111
|
25
25
|
nucleus/data_transfer_object/scenes_list.py,sha256=iTHE6vA47bRB6ciyEU4LArUXEXco4ArnGvZTGTeK8xs,432
|
26
|
-
nucleus/dataset.py,sha256=
|
27
|
-
nucleus/dataset_item.py,sha256
|
26
|
+
nucleus/dataset.py,sha256=w1BF3Qwg7jA_ymEU3QLx37dzXP2AZYVsneXdfh8ezHw,70455
|
27
|
+
nucleus/dataset_item.py,sha256=NbJMHjaLIjsdF6IfsYgJgYibvNWn7BiV9dWmDX7QWeI,9148
|
28
28
|
nucleus/dataset_item_uploader.py,sha256=oH4Ly6sIQYrkdaOqrcbU_l-n5wQnspMefpJvgdBYAUM,6938
|
29
29
|
nucleus/deprecation_warning.py,sha256=5C9dVusR5UkUQnW2MrRkIXCfbc8ULc7xOaB134agNKk,976
|
30
30
|
nucleus/errors.py,sha256=IAONLQq-vsFVZSCY3zWzEOyRjkiOpJ3hUquS7_jNAz8,2870
|
31
|
-
nucleus/job.py,sha256=
|
31
|
+
nucleus/job.py,sha256=juxzn3xB8HwGDxolANX8Ryo4xM5QCOCaOembCdxyFaQ,4745
|
32
32
|
nucleus/logger.py,sha256=acoFtszu4T-fj_Op4rwlXNNaLPrQ8Kw2ofaYusBHO8I,208
|
33
33
|
nucleus/metadata_manager.py,sha256=gO1jChfP7sAokr-llYv3D86eV_VPumMWfOtn6GMw-Ew,1890
|
34
|
-
nucleus/metrics/__init__.py,sha256=
|
35
|
-
nucleus/metrics/base.py,sha256=
|
36
|
-
nucleus/metrics/categorization_metrics.py,sha256=
|
34
|
+
nucleus/metrics/__init__.py,sha256=bve48T1quN_vh3zhpW1nbv8ZfFBBiT9k6d8cipu-1k0,894
|
35
|
+
nucleus/metrics/base.py,sha256=cwBE1xm-2SN6ULfRwajLwNrC8oaLU4cGxP686EP4KE8,7757
|
36
|
+
nucleus/metrics/categorization_metrics.py,sha256=sGM7Zyz1DLSUEFbaqBFEf4oNXlWvc465dMCFVI5LhcI,11934
|
37
37
|
nucleus/metrics/cuboid_metrics.py,sha256=ZjlFNa8kknx2mJzEiJ8ZvTlvOSW0BjZzzfJiv3WHm-g,12461
|
38
|
-
nucleus/metrics/cuboid_utils.py,sha256=
|
38
|
+
nucleus/metrics/cuboid_utils.py,sha256=J_HOd5c9m77naHhiS0xhbUbRwTOicN9RpGrf97ODtAY,11190
|
39
39
|
nucleus/metrics/custom_types.py,sha256=6oWmlajz229crwEm2ImvC5vOhBXjt-HhVqj41D5uSwk,485
|
40
|
-
nucleus/metrics/errors.py,sha256=
|
41
|
-
nucleus/metrics/filtering.py,sha256=
|
40
|
+
nucleus/metrics/errors.py,sha256=Cu2W5tSsIHpazryd-9FXzu46OLC12Wk6gQT66hxQDis,304
|
41
|
+
nucleus/metrics/filtering.py,sha256=_DLjiEmJ1uBL2ell-0pXow4gHRjMsDUL0WDhT0s7LdQ,25444
|
42
42
|
nucleus/metrics/filters.py,sha256=SegJ2UdYSSnRJpoiqguVpGrDSGfyCK7OiREziunZw54,1140
|
43
43
|
nucleus/metrics/metric_utils.py,sha256=1EJf3ezTQAzh4mgECrxWyiUHzUjDqA_5hV9eqZISxRU,971
|
44
44
|
nucleus/metrics/polygon_metrics.py,sha256=mrsGc7714B944NDhLZ6pa0FbyWltuJEkd6ZVccLibdU,29277
|
45
|
-
nucleus/metrics/polygon_utils.py,sha256=
|
46
|
-
nucleus/metrics/
|
47
|
-
nucleus/metrics/
|
48
|
-
nucleus/metrics/
|
49
|
-
nucleus/
|
50
|
-
nucleus/
|
51
|
-
nucleus/
|
52
|
-
nucleus/
|
45
|
+
nucleus/metrics/polygon_utils.py,sha256=z1ERZepMwrmEgUz1tSBfCy9z07uqsoLZFNJ41Bl-sX4,12371
|
46
|
+
nucleus/metrics/segmentation_loader.py,sha256=GEKbdp71hIiyBwrZm7qkLJ1fFH_FOsDGYTSuZ_9GPYA,790
|
47
|
+
nucleus/metrics/segmentation_metrics.py,sha256=6PFp4ESPx3gUWqxF7HOtDm44_j_Sdp2lTi1P0bkEFas,29522
|
48
|
+
nucleus/metrics/segmentation_to_poly_metrics.py,sha256=1C1In5Kz2CAgVy39GCF3zBBT_OBybHnbL-jlCsQYrZc,29087
|
49
|
+
nucleus/metrics/segmentation_utils.py,sha256=uvypa95DX66sDIHHdE5xUjsuePTFJWePiq2OceolW3I,10075
|
50
|
+
nucleus/model.py,sha256=vbBgq0ZJEWL-1-w_rWMZiYmH5N3rDX_pY2Gvlg_QwmQ,8738
|
51
|
+
nucleus/model_run.py,sha256=Epbr-M2m0qOZY2AR9r-tzX6Au9i9bbk2Vwb5mw27i0Q,9541
|
52
|
+
nucleus/package_not_installed.py,sha256=1ae0aqKAM3KrB0C-5MuPPXoz9tLWJUKtP1UZ-vw9Zik,1117
|
53
|
+
nucleus/payload_constructor.py,sha256=-x4UYu_NHTaWfbrhEx9USUKH2q6wZzelh1gGG_-2nQM,4442
|
54
|
+
nucleus/prediction.py,sha256=D91YVjHvtGFmVuJjUS1LfxeJiJcMORJUtfhQP3FFxaY,25921
|
53
55
|
nucleus/pydantic_base.py,sha256=EQER8_XqG4B-RC4aggUfukJa6f5OZ7ej92AsDWWIWPc,682
|
54
56
|
nucleus/quaternion.py,sha256=TAnwj4arQXoTeofFgZMdZsCyxAMnu23N6to0F1WFNwk,1111
|
55
57
|
nucleus/retry_strategy.py,sha256=daKZqjZYCh87WtXoVUuR9BZu2TTE-CtOFEYZ-d6xVMY,312
|
56
|
-
nucleus/scene.py,sha256=
|
57
|
-
nucleus/
|
58
|
-
nucleus/slice.py,sha256=wf5MAoGdN0Rf4dIyEh__3vSvHAGgJiobYJ8KxRoM-H0,12926
|
58
|
+
nucleus/scene.py,sha256=4mQLstDi9GNRP7EGr4nLcHN9ALIldgR6Yw4hrBaULVk,26149
|
59
|
+
nucleus/slice.py,sha256=2MR6dbFjEHc7vji45KdFI-4BKWgTWBoCN4TssvKnXgE,18767
|
59
60
|
nucleus/upload_response.py,sha256=wR_pfZCBju1vGiGqbVgk8zhM6GhD3ebYxyGBm8y0GvY,3287
|
60
61
|
nucleus/url_utils.py,sha256=EZ3vy1FYTGvXRVNyq43Wif-ypS8LFoDrYMYJre_DVuQ,790
|
61
|
-
nucleus/utils.py,sha256=
|
62
|
-
nucleus/validate/__init__.py,sha256=
|
63
|
-
nucleus/validate/client.py,sha256=
|
64
|
-
nucleus/validate/constants.py,sha256=
|
62
|
+
nucleus/utils.py,sha256=fxISxhIPbAeBBRs25YG_kRnRfHKxpisXv-AF9uHZGCA,12653
|
63
|
+
nucleus/validate/__init__.py,sha256=de4m8RfJXSMBD8lF_mR0NAedP4Y5F03jHqNU0-XHSjI,773
|
64
|
+
nucleus/validate/client.py,sha256=0QcF2u1g513NjvR_CID0M6zM0jqRthSqBY9zla6LBZg,7786
|
65
|
+
nucleus/validate/constants.py,sha256=aHCX56E-yqsbIzeLbstaOhPqZOEXQptn4-zr74NDgzw,663
|
65
66
|
nucleus/validate/data_transfer_objects/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
66
|
-
nucleus/validate/data_transfer_objects/eval_function.py,sha256=
|
67
|
+
nucleus/validate/data_transfer_objects/eval_function.py,sha256=5scyeLfQhTWdNWrdybUEf5MIJJ0r9xdyfUO-aeYq7cQ,3828
|
67
68
|
nucleus/validate/data_transfer_objects/scenario_test.py,sha256=6gFGzBkl9y0Z5yNI_QtAC_TDPbLWqG0_pPAteDF0vnw,574
|
68
|
-
nucleus/validate/data_transfer_objects/scenario_test_evaluations.py,sha256=
|
69
|
+
nucleus/validate/data_transfer_objects/scenario_test_evaluations.py,sha256=MsQQp8ls5g91MzsyD6-n9KdBqV_rKrjOe3wfCbfSDoA,491
|
69
70
|
nucleus/validate/data_transfer_objects/scenario_test_metric.py,sha256=jXGwPx0Y99ga0RfzwGMCG3_06NkiFsp0yHxUuGFJ2EI,208
|
70
71
|
nucleus/validate/errors.py,sha256=UOI4oPeVzNLEmibWayfMdCMFNZvgsq-VRG42vC1cT_w,110
|
71
72
|
nucleus/validate/eval_functions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
72
|
-
nucleus/validate/eval_functions/available_eval_functions.py,sha256=
|
73
|
+
nucleus/validate/eval_functions/available_eval_functions.py,sha256=Uv3SeXLocbvAvWhyZafeOc3pc_Fd238xdtqyx7k4_tk,68938
|
73
74
|
nucleus/validate/eval_functions/base_eval_function.py,sha256=bMwK1oTiVmQOJZ07S6p7cr5ZHaHlt6idMZY7yV-9fjw,2207
|
74
75
|
nucleus/validate/eval_functions/config_classes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
75
|
-
nucleus/validate/eval_functions/config_classes/segmentation.py,sha256=
|
76
|
-
nucleus/validate/scenario_test.py,sha256=
|
77
|
-
nucleus/validate/scenario_test_evaluation.py,sha256=
|
76
|
+
nucleus/validate/eval_functions/config_classes/segmentation.py,sha256=Hk6yDYDwdKgjamfQJEOpyzQLP4zMqcz_I2cLnDBXtz0,13409
|
77
|
+
nucleus/validate/scenario_test.py,sha256=1FQanSrvh72TPiJwSAdNRkb6gfNPyauVo-1s8apiZRo,8597
|
78
|
+
nucleus/validate/scenario_test_evaluation.py,sha256=Q0WzaEE9uUbPVc4EHlCoKjhJcqMNt4QbyiiJx12VOR0,4075
|
78
79
|
nucleus/validate/scenario_test_metric.py,sha256=AhVFOB1ULwBqlZ2X_Au1TXy4iQELljtzR4ZpeLB35So,1209
|
79
|
-
nucleus/validate/utils.py,sha256=
|
80
|
-
scale_nucleus-0.
|
81
|
-
scale_nucleus-0.
|
82
|
-
scale_nucleus-0.
|
83
|
-
scale_nucleus-0.
|
84
|
-
scale_nucleus-0.
|
80
|
+
nucleus/validate/utils.py,sha256=VjdIJj9Pii4z4L6xbvClAc7ra_J7cX0vWB_J2X6yrGE,185
|
81
|
+
scale_nucleus-0.14.14b0.dist-info/entry_points.txt,sha256=fmqEzh6NZQyg9eFMILnWabKT8OWQTMSCdDzMiVq2zYs,32
|
82
|
+
scale_nucleus-0.14.14b0.dist-info/LICENSE,sha256=jaTGyQSQIZeWMo5iyYqgbAYHR9Bdy7nOzgE-Up3m_-g,1075
|
83
|
+
scale_nucleus-0.14.14b0.dist-info/WHEEL,sha256=DA86_h4QwwzGeRoz62o1svYt5kGEXpoUTuTtwzoTb30,83
|
84
|
+
scale_nucleus-0.14.14b0.dist-info/METADATA,sha256=KYRHazVKZ2BXxUYGGCpTbpKrpIOtJtZ8xT4hmXpkIGE,7735
|
85
|
+
scale_nucleus-0.14.14b0.dist-info/RECORD,,
|
File without changes
|