code-loader 1.0.90__tar.gz → 1.0.91.dev0__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.
Files changed (32) hide show
  1. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/PKG-INFO +1 -1
  2. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/contract/datasetclasses.py +10 -0
  3. code_loader-1.0.91.dev0/code_loader/contract/mapping.py +56 -0
  4. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/contract/responsedataclasses.py +8 -0
  5. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/inner_leap_binder/leapbinder.py +9 -1
  6. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/inner_leap_binder/leapbinder_decorators.py +107 -4
  7. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/leaploader.py +4 -2
  8. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/pyproject.toml +1 -1
  9. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/LICENSE +0 -0
  10. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/README.md +0 -0
  11. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/__init__.py +0 -0
  12. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/contract/__init__.py +0 -0
  13. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/contract/enums.py +0 -0
  14. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/contract/exceptions.py +0 -0
  15. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/contract/visualizer_classes.py +0 -0
  16. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/default_losses.py +0 -0
  17. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/default_metrics.py +0 -0
  18. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/experiment_api/__init__.py +0 -0
  19. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/experiment_api/api.py +0 -0
  20. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/experiment_api/cli_config_utils.py +0 -0
  21. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/experiment_api/client.py +0 -0
  22. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/experiment_api/epoch.py +0 -0
  23. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/experiment_api/experiment.py +0 -0
  24. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/experiment_api/experiment_context.py +0 -0
  25. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/experiment_api/types.py +0 -0
  26. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/experiment_api/utils.py +0 -0
  27. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/experiment_api/workingspace_config_utils.py +0 -0
  28. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/inner_leap_binder/__init__.py +0 -0
  29. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/leaploaderbase.py +0 -0
  30. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/utils.py +0 -0
  31. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/visualizers/__init__.py +0 -0
  32. {code_loader-1.0.90 → code_loader-1.0.91.dev0}/code_loader/visualizers/default_visualizers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: code-loader
3
- Version: 1.0.90
3
+ Version: 1.0.91.dev0
4
4
  Summary:
5
5
  Home-page: https://github.com/tensorleap/code-loader
6
6
  License: MIT
@@ -38,6 +38,7 @@ class PreprocessResponse:
38
38
  sample_ids: Optional[Union[List[str], List[int]]] = None
39
39
  state: Optional[DataStateType] = None
40
40
  sample_id_type: Optional[Union[Type[str], Type[int]]] = None
41
+ sample_ids_to_instance_mappings: Optional[Dict[Union[str, int], Union[List[str], List[int]]]] = None # in use only for element instance
41
42
 
42
43
  def __post_init__(self) -> None:
43
44
  def is_valid_string(s: str) -> bool:
@@ -188,6 +189,15 @@ class InputHandler(DatasetBaseHandler):
188
189
  shape: Optional[List[int]] = None
189
190
  channel_dim: Optional[int] = -1
190
191
 
192
+ @dataclass
193
+ class ElementInstance:
194
+ name: str
195
+ mask: npt.NDArray[np.float32]
196
+
197
+ @dataclass
198
+ class ElementInstanceHandler:
199
+ input_name: str
200
+ instance_function: [[int, PreprocessResponse], List[ElementInstance]]
191
201
 
192
202
  @dataclass
193
203
  class GroundTruthHandler(DatasetBaseHandler):
