code-loader 1.0.172.dev3__tar.gz → 1.0.173__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 (36) hide show
  1. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/PKG-INFO +1 -1
  2. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/contract/datasetclasses.py +2 -38
  3. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/default_metrics.py +1 -1
  4. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/inner_leap_binder/leapbinder_decorators.py +70 -13
  5. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/pyproject.toml +1 -1
  6. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/LICENSE +0 -0
  7. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/README.md +0 -0
  8. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/__init__.py +0 -0
  9. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/contract/__init__.py +0 -0
  10. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/contract/enums.py +0 -0
  11. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/contract/exceptions.py +0 -0
  12. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/contract/mapping.py +0 -0
  13. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/contract/responsedataclasses.py +0 -0
  14. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/contract/visualizer_classes.py +0 -0
  15. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/default_losses.py +0 -0
  16. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/experiment_api/__init__.py +0 -0
  17. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/experiment_api/api.py +0 -0
  18. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/experiment_api/cli_config_utils.py +0 -0
  19. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/experiment_api/client.py +0 -0
  20. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/experiment_api/epoch.py +0 -0
  21. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/experiment_api/experiment.py +0 -0
  22. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/experiment_api/experiment_context.py +0 -0
  23. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/experiment_api/types.py +0 -0
  24. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/experiment_api/utils.py +0 -0
  25. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/experiment_api/workingspace_config_utils.py +0 -0
  26. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/inner_leap_binder/__init__.py +0 -0
  27. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/inner_leap_binder/leapbinder.py +0 -0
  28. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/leaploader.py +0 -0
  29. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/leaploaderbase.py +0 -0
  30. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/mixpanel_tracker.py +0 -0
  31. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/plot_functions/__init__.py +0 -0
  32. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/plot_functions/plot_functions.py +0 -0
  33. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/plot_functions/visualize.py +0 -0
  34. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/utils.py +0 -0
  35. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/code_loader/visualizers/__init__.py +0 -0
  36. {code_loader-1.0.172.dev3 → code_loader-1.0.173}/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.172.dev3
3
+ Version: 1.0.173
4
4
  Summary:
5
5
  Home-page: https://github.com/tensorleap/code-loader
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  import warnings
2
2
  from dataclasses import dataclass, field
3
- from typing import Any, Callable, Iterable, List, Optional, Dict, Union, Type, Literal, Tuple
3
+ from typing import Any, Callable, List, Optional, Dict, Union, Type, Literal
4
4
  import re
5
5
  import numpy as np
6
6
  import numpy.typing as npt
@@ -165,43 +165,6 @@ class MetricHandlerData:
165
165
  compute_insights: Optional[Union[bool, Dict[str, bool]]] = None
166
166
 
167
167
 
168
- def normalize_metric_handler_settings(
169
- direction: Union[None, MetricDirection, Dict[str, MetricDirection]],
170
- compute_insights: Optional[Union[bool, Dict[str, bool]]],
171
- result_keys: Iterable[str],
172
- ) -> Tuple[Union[None, MetricDirection, Dict[str, MetricDirection]], Optional[Union[bool, Dict[str, bool]]]]:
173
- ordered_result_keys = list(result_keys)
174
- if not ordered_result_keys:
175
- return direction, compute_insights
176
-
177
- normalized_direction = direction
178
- if direction is None:
179
- normalized_direction = {
180
- key: MetricDirection.Downward
181
- for key in ordered_result_keys
182
- }
183
- elif isinstance(direction, MetricDirection):
184
- normalized_direction = {key: direction for key in ordered_result_keys}
185
- elif isinstance(direction, dict):
186
- normalized_direction = {
187
- key: direction.get(key, MetricDirection.Downward)
188
- for key in ordered_result_keys
189
- }
190
-
191
- normalized_compute_insights = compute_insights
192
- if compute_insights is None:
193
- normalized_compute_insights = {}
194
- elif isinstance(compute_insights, bool):
195
- normalized_compute_insights = {key: compute_insights for key in ordered_result_keys}
196
- elif isinstance(compute_insights, dict):
197
- normalized_compute_insights = {
198
- key: compute_insights.get(key, True)
199
- for key in ordered_result_keys
200
- }
201
-
202
- return normalized_direction, normalized_compute_insights
203
-
204
-
205
168
  @dataclass
