code-loader 1.0.51__tar.gz → 1.0.52__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 (29) hide show
  1. {code_loader-1.0.51 → code_loader-1.0.52}/PKG-INFO +1 -1
  2. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/inner_leap_binder/leapbinder.py +7 -0
  3. code_loader-1.0.52/code_loader/inner_leap_binder/leapbinder_decorators.py +380 -0
  4. {code_loader-1.0.51 → code_loader-1.0.52}/pyproject.toml +1 -1
  5. {code_loader-1.0.51 → code_loader-1.0.52}/LICENSE +0 -0
  6. {code_loader-1.0.51 → code_loader-1.0.52}/README.md +0 -0
  7. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/__init__.py +0 -0
  8. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/code_inegration_processes_manager.py +0 -0
  9. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/contract/__init__.py +0 -0
  10. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/contract/datasetclasses.py +0 -0
  11. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/contract/enums.py +0 -0
  12. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/contract/exceptions.py +0 -0
  13. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/contract/responsedataclasses.py +0 -0
  14. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/contract/visualizer_classes.py +0 -0
  15. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/experiment_api/__init__.py +0 -0
  16. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/experiment_api/api.py +0 -0
  17. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/experiment_api/cli_config_utils.py +0 -0
  18. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/experiment_api/client.py +0 -0
  19. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/experiment_api/epoch.py +0 -0
  20. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/experiment_api/experiment.py +0 -0
  21. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/experiment_api/experiment_context.py +0 -0
  22. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/experiment_api/types.py +0 -0
  23. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/experiment_api/utils.py +0 -0
  24. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/experiment_api/workingspace_config_utils.py +0 -0
  25. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/inner_leap_binder/__init__.py +0 -0
  26. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/leaploader.py +0 -0
  27. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/utils.py +0 -0
  28. {code_loader-1.0.51 → code_loader-1.0.52}/code_loader/visualizers/__init__.py +0 -0
  29. {code_loader-1.0.51 → code_loader-1.0.52}/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.51
3
+ Version: 1.0.52
4
4
  Summary:
5
5
  Home-page: https://github.com/tensorleap/code-loader
6
6
  License: MIT
@@ -37,6 +37,8 @@ class LeapBinder:
37
37
  self._encoder_names: List[str] = list()
38
38
  self._extend_with_default_visualizers()
39
39
 
40
+ self.batch_size_to_validate: Optional[int] = None
41
+
40
42
  def _extend_with_default_visualizers(self) -> None:
41
43
  self.set_visualizer(function=default_image_visualizer, name=DefaultVisualizer.Image.value,
42
44
  visualizer_type=LeapDataType.Image)
@@ -472,4 +474,9 @@ class LeapBinder:
472
474
  self.check_handlers(preprocess_result)
473
475
  print("Successful!")
474
476
 
477
+ def set_batch_size_to_validate(self, batch_size: int) -> None:
478
+ self.batch_size_to_validate = batch_size
479
+
480
+
481
+
475
482
 