@@ -0,0 +1,56 @@
1
+ # mypy: ignore-errors
2
+
3
+
4
+ from enum import Enum
5
+
6
+ from typing import Optional, Dict, Any, List
7
+ from dataclasses import dataclass
8
+
9
+
10
+
11
+ class NodeMappingType(Enum):
12
+ Visualizer = 'Visualizer'
13
+ Metric = 'Metric'
14
+ GroundTruth = 'GroundTruth'
15
+ Input = 'Input'
16
+ Layer = 'Layer'
17
+ Loss = 'Loss'
18
+ CustomLoss = 'CustomLoss'
19
+ Optimizer = 'Optimizer'
20
+ Prediction0 = 'Prediction0'
21
+ Prediction1 = 'Prediction1'
22
+ Prediction2 = 'Prediction2'
23
+ Prediction3 = 'Prediction3'
24
+ Input0 = 'Input0'
25
+ Input1 = 'Input1'
26
+ Input2 = 'Input2'
27
+ Input3 = 'Input3'
28
+ Input4 = 'Input4'
29
+ Input5 = 'Input5'
30
+ PredictionLabels = 'PredictionLabels'
31
+
32
+
33
+ @dataclass
34
+ class NodeMapping:
35
+ name: str
36
+ type: NodeMappingType
37
+ user_unique_name: Optional[str] = None
38
+ sub_type: Optional[str] = None
39
+ arg_names: Optional[List[str]] = None
40
+
41
+
42
+ @dataclass
43
+ class NodeConnection:
44
+ node: NodeMapping
45
+ node_inputs: Optional[Dict[str, NodeMapping]]
46
+
47
+
48
+ def leap_output(idx):
49
+ def dummy():
50
+ return None
51
+
52
+ node_mapping_type = NodeMappingType(f'Prediction{str(idx)}')
53
+ dummy.node_mapping = NodeMapping('', node_mapping_type)
54
+
55
+ return dummy
56
+
@@ -2,6 +2,7 @@ from typing import List, Optional, Dict, Any, Union
2
2
 
3
3
  from dataclasses import dataclass, field
4
4
  from code_loader.contract.enums import DatasetMetadataType, LeapDataType
5
+ from code_loader.contract.mapping import NodeConnection
5
6
 
6
7
 
7
8
  @dataclass
@@ -120,6 +121,12 @@ class BoundingBox:
120
121
  metadata: Optional[Dict[str, Union[str, int, float]]] = None
121
122
 
122
123
 
124
+
125
+ @dataclass
126
+ class EngineFileContract:
127
+ node_connections: Optional[List[NodeConnection]] = None
128
+
129
+
123
130
  @dataclass
124
131
  class DatasetIntegParseResult:
125
132
  payloads: List[DatasetTestResultPayload]
@@ -129,3 +136,4 @@ class DatasetIntegParseResult:
129
136
  model_setup: Optional[ModelSetup] = None
130
137
  general_error: Optional[str] = None
131
138
  print_log: Optional[str] = None
139
+ engine_file_contract: Optional[EngineFileContract] = None
@@ -12,6 +12,7 @@ from code_loader.contract.datasetclasses import SectionCallableInterface, InputH
12
12
  CustomMultipleReturnCallableInterfaceMultiArgs, DatasetBaseHandler, custom_latent_space_attribute, \
13
13
  RawInputsForHeatmap, VisualizerHandlerData, MetricHandlerData, CustomLossHandlerData, SamplePreprocessResponse
14
14
  from code_loader.contract.enums import LeapDataType, DataStateEnum, DataStateType, MetricDirection, DatasetMetadataType
15
+ from code_loader.contract.mapping import NodeConnection, NodeMapping, NodeMappingType
15
16
  from code_loader.contract.responsedataclasses import DatasetTestResultPayload
16
17
  from code_loader.contract.visualizer_classes import map_leap_data_type_to_visualizer_class
17
18
  from code_loader.default_losses import loss_name_to_function
@@ -43,6 +44,8 @@ class LeapBinder:
43
44
  self._extend_with_default_metrics()
44
45
  self._extend_with_default_losses()
45
46
 
47
+ self.mapping_connections: List[NodeConnection] = []
48
+
46
49
  self.batch_size_to_validate: Optional[int] = None
47
50
 
48
51
  def _extend_with_default_visualizers(self) -> None:
@@ -307,7 +310,7 @@ class LeapBinder:
307
310
  metric_handler_data = MetricHandlerData(name, regular_arg_names, direction, compute_insights)
308
311
  self.setup_container.metrics.append(MetricHandler(metric_handler_data, function))
309
312
 
310
- def add_prediction(self, name: str, labels: List[str], channel_dim: int = -1) -> None:
313
+ def add_prediction(self, name: str, labels: List[str], channel_dim: int = -1, prediction_index: Optional[int]=None) -> None:
311
314
  """
312
315
  Add prediction labels to the setup.
313
316
 
@@ -322,6 +325,11 @@ class LeapBinder:
322
325
  leap_binder.add_prediction(name='class_labels', labels=['cat', 'dog'])
323
326
  """