206
169
  class MetricHandler:
207
170
  metric_handler_data: MetricHandlerData
@@ -309,3 +272,4 @@ class DatasetSample:
309
272
  state: DataStateEnum
310
273
  custom_latent_space: Optional[npt.NDArray[np.float32]] = None
311
274
  instance_masks: Optional[Dict[str, ElementInstance]] = None
275
+
@@ -29,7 +29,7 @@ def binary_crossentropy(ground_truth: np.array, prediction: np.array) -> np.arra
29
29
 
30
30
  def categorical_crossentropy(ground_truth: np.array, prediction: np.array) -> np.array:
31
31
  ground_truth, prediction = flatten_non_batch_dims(ground_truth, prediction)
32
- prediction = prediction / np.sum(prediction, axis=1)
32
+ prediction = prediction / np.sum(prediction, axis=1, keepdims=True)
33
33
  epsilon = 1e-07
34
34
  prediction = np.clip(prediction, epsilon, 1.0 - epsilon)
35
35
  return -(ground_truth * np.log(prediction)).sum(axis=1).astype(np.float32)
@@ -19,7 +19,7 @@ from code_loader.contract.datasetclasses import CustomCallableInterfaceMultiArgs
19
19
  CustomMultipleReturnCallableInterfaceMultiArgs, ConfusionMatrixCallableInterfaceMultiArgs, CustomCallableInterface, \
20
20
  VisualizerCallableInterface, MetadataSectionCallableInterface, PreprocessResponse, SectionCallableInterface, \
21
21
  ConfusionMatrixElement, SamplePreprocessResponse, PredictionTypeHandler, InstanceCallableInterface, ElementInstance, \
22
- InstanceLengthCallableInterface, normalize_metric_handler_settings
22
+ InstanceLengthCallableInterface
23
23
  from code_loader.contract.enums import MetricDirection, LeapDataType, DatasetMetadataType, DataStateType
24
24
  from code_loader import leap_binder, LeapLoader
25
25
  from code_loader.contract.mapping import NodeMapping, NodeMappingType, NodeConnection