@@ -0,0 +1,380 @@
1
+ # mypy: ignore-errors
2
+
3
+ from typing import Optional, Union, Callable, List
4
+
5
+ import numpy as np
6
+ import numpy.typing as npt
7
+
8
+ from code_loader.contract.datasetclasses import CustomCallableInterfaceMultiArgs, \
9
+ CustomMultipleReturnCallableInterfaceMultiArgs, ConfusionMatrixCallableInterfaceMultiArgs, CustomCallableInterface, \
10
+ VisualizerCallableInterface, MetadataSectionCallableInterface, PreprocessResponse, SectionCallableInterface, \
11
+ ConfusionMatrixElement
12
+ from code_loader.contract.enums import MetricDirection, LeapDataType
13
+ from code_loader import leap_binder
14
+ from code_loader.contract.visualizer_classes import LeapImage, LeapImageMask, LeapTextMask, LeapText, LeapGraph, \
15
+ LeapHorizontalBar, LeapImageWithBBox, LeapImageWithHeatmap
16
+
17
+
18
+ def tensorleap_custom_metric(name: str, direction: Optional[MetricDirection] = MetricDirection.Downward):
19
+ def decorating_function(
20
+ user_function: Union[CustomCallableInterfaceMultiArgs,
21
+ CustomMultipleReturnCallableInterfaceMultiArgs,
22
+ ConfusionMatrixCallableInterfaceMultiArgs]
23
+ ):
24
+ for metric_handler in leap_binder.setup_container.metrics:
25
+ if metric_handler.name == name:
26
+ raise Exception(f'Metric with name {name} already exists. '
27
+ f'Please choose another')
28
+
29
+ leap_binder.add_custom_metric(user_function, name, direction)
30
+
31
+ def _validate_input_args(*args, **kwargs) -> None:
32
+ for i, arg in enumerate(args):
33
+ assert isinstance(arg, np.ndarray), (f'tensorleap_custom_metric validation failed: '
34
+ f'Argument #{i} should be a numpy array. Got {type(arg)}.')
35
+ if leap_binder.batch_size_to_validate:
36
+ assert arg.shape[0] == leap_binder.batch_size_to_validate, \
37
+ (f'tensorleap_custom_metric validation failed: Argument #{i} '
38
+ f'first dim should be as the batch size. Got {arg.shape[0]} '
39
+ f'instead of {leap_binder.batch_size_to_validate}')
40
+
41
+ for _arg_name, arg in kwargs.items():
42
+ assert isinstance(arg, np.ndarray), (f'tensorleap_custom_metric validation failed: '
43
+ f'Argument {_arg_name} should be a numpy array. Got {type(arg)}.')
44
+ if leap_binder.batch_size_to_validate:
45
+ assert arg.shape[0] == leap_binder.batch_size_to_validate, \
46
+ (f'tensorleap_custom_metric validation failed: Argument {_arg_name} '
47
+ f'first dim should be as the batch size. Got {arg.shape[0]} '
48
+ f'instead of {leap_binder.batch_size_to_validate}')
49
+
50
+ def _validate_result(result) -> None:
51
+ supported_types_message = (f'tensorleap_custom_metric validation failed: '
52
+ f'Metric has returned unsupported type. Supported types are List[float], '
53
+ f'List[List[ConfusionMatrixElement]], NDArray[np.float32]. ')
54
+
55
+ if isinstance(result, list):
56
+ if isinstance(result[0], list):
57
+ assert isinstance(result[0][0], ConfusionMatrixElement), \
58
+ f'{supported_types_message}Got List[List[{type(result[0][0])}]].'
59
+ else:
60
+ assert isinstance(result[0], float), f'{supported_types_message}Got List[{type(result[0])}].'
61
+
62
+ else:
63
+ assert isinstance(result, np.ndarray), f'{supported_types_message}Got {type(result)}.'
64
+ assert len(result.shape) == 1, (f'tensorleap_custom_metric validation failed: '
65
+ f'The return shape should be 1D. Got {len(result.shape)}D.')
66
+ if leap_binder.batch_size_to_validate:
67
+ assert len(result) == leap_binder.batch_size_to_validate, \
68
+ f'tensorleap_custom_metrix validation failed: The return len should be as the batch size.'
69
+
70
+ def inner(*args, **kwargs):
71
+ _validate_input_args(*args, **kwargs)
72
+ result = user_function(*args, **kwargs)
73
+ _validate_result(result)
74
+ return result
75
+
76
+ return inner
77
+
78
+ return decorating_function
79
+
80
+
81
+ def tensorleap_custom_visualizer(name: str, visualizer_type: LeapDataType,
82
+ heatmap_function: Optional[Callable[..., npt.NDArray[np.float32]]] = None):
83
+ def decorating_function(user_function: VisualizerCallableInterface):
84
+ for viz_handler in leap_binder.setup_container.visualizers:
85
+ if viz_handler.name == name:
86
+ raise Exception(f'Visualizer with name {name} already exists. '
87
+ f'Please choose another')
88
+
89
+ leap_binder.set_visualizer(user_function, name, visualizer_type, heatmap_function)
90
+
91
+ def _validate_input_args(*args, **kwargs):
92
+ for i, arg in enumerate(args):
93
+ assert isinstance(arg, np.ndarray), (f'tensorleap_custom_visualizer validation failed: '
94
+ f'Argument #{i} should be a numpy array. Got {type(arg)}.')
95
+ if leap_binder.batch_size_to_validate:
96
+ assert arg.shape[0] == leap_binder.batch_size_to_validate, \
97
+ (f'tensorleap_custom_visualizer validation failed: Argument #{i} '
98
+ f'first dim should be 1. The visualizers will always run with batch size 1. Got {arg.shape[0]}')
99
+
100
+ for _arg_name, arg in kwargs.items():
101
+ assert isinstance(arg, np.ndarray), (f'tensorleap_custom_visualizer validation failed: '
102
+ f'Argument {_arg_name} should be a numpy array. Got {type(arg)}.')
103
+ if leap_binder.batch_size_to_validate:
104
+ assert arg.shape[0] == leap_binder.batch_size_to_validate, \
105
+ (f'tensorleap_custom_visualizer validation failed: Argument {_arg_name} '
106
+ f'first dim should be 1. The visualizers will always run with batch size 1. Got {arg.shape[0]}')
107
+
108
+ def _validate_result(result):
109
+ result_type_map = {
110
+ LeapDataType.Image: LeapImage,
111
+ LeapDataType.ImageMask: LeapImageMask,
112
+ LeapDataType.TextMask: LeapTextMask,
113
+ LeapDataType.Text: LeapText,
114
+ LeapDataType.Graph: LeapGraph,
115
+ LeapDataType.HorizontalBar: LeapHorizontalBar,
116
+ LeapDataType.ImageWithBBox: LeapImageWithBBox,
117
+ LeapDataType.ImageWithHeatmap: LeapImageWithHeatmap
118
+ }
119
+ assert isinstance(result, result_type_map[visualizer_type]), \
120
+ (f'tensorleap_custom_visualizer validation failed: '
121
+ f'The return type should be {result_type_map[visualizer_type]}. Got {type(result)}.')
122
+
123
+ def inner(*args, **kwargs):
124
+ _validate_input_args(*args, **kwargs)
125
+ result = user_function(*args, **kwargs)
126
+ _validate_result(result)
127
+ return result
128
+
129
+ return inner
130
+
131
+ return decorating_function
132
+
133
+
134
+ def tensorleap_metadata(name: str):
135
+ def decorating_function(user_function: MetadataSectionCallableInterface):
136
+ for metadata_handler in leap_binder.setup_container.metadata:
137
+ if metadata_handler.name == name:
138
+ raise Exception(f'Metadata with name {name} already exists. '
139
+ f'Please choose another')
140
+
141
+ leap_binder.set_metadata(user_function, name)
142
+
143
+ def _validate_input_args(sample_id: Union[int, str], preprocess_response: PreprocessResponse):
144
+ assert isinstance(sample_id, (int, str)), \
145
+ (f'tensorleap_metadata validation failed: '
146
+ f'Argument sample_id should be either int or str. Got {type(sample_id)}.')
147
+ assert isinstance(preprocess_response, PreprocessResponse), \
148
+ (f'tensorleap_metadata validation failed: '
149
+ f'Argument preprocess_response should be a PreprocessResponse. Got {type(preprocess_response)}.')
150
+ assert type(sample_id) == preprocess_response.sample_id_type, \
151
+ (f'tensorleap_metadata validation failed: '
152
+ f'Argument sample_id should be as the same type as defined in the preprocess response '
153
+ f'{preprocess_response.sample_id_type}. Got {type(sample_id)}.')
154
+
155
+ def _validate_result(result):
156
+ supported_result_types = (int, str, bool, float, dict, np.floating,
157
+ np.bool_, np.unsignedinteger, np.signedinteger, np.integer)
158
+ assert isinstance(result, supported_result_types), \
159
+ (f'tensorleap_metadata validation failed: '
160
+ f'Unsupported return type. Got {type(result)}. should be any of {str(supported_result_types)}')
161
+ if isinstance(result, dict):
162
+ for key, value in result.items():
163
+ assert isinstance(key, str), \
164
+ (f'tensorleap_metadata validation failed: '
165
+ f'Keys in the return dict should be of type str. Got {type(key)}.')
166
+ assert isinstance(value, supported_result_types), \
167
+ (f'tensorleap_metadata validation failed: '
168
+ f'Values in the return dict should be of type {str(supported_result_types)}. Got {type(value)}.')
169
+
170
+ def inner(sample_id, preprocess_response):
171
+ _validate_input_args(sample_id, preprocess_response)
172
+ result = user_function(sample_id, preprocess_response)
173
+ _validate_result(result)
174
+ return result
175
+
176
+ return inner
177
+
178
+ return decorating_function
179
+
180
+
181
+ def tensorleap_preprocess():
182
+ def decorating_function(user_function: Callable[[], List[PreprocessResponse]]):
183
+ leap_binder.set_preprocess(user_function)
184
+
185
+ def _validate_input_args(*args, **kwargs):
186
+ assert len(args) == 0 and len(kwargs) == 0, \
187
+ (f'tensorleap_preprocess validation failed: '
188
+ f'The function should not take any arguments. Got {args} and {kwargs}.')
189
+
190
+ def _validate_result(result):
191
+ assert isinstance(result, list), \
192
+ (f'tensorleap_preprocess validation failed: '
193
+ f'The return type should be a list. Got {type(result)}.')
194
+ for i, response in enumerate(result):
195
+ assert isinstance(response, PreprocessResponse), \
196
+ (f'tensorleap_preprocess validation failed: '
197
+ f'Element #{i} in the return list should be a PreprocessResponse. Got {type(response)}.')
198
+ assert len(set(result)) == len(result), \
199
+ (f'tensorleap_preprocess validation failed: '
200
+ f'The return list should not contain duplicate PreprocessResponse objects.')
201
+
202
+ def inner(*args, **kwargs):
203
+ _validate_input_args(*args, **kwargs)
204
+ result = user_function()
205
+ _validate_result(result)
206
+ return result
207
+
208
+ return inner
209
+
210
+ return decorating_function
211
+
212
+
213
+ def tensorleap_unlabeled_preprocess():
214
+ def decorating_function(user_function: Callable[[], PreprocessResponse]):
215
+ leap_binder.set_unlabeled_data_preprocess(user_function)
216
+
217
+ def _validate_input_args(*args, **kwargs):
218
+ assert len(args) == 0 and len(kwargs) == 0, \
219
+ (f'tensorleap_unlabeled_preprocess validation failed: '
220
+ f'The function should not take any arguments. Got {args} and {kwargs}.')
221
+
222
+ def _validate_result(result):
223
+ assert isinstance(result, PreprocessResponse), \
224
+ (f'tensorleap_unlabeled_preprocess validation failed: '
225
+ f'The return type should be a PreprocessResponse. Got {type(result)}.')
226
+
227
+ def inner(*args, **kwargs):
228
+ _validate_input_args(*args, **kwargs)
229
+ result = user_function()
230
+ _validate_result(result)
231
+ return result
232
+
233
+ return inner
234
+
235
+ return decorating_function
236
+
237
+
238
+ def tensorleap_input_encoder(name: str):
239
+ def decorating_function(user_function: SectionCallableInterface):
240
+ for input_handler in leap_binder.setup_container.inputs:
241
+ if input_handler.name == name:
242
+ raise Exception(f'Input with name {name} already exists. '
243
+ f'Please choose another')
244
+
245
+ leap_binder.set_input(user_function, name)
246
+
247
+ def _validate_input_args(sample_id: Union[int, str], preprocess_response: PreprocessResponse):
248
+ assert isinstance(sample_id, (int, str)), \
249
+ (f'tensorleap_input_encoder validation failed: '
250
+ f'Argument sample_id should be either int or str. Got {type(sample_id)}.')
251
+ assert isinstance(preprocess_response, PreprocessResponse), \
252
+ (f'tensorleap_input_encoder validation failed: '
253
+ f'Argument preprocess_response should be a PreprocessResponse. Got {type(preprocess_response)}.')
254
+ assert type(sample_id) == preprocess_response.sample_id_type, \
255
+ (f'tensorleap_input_encoder validation failed: '
256
+ f'Argument sample_id should be as the same type as defined in the preprocess response '
257
+ f'{preprocess_response.sample_id_type}. Got {type(sample_id)}.')
258
+
259
+ def _validate_result(result):
260
+ assert isinstance(result, np.ndarray), \
261
+ (f'tensorleap_input_encoder validation failed: '
262
+ f'Unsupported return type. Should be a numpy array. Got {type(result)}.')
263
+ assert result.dtype == np.float32, \
264
+ (f'tensorleap_input_encoder validation failed: '
265
+ f'The return type should be a numpy array of type float32. Got {result.dtype}.')
266
+
267
+ def inner(sample_id, preprocess_response):
268
+ _validate_input_args(sample_id, preprocess_response)
269
+ result = user_function(sample_id, preprocess_response)
270
+ _validate_result(result)
271
+ return result
272
+
273
+ return inner
274
+
275
+ return decorating_function
276
+
277
+
278
+ def tensorleap_gt_encoder(name: str):
279
+ def decorating_function(user_function: SectionCallableInterface):
280
+ for gt_handler in leap_binder.setup_container.ground_truths:
281
+ if gt_handler.name == name:
282
+ raise Exception(f'Input with name {name} already exists. '
283
+ f'Please choose another')
284
+
285
+ leap_binder.set_ground_truth(user_function, name)
286
+
287
+ def _validate_input_args(sample_id: Union[int, str], preprocess_response: PreprocessResponse):
288
+ assert isinstance(sample_id, (int, str)), \
289
+ (f'tensorleap_gt_encoder validation failed: '
290
+ f'Argument sample_id should be either int or str. Got {type(sample_id)}.')
291
+ assert isinstance(preprocess_response, PreprocessResponse), \
292
+ (f'tensorleap_gt_encoder validation failed: '
293
+ f'Argument preprocess_response should be a PreprocessResponse. Got {type(preprocess_response)}.')
294
+ assert type(sample_id) == preprocess_response.sample_id_type, \
295
+ (f'tensorleap_gt_encoder validation failed: '
296
+ f'Argument sample_id should be as the same type as defined in the preprocess response '
297
+ f'{preprocess_response.sample_id_type}. Got {type(sample_id)}.')
298
+
299
+ def _validate_result(result):
300
+ assert isinstance(result, np.ndarray), \
301
+ (f'tensorleap_gt_encoder validation failed: '
302
+ f'Unsupported return type. Should be a numpy array. Got {type(result)}.')
303
+ assert result.dtype == np.float32, \
304
+ (f'tensorleap_gt_encoder validation failed: '
305
+ f'The return type should be a numpy array of type float32. Got {result.dtype}.')
306
+
307
+ def inner(sample_id, preprocess_response):
308
+ _validate_input_args(sample_id, preprocess_response)
309
+ result = user_function(sample_id, preprocess_response)
310
+ _validate_result(result)
311
+ return result
312
+
313
+ return inner
314
+
315
+ return decorating_function
316
+
317
+
318
+ def tensorleap_custom_loss(name: str):
319
+ def decorating_function(user_function: CustomCallableInterface):
320
+ for loss_handler in leap_binder.setup_container.custom_loss_handlers:
321
+ if loss_handler.name == name:
322
+ raise Exception(f'Input with name {name} already exists. '
323
+ f'Please choose another')
324
+
325
+ leap_binder.add_custom_loss(user_function, name)
326
+
327
+ def _validate_input_args(*args, **kwargs):
328
+ try:
329
+ import tensorflow as tf
330
+ except ImportError:
331
+ raise Exception('the input arguments of the custom loss function should be tensorflow tensors')
332
+
333
+ for i, arg in enumerate(args):
334
+ assert isinstance(arg, tf.Tensor), (f'tensorleap_custom_loss validation failed: '
335
+ f'Argument #{i} should be a tensorflow tensor. Got {type(arg)}.')
336
+ for _arg_name, arg in kwargs.items():
337
+ assert isinstance(arg, tf.Tensor), (f'tensorleap_custom_loss validation failed: '
338
+ f'Argument {_arg_name} should be a tensorflow tensor. Got {type(arg)}.')
339
+
340
+ def _validate_result(result):
341
+ try:
342
+ import tensorflow as tf
343
+ except ImportError:
344
+ raise Exception('the input arguments of the custom loss function should be tensorflow tensors')
345
+
346
+ assert isinstance(result, (np.ndarray, tf.Tensor)), \
347
+ (f'tensorleap_custom_loss validation failed: '
348
+ f'The return type should be a numpy array or a tensorflow tensor. Got {type(result)}.')
349
+
350
+ def inner(sample_id, preprocess_response):
351
+ _validate_input_args(sample_id, preprocess_response)
352
+ result = user_function(sample_id, preprocess_response)
353
+ _validate_result(result)
354
+ return result
355
+
356
+ return inner
357
+
358
+ return decorating_function
359
+
360
+
361
+ def tensorleap_custom_layer(name: str):
362
+ def decorating_function(custom_layer):
363
+ for custom_layer_handler in leap_binder.setup_container.custom_layers.values():
364
+ if custom_layer_handler.name == name:
365
+ raise Exception(f'Custom Layer with name {name} already exists. '
366
+ f'Please choose another')
367
+
368
+ try:
369
+ import tensorflow as tf
370
+ except ImportError:
371
+ raise Exception('The custom layer should be inherited from tf.keras.layers.Layer')
372
+
373
+ if not issubclass(custom_layer, tf.keras.layers.Layer):
374
+ raise Exception('The custom layer should be inherited from tf.keras.layers.Layer')
375
+
376
+ leap_binder.set_custom_layer(custom_layer, name)
377
+
378
+ return custom_layer
379
+
380
+ return decorating_function
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "code-loader"
3
- version = "1.0.51"
3
+ version = "1.0.52"
4
4
  description = ""
5
5
  authors = ["dorhar <doron.harnoy@tensorleap.ai>"]
6
6
  license = "MIT"
File without changes
File without changes