324
327
  self.setup_container.prediction_types.append(PredictionTypeHandler(name, labels, channel_dim))
328
+ if prediction_index is not None:
329
+ node_connection = NodeConnection(NodeMapping(name, NodeMappingType.PredictionLabels),
330
+ {'temp': NodeMapping('', NodeMappingType(f'Prediction{prediction_index}'))})
331
+
332
+ self.mapping_connections.append(node_connection)
325
333
 
326
334
  def set_ground_truth(self, function: SectionCallableInterface, name: str) -> None:
327
335
  """
@@ -11,13 +11,25 @@ from code_loader.contract.datasetclasses import CustomCallableInterfaceMultiArgs
11
11
  ConfusionMatrixElement, SamplePreprocessResponse
12
12
  from code_loader.contract.enums import MetricDirection, LeapDataType, DatasetMetadataType
13
13
  from code_loader import leap_binder
14
+ from code_loader.contract.mapping import NodeMapping, NodeMappingType, NodeConnection
14
15
  from code_loader.contract.visualizer_classes import LeapImage, LeapImageMask, LeapTextMask, LeapText, LeapGraph, \
15
16
  LeapHorizontalBar, LeapImageWithBBox, LeapImageWithHeatmap
16
17
 
17
18
 
19
+ def _add_mapping_connections(connects_to, arg_names, node_mapping_type, name):
20
+ for user_unique_name, connection_destinations in connects_to.items():
21
+ main_node_mapping = NodeMapping(name, node_mapping_type, user_unique_name, arg_names=arg_names)
22
+ node_inputs = {}
23
+ for arg_name, destination in zip(arg_names, connection_destinations):
24
+ node_inputs[arg_name] = destination.node_mapping
25
+
26
+ leap_binder.mapping_connections.append(NodeConnection(main_node_mapping, node_inputs))
27
+
28
+
18
29
  def tensorleap_custom_metric(name: str,
19
30
  direction: Union[MetricDirection, Dict[str, MetricDirection]] = MetricDirection.Downward,
20
- compute_insights: Optional[Union[bool, Dict[str, bool]]] = None):
31
+ compute_insights: Optional[Union[bool, Dict[str, bool]]] = None,
32
+ connects_to=None):
21
33
  def decorating_function(user_function: Union[CustomCallableInterfaceMultiArgs,
22
34
  CustomMultipleReturnCallableInterfaceMultiArgs,
23
35
  ConfusionMatrixCallableInterfaceMultiArgs]):
@@ -28,6 +40,10 @@ def tensorleap_custom_metric(name: str,
28
40
 
29
41
  leap_binder.add_custom_metric(user_function, name, direction, compute_insights)
30
42
 
43
+ if connects_to is not None:
44
+ arg_names = leap_binder.setup_container.metrics[-1].metric_handler_data.arg_names
45
+ _add_mapping_connections(connects_to, arg_names, NodeMappingType.Metric, name)
46
+
31
47
  def _validate_input_args(*args, **kwargs) -> None:
32
48
  for i, arg in enumerate(args):
33
49
  assert isinstance(arg, (np.ndarray, SamplePreprocessResponse)), (
@@ -116,7 +132,8 @@ def tensorleap_custom_metric(name: str,
116
132
 
117
133
 
118
134
  def tensorleap_custom_visualizer(name: str, visualizer_type: LeapDataType,
119
- heatmap_function: Optional[Callable[..., npt.NDArray[np.float32]]] = None):
135
+ heatmap_function: Optional[Callable[..., npt.NDArray[np.float32]]] = None,
136
+ connects_to=None):
120
137
  def decorating_function(user_function: VisualizerCallableInterface):
121
138
  for viz_handler in leap_binder.setup_container.visualizers:
122
139
  if viz_handler.visualizer_handler_data.name == name:
@@ -125,6 +142,10 @@ def tensorleap_custom_visualizer(name: str, visualizer_type: LeapDataType,
125
142
 
126
143
  leap_binder.set_visualizer(user_function, name, visualizer_type, heatmap_function)
127
144
 
145
+ if connects_to is not None:
146
+ arg_names = leap_binder.setup_container.visualizers[-1].visualizer_handler_data.arg_names
147
+ _add_mapping_connections(connects_to, arg_names, NodeMappingType.Visualizer, name)
148
+
128
149
  def _validate_input_args(*args, **kwargs):
129
150
  for i, arg in enumerate(args):
130
151
  assert isinstance(arg, (np.ndarray, SamplePreprocessResponse)), (
@@ -249,6 +270,49 @@ def tensorleap_preprocess():
249
270
 
250
271
  return decorating_function
251
272
 
273
+ def tensorleap_element_instance_preprocess(instance_mask_encoder: Callable[[int, PreprocessResponse], List[PreprocessResponse]]):
274
+ def decorating_function(user_function: Callable[[], List[PreprocessResponse]]):
275
+ leap_binder.set_preprocess(user_function)
276
+
277
+ def _validate_input_args(*args, **kwargs):
278
+ assert len(args) == 0 and len(kwargs) == 0, \
279
+ (f'tensorleap_preprocess validation failed: '
280
+ f'The function should not take any arguments. Got {args} and {kwargs}.')
281
+
282
+ def _validate_result(result):
283
+ assert isinstance(result, list), \
284
+ (f'tensorleap_preprocess validation failed: '
285
+ f'The return type should be a list. Got {type(result)}.')
286
+ for i, response in enumerate(result):
287
+ assert isinstance(response, PreprocessResponse), \
288
+ (f'tensorleap_preprocess validation failed: '
289
+ f'Element #{i} in the return list should be a PreprocessResponse. Got {type(response)}.')
290
+ assert len(set(result)) == len(result), \
291
+ (f'tensorleap_preprocess validation failed: '
292
+ f'The return list should not contain duplicate PreprocessResponse objects.')
293
+
294
+ def inner(*args, **kwargs):
295
+ _validate_input_args(*args, **kwargs)
296
+ result = user_function()
297
+ for preprocess_response in result:
298
+ data_length = len(preprocess_response.sample_ids)
299
+ sample_ids_to_instance_mappings = {}
300
+ all_sample_ids = preprocess_response.sample_ids
301
+ for sample_id in preprocess_response.sample_ids:
302
+ instances_masks = instance_mask_encoder(sample_id, preprocess_response)
303
+ instances_ids = list(range(data_length, data_length + len(instances_masks)))
304
+ sample_ids_to_instance_mappings[sample_id] = instances_ids
305
+ all_sample_ids.extend(instances_ids)
306
+ preprocess_response.sample_ids_to_instance_mappings = sample_ids_to_instance_mappings
307
+ data_length = len(all_sample_ids)
308
+ preprocess_response.sample_ids = all_sample_ids
309
+ _validate_result(result)
310
+ return result
311
+
312
+ return inner
313
+
314
+ return decorating_function
315
+
252
316
 
253
317
  def tensorleap_unlabeled_preprocess():
254
318
  def decorating_function(user_function: Callable[[], PreprocessResponse]):
@@ -275,7 +339,32 @@ def tensorleap_unlabeled_preprocess():
275
339
  return decorating_function
276
340
 
277
341
 
278
- def tensorleap_input_encoder(name: str, channel_dim=-1):
342
+ def tensorleap_instance_encoder():
343
+ def decorating_function(user_function: Callable[[], PreprocessResponse]):
344
+ leap_binder.set_unlabeled_data_preprocess(user_function)
345
+
346
+ def _validate_input_args(*args, **kwargs):
347
+ assert len(args) == 0 and len(kwargs) == 0, \
348
+ (f'tensorleap_instance_encoder validation failed: '
349
+ f'The function should not take any arguments. Got {args} and {kwargs}.')
350
+
351
+ def _validate_result(result):
352
+ assert isinstance(result, PreprocessResponse), \
353
+ (f'tensorleap_instance_encoder validation failed: '
354
+ f'The return type should be a PreprocessResponse. Got {type(result)}.')
355
+
356
+ def inner(*args, **kwargs):
357
+ _validate_input_args(*args, **kwargs)
358
+ result = user_function()
359
+ _validate_result(result)
360
+ return result
361
+
362
+ return inner
363
+
364
+ return decorating_function
365
+
366
+
367
+ def tensorleap_input_encoder(name: str, channel_dim=-1, model_input_index=None):
279
368
  def decorating_function(user_function: SectionCallableInterface):
280
369
  for input_handler in leap_binder.setup_container.inputs:
281
370
  if input_handler.name == name:
@@ -314,6 +403,11 @@ def tensorleap_input_encoder(name: str, channel_dim=-1):
314
403
  _validate_result(result)
315
404
  return result
316
405
 
406
+ node_mapping_type = NodeMappingType.Input
407
+ if model_input_index is not None:
408
+ node_mapping_type = NodeMappingType(f'Input{str(model_input_index)}')
409
+ inner.node_mapping = NodeMapping(name, node_mapping_type)
410
+
317
411
  return inner
318
412
 
319
413
  return decorating_function
@@ -354,12 +448,16 @@ def tensorleap_gt_encoder(name: str):
354
448
  _validate_result(result)
355
449
  return result
356
450
 
451
+ inner.node_mapping = NodeMapping(name, NodeMappingType.GroundTruth)
452
+
357
453
  return inner
358
454
 
455
+
456
+
359
457
  return decorating_function
360
458
 
361
459
 
362
- def tensorleap_custom_loss(name: str):
460
+ def tensorleap_custom_loss(name: str, connects_to=None):
363
461
  def decorating_function(user_function: CustomCallableInterface):
364
462
  for loss_handler in leap_binder.setup_container.custom_loss_handlers:
365
463
  if loss_handler.custom_loss_handler_data.name == name:
@@ -368,6 +466,11 @@ def tensorleap_custom_loss(name: str):
368
466
 
369
467
  leap_binder.add_custom_loss(user_function, name)
370
468
 
469
+ if connects_to is not None:
470
+ arg_names = leap_binder.setup_container.custom_loss_handlers[-1].custom_loss_handler_data.arg_names
471
+ _add_mapping_connections(connects_to, arg_names, NodeMappingType.CustomLoss, name)
472
+
473
+
371
474
  valid_types = (np.ndarray, SamplePreprocessResponse)
372
475
  try:
373
476
  import tensorflow as tf
@@ -19,7 +19,8 @@ from code_loader.contract.enums import DataStateEnum, TestingSectionEnum, DataSt
19
19
  from code_loader.contract.exceptions import DatasetScriptException
20
20
  from code_loader.contract.responsedataclasses import DatasetIntegParseResult, DatasetTestResultPayload, \
21
21
  DatasetPreprocess, DatasetSetup, DatasetInputInstance, DatasetOutputInstance, DatasetMetadataInstance, \
22
- VisualizerInstance, PredictionTypeInstance, ModelSetup, CustomLayerInstance, MetricInstance, CustomLossInstance
22
+ VisualizerInstance, PredictionTypeInstance, ModelSetup, CustomLayerInstance, MetricInstance, CustomLossInstance, \
23
+ EngineFileContract
23
24
  from code_loader.inner_leap_binder import global_leap_binder
24
25
  from code_loader.leaploaderbase import LeapLoaderBase
25
26
  from code_loader.utils import get_root_exception_file_and_line_number
@@ -179,7 +180,8 @@ class LeapLoader(LeapLoaderBase):
179
180
  return DatasetIntegParseResult(is_valid=is_valid, payloads=test_payloads,
180
181
  is_valid_for_model=is_valid_for_model, setup=setup_response,
181
182
  model_setup=model_setup, general_error=general_error,
182
- print_log=print_log)
183
+ print_log=print_log,
184
+ engine_file_contract=EngineFileContract(global_leap_binder.mapping_connections))
183
185
 
184
186
  def _check_preprocess(self) -> DatasetTestResultPayload:
185
187
  test_result = DatasetTestResultPayload('preprocess')
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "code-loader"
3
- version = "1.0.90"
3
+ version = "1.0.91.dev0"
4
4
  description = ""
5
5
  authors = ["dorhar <doron.harnoy@tensorleap.ai>"]
6
6
  license = "MIT"
File without changes