@@ -365,14 +365,62 @@ def tensorleap_load_model(prediction_types: Optional[List[PredictionTypeHandler]
365
365
  self.model = load_model_func()
366
366
  self.prediction_types = prediction_types
367
367
  _validate_result(self.model)
368
+ self.fixed_batch_size = self._detect_fixed_batch_size()
369
+
370
+ def _detect_fixed_batch_size(self):
371
+ """Detect if the model requires a fixed batch size > 1."""
372
+ try:
373
+ import onnxruntime
374
+ if isinstance(self.model, onnxruntime.InferenceSession):
375
+ inputs = self.model.get_inputs()
376
+ if inputs:
377
+ batch_dim = inputs[0].shape[0]
378
+ if isinstance(batch_dim, int) and batch_dim > 1:
379
+ return batch_dim
380
+ return None
381
+ except ImportError:
382
+ pass
383
+ try:
384
+ input_shape = self.model.input_shape
385
+ if isinstance(input_shape, list):
386
+ batch_dim = input_shape[0][0]
387
+ else:
388
+ batch_dim = input_shape[0]
389
+ if isinstance(batch_dim, int) and batch_dim > 1:
390
+ return batch_dim
391
+ except Exception:
392
+ pass
393
+ return None
394
+
395
+ def _tile_inputs(self, arg):
396
+ """Tile batch-1 inputs to match the model's fixed batch size."""
397
+ if isinstance(arg, list):
398
+ return [np.repeat(a, self.fixed_batch_size, axis=0)
399
+ if isinstance(a, np.ndarray) and a.shape[0] == 1 else a
400
+ for a in arg]
401
+ elif isinstance(arg, np.ndarray) and arg.shape[0] == 1:
402
+ return np.repeat(arg, self.fixed_batch_size, axis=0)
403
+ return arg
404
+
405
+ def _slice_outputs(self, result):
406
+ """Slice batched outputs back to batch=1."""
407
+ if isinstance(result, list):
408
+ return [r[:1] for r in result]
409
+ return result[:1]
368
410
 
369
411
  # keras interface
370
412
  def __call__(self, arg):
413
+ if self.fixed_batch_size and self.fixed_batch_size > 1 and _called_from_inside_tl_integration_test_decorator:
414
+ arg = self._tile_inputs(arg)
371
415
  ret = self.model(arg)
372
416
  self.validate_declared_prediction_types(ret)
373
417
  if isinstance(ret, list):
374
- return [r.numpy() for r in ret]
375
- return ret.numpy()
418
+ result = [r.numpy() for r in ret]
419
+ else:
420
+ result = ret.numpy()
421
+ if self.fixed_batch_size and self.fixed_batch_size > 1 and _called_from_inside_tl_integration_test_decorator:
422
+ result = self._slice_outputs(result)
423
+ return result
376
424
 
377
425
  def validate_declared_prediction_types(self, ret):
378
426
  if not (len(self.prediction_types) == len(ret) if isinstance(ret, list) else 1) and len(
@@ -444,8 +492,16 @@ def tensorleap_load_model(prediction_types: Optional[List[PredictionTypeHandler]
444
492
  # onnx runtime interface
445
493
  def run(self, output_names, input_dict):
446
494
  corrected_type_inputs = self._convert_onnx_inputs_to_correct_type(input_dict)
495
+ if self.fixed_batch_size and self.fixed_batch_size > 1 and _called_from_inside_tl_integration_test_decorator:
496
+ corrected_type_inputs = {
497
+ k: np.repeat(v, self.fixed_batch_size, axis=0)
498
+ if isinstance(v, np.ndarray) and v.shape[0] == 1 else v
499
+ for k, v in corrected_type_inputs.items()
500
+ }
447
501
  ret = self.model.run(output_names, corrected_type_inputs)
448
502
  self.validate_declared_prediction_types(ret)
503
+ if self.fixed_batch_size and self.fixed_batch_size > 1 and _called_from_inside_tl_integration_test_decorator:
504
+ ret = [r[:1] if isinstance(r, np.ndarray) else r for r in ret]
449
505
  return ret
450
506
 
451
507
  def get_inputs(self):
@@ -699,21 +755,21 @@ def tensorleap_custom_metric(name: str,
699
755
  (f'{user_function.__name__}() validation failed: '
700
756
  f'Keys in the compute_insights mapping should be part of result keys. Got key {ci_key}.')
701
757
 
702
- normalized_direction_input = None if direction is _UNSET else direction
703
- effective_direction, effective_compute_insights = normalize_metric_handler_settings(
704
- normalized_direction_input,
705
- compute_insights,
706
- result.keys(),
707
- )
758
+ effective_direction = {} if direction is _UNSET else direction if isinstance(direction, dict) else {k:direction for k in result_keys}
759
+ defaulted_direction_keys = result_keys.difference(effective_direction.keys())
708
760
 
709
- defaulted_direction_keys = set()
710
- if isinstance(direction, dict):
711
- defaulted_direction_keys = result_keys.difference(direction.keys())
761
+ if defaulted_direction_keys:
762
+ effective_direction = {key: effective_direction.get(key, MetricDirection.Downward) for key in result}
712
763
 
713
764
  leap_binder.setup_container.metrics[-1].metric_handler_data.direction = effective_direction
714
- leap_binder.setup_container.metrics[-1].metric_handler_data.compute_insights = effective_compute_insights
715
765
 
716
766
  if defaulted_direction_keys and not _call_from_tl_platform:
767
+ if compute_insights is None:
768
+ effective_compute_insights = {}
769
+ elif isinstance(compute_insights, dict):
770
+ effective_compute_insights = compute_insights
771
+ else:
772
+ effective_compute_insights = {k: compute_insights for k in result_keys}
717
773
  warning_keys = {key for key in defaulted_direction_keys if effective_compute_insights.get(key, True)}
718
774
  if warning_keys:
719
775
  store_warning_by_param(
@@ -1814,3 +1870,4 @@ if not _call_from_tl_platform:
1814
1870
 
1815
1871
 
1816
1872
 
1873
+
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "code-loader"
3
- version = "1.0.172.dev3"
3
+ version = "1.0.173"
4
4
  description = ""
5
5
  authors = ["dorhar <doron.harnoy@tensorleap.ai>"]
6
6
  license = "MIT"