keras-nightly 3.12.0.dev2025100503__py3-none-any.whl → 3.14.0.dev2026011604__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.
Files changed (136) hide show
  1. keras/__init__.py +1 -0
  2. keras/_tf_keras/keras/__init__.py +1 -0
  3. keras/_tf_keras/keras/callbacks/__init__.py +3 -0
  4. keras/_tf_keras/keras/distillation/__init__.py +16 -0
  5. keras/_tf_keras/keras/distribution/__init__.py +3 -0
  6. keras/_tf_keras/keras/dtype_policies/__init__.py +3 -0
  7. keras/_tf_keras/keras/layers/__init__.py +21 -0
  8. keras/_tf_keras/keras/ops/__init__.py +13 -0
  9. keras/_tf_keras/keras/ops/image/__init__.py +1 -0
  10. keras/_tf_keras/keras/ops/linalg/__init__.py +1 -0
  11. keras/_tf_keras/keras/ops/nn/__init__.py +3 -0
  12. keras/_tf_keras/keras/ops/numpy/__init__.py +9 -0
  13. keras/_tf_keras/keras/quantizers/__init__.py +13 -0
  14. keras/callbacks/__init__.py +3 -0
  15. keras/distillation/__init__.py +16 -0
  16. keras/distribution/__init__.py +3 -0
  17. keras/dtype_policies/__init__.py +3 -0
  18. keras/layers/__init__.py +21 -0
  19. keras/ops/__init__.py +13 -0
  20. keras/ops/image/__init__.py +1 -0
  21. keras/ops/linalg/__init__.py +1 -0
  22. keras/ops/nn/__init__.py +3 -0
  23. keras/ops/numpy/__init__.py +9 -0
  24. keras/quantizers/__init__.py +13 -0
  25. keras/src/applications/imagenet_utils.py +4 -1
  26. keras/src/backend/common/backend_utils.py +30 -6
  27. keras/src/backend/common/name_scope.py +2 -1
  28. keras/src/backend/common/variables.py +30 -15
  29. keras/src/backend/jax/core.py +92 -3
  30. keras/src/backend/jax/distribution_lib.py +16 -2
  31. keras/src/backend/jax/linalg.py +4 -0
  32. keras/src/backend/jax/nn.py +509 -29
  33. keras/src/backend/jax/numpy.py +59 -8
  34. keras/src/backend/jax/trainer.py +14 -2
  35. keras/src/backend/numpy/linalg.py +4 -0
  36. keras/src/backend/numpy/nn.py +311 -1
  37. keras/src/backend/numpy/numpy.py +65 -2
  38. keras/src/backend/openvino/__init__.py +1 -0
  39. keras/src/backend/openvino/core.py +2 -23
  40. keras/src/backend/openvino/linalg.py +4 -0
  41. keras/src/backend/openvino/nn.py +271 -20
  42. keras/src/backend/openvino/numpy.py +943 -189
  43. keras/src/backend/tensorflow/layer.py +43 -9
  44. keras/src/backend/tensorflow/linalg.py +24 -0
  45. keras/src/backend/tensorflow/nn.py +545 -1
  46. keras/src/backend/tensorflow/numpy.py +250 -50
  47. keras/src/backend/torch/core.py +3 -1
  48. keras/src/backend/torch/linalg.py +4 -0
  49. keras/src/backend/torch/nn.py +125 -0
  50. keras/src/backend/torch/numpy.py +80 -2
  51. keras/src/callbacks/__init__.py +1 -0
  52. keras/src/callbacks/model_checkpoint.py +5 -0
  53. keras/src/callbacks/orbax_checkpoint.py +332 -0
  54. keras/src/callbacks/terminate_on_nan.py +54 -5
  55. keras/src/datasets/cifar10.py +5 -0
  56. keras/src/distillation/__init__.py +1 -0
  57. keras/src/distillation/distillation_loss.py +390 -0
  58. keras/src/distillation/distiller.py +598 -0
  59. keras/src/distribution/distribution_lib.py +14 -0
  60. keras/src/dtype_policies/__init__.py +2 -0
  61. keras/src/dtype_policies/dtype_policy.py +90 -1
  62. keras/src/export/__init__.py +2 -0
  63. keras/src/export/export_utils.py +39 -2
  64. keras/src/export/litert.py +248 -0
  65. keras/src/export/openvino.py +1 -1
  66. keras/src/export/tf2onnx_lib.py +3 -0
  67. keras/src/layers/__init__.py +13 -0
  68. keras/src/layers/activations/softmax.py +9 -4
  69. keras/src/layers/attention/multi_head_attention.py +4 -1
  70. keras/src/layers/core/dense.py +241 -111
  71. keras/src/layers/core/einsum_dense.py +316 -131
  72. keras/src/layers/core/embedding.py +84 -94
  73. keras/src/layers/core/input_layer.py +1 -0
  74. keras/src/layers/core/reversible_embedding.py +399 -0
  75. keras/src/layers/input_spec.py +17 -17
  76. keras/src/layers/layer.py +45 -15
  77. keras/src/layers/merging/dot.py +4 -1
  78. keras/src/layers/pooling/adaptive_average_pooling1d.py +65 -0
  79. keras/src/layers/pooling/adaptive_average_pooling2d.py +62 -0
  80. keras/src/layers/pooling/adaptive_average_pooling3d.py +63 -0
  81. keras/src/layers/pooling/adaptive_max_pooling1d.py +65 -0
  82. keras/src/layers/pooling/adaptive_max_pooling2d.py +62 -0
  83. keras/src/layers/pooling/adaptive_max_pooling3d.py +63 -0
  84. keras/src/layers/pooling/base_adaptive_pooling.py +63 -0
  85. keras/src/layers/preprocessing/discretization.py +6 -5
  86. keras/src/layers/preprocessing/feature_space.py +8 -4
  87. keras/src/layers/preprocessing/image_preprocessing/aug_mix.py +2 -2
  88. keras/src/layers/preprocessing/image_preprocessing/random_contrast.py +3 -3
  89. keras/src/layers/preprocessing/image_preprocessing/resizing.py +10 -0
  90. keras/src/layers/preprocessing/index_lookup.py +19 -1
  91. keras/src/layers/preprocessing/normalization.py +14 -1
  92. keras/src/layers/regularization/dropout.py +43 -1
  93. keras/src/layers/rnn/rnn.py +19 -0
  94. keras/src/losses/loss.py +1 -1
  95. keras/src/losses/losses.py +24 -0
  96. keras/src/metrics/confusion_metrics.py +7 -6
  97. keras/src/models/cloning.py +4 -0
  98. keras/src/models/functional.py +11 -3
  99. keras/src/models/model.py +172 -34
  100. keras/src/ops/image.py +257 -20
  101. keras/src/ops/linalg.py +93 -0
  102. keras/src/ops/nn.py +258 -0
  103. keras/src/ops/numpy.py +569 -36
  104. keras/src/optimizers/muon.py +65 -31
  105. keras/src/optimizers/schedules/learning_rate_schedule.py +4 -3
  106. keras/src/quantizers/__init__.py +14 -1
  107. keras/src/quantizers/awq.py +361 -0
  108. keras/src/quantizers/awq_config.py +140 -0
  109. keras/src/quantizers/awq_core.py +217 -0
  110. keras/src/quantizers/gptq.py +2 -8
  111. keras/src/quantizers/gptq_config.py +36 -1
  112. keras/src/quantizers/gptq_core.py +65 -79
  113. keras/src/quantizers/quantization_config.py +246 -0
  114. keras/src/quantizers/quantizers.py +127 -61
  115. keras/src/quantizers/utils.py +23 -0
  116. keras/src/random/seed_generator.py +6 -4
  117. keras/src/saving/file_editor.py +81 -6
  118. keras/src/saving/orbax_util.py +26 -0
  119. keras/src/saving/saving_api.py +37 -14
  120. keras/src/saving/saving_lib.py +1 -1
  121. keras/src/testing/__init__.py +1 -0
  122. keras/src/testing/test_case.py +45 -5
  123. keras/src/utils/backend_utils.py +31 -4
  124. keras/src/utils/dataset_utils.py +234 -35
  125. keras/src/utils/file_utils.py +49 -11
  126. keras/src/utils/image_utils.py +14 -2
  127. keras/src/utils/jax_layer.py +244 -55
  128. keras/src/utils/module_utils.py +29 -0
  129. keras/src/utils/progbar.py +10 -2
  130. keras/src/utils/rng_utils.py +9 -1
  131. keras/src/utils/tracking.py +5 -5
  132. keras/src/version.py +1 -1
  133. {keras_nightly-3.12.0.dev2025100503.dist-info → keras_nightly-3.14.0.dev2026011604.dist-info}/METADATA +16 -6
  134. {keras_nightly-3.12.0.dev2025100503.dist-info → keras_nightly-3.14.0.dev2026011604.dist-info}/RECORD +136 -115
  135. {keras_nightly-3.12.0.dev2025100503.dist-info → keras_nightly-3.14.0.dev2026011604.dist-info}/WHEEL +0 -0
  136. {keras_nightly-3.12.0.dev2025100503.dist-info → keras_nightly-3.14.0.dev2026011604.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,65 @@
1
+ """Adaptive Average Pooling 1D layer."""
2
+
3
+ from keras.src.api_export import keras_export
4
+ from keras.src.layers.pooling.base_adaptive_pooling import (
5
+ BaseAdaptiveAveragePooling,
6
+ )
7
+
8
+
9
+ @keras_export("keras.layers.AdaptiveAveragePooling1D")
10
+ class AdaptiveAveragePooling1D(BaseAdaptiveAveragePooling):
11
+ """Adaptive average pooling operation for 1D temporal or spatial data.
12
+
13
+ This layer applies an adaptive average pooling operation, which pools the
14
+ input such that the output has a target length specified by `output_size`,
15
+ regardless of the input length. The kernel size and stride are automatically
16
+ computed to achieve the target output size.
17
+
18
+ Args:
19
+ output_size: Integer specifying the target output length.
20
+ data_format: string, either `"channels_last"` or `"channels_first"`.
21
+ `"channels_last"` corresponds to inputs with shape
22
+ `(batch, length, channels)`.
23
+ `"channels_first"` corresponds to inputs with shape
24
+ `(batch, channels, length)`.
25
+ Defaults to the value found in your Keras config file at
26
+ `~/.keras/keras.json`. If never set, `"channels_last"` is used.
27
+
28
+ Input shape:
29
+ - If `data_format="channels_last"`: 3D tensor
30
+ `(batch_size, length, channels)`
31
+ - If `data_format="channels_first"`: 3D tensor
32
+ `(batch_size, channels, length)`
33
+
34
+ Output shape:
35
+ - If `data_format="channels_last"`:
36
+ `(batch_size, output_length, channels)`
37
+ - If `data_format="channels_first"`:
38
+ `(batch_size, channels, output_length)`
39
+
40
+ Examples:
41
+ >>> import numpy as np
42
+ >>> input_seq = np.random.rand(1, 64, 3)
43
+ >>> layer = AdaptiveAveragePooling1D(output_size=32)
44
+ >>> output_seq = layer(input_seq)
45
+ >>> output_seq.shape
46
+ (1, 32, 3)
47
+ """
48
+
49
+ def __init__(self, output_size, data_format=None, **kwargs):
50
+ if isinstance(output_size, int):
51
+ output_size = (output_size,)
52
+ elif isinstance(output_size, (tuple, list)):
53
+ if len(output_size) != 1:
54
+ raise ValueError(
55
+ f"For 1D input, `output_size` tuple must have length 1. "
56
+ f"Received: {output_size}"
57
+ )
58
+ output_size = tuple(output_size)
59
+ else:
60
+ raise TypeError(
61
+ f"`output_size` must be an integer or tuple of 1 integer. "
62
+ f"Received: {output_size} of type {type(output_size)}"
63
+ )
64
+
65
+ super().__init__(output_size, data_format, **kwargs)
@@ -0,0 +1,62 @@
1
+ """Adaptive Average Pooling 2D layer."""
2
+
3
+ from keras.src.api_export import keras_export
4
+ from keras.src.layers.pooling.base_adaptive_pooling import (
5
+ BaseAdaptiveAveragePooling,
6
+ )
7
+
8
+
9
+ @keras_export("keras.layers.AdaptiveAveragePooling2D")
10
+ class AdaptiveAveragePooling2D(BaseAdaptiveAveragePooling):
11
+ """Adaptive average pooling operation for 2D spatial data.
12
+
13
+ This layer applies an adaptive average pooling operation, which pools the
14
+ input such that the output has a target spatial size specified by
15
+ `output_size`, regardless of the input spatial size. The kernel size
16
+ and stride are automatically computed to achieve the target output size.
17
+
18
+ Args:
19
+ output_size: Integer or tuple of 2 integers specifying the
20
+ target output size.
21
+ If an integer, the same value is used for both height and width.
22
+ data_format: string, either `"channels_last"` or `"channels_first"`.
23
+ `"channels_last"` corresponds to inputs with shape
24
+ `(batch, height, width, channels)`.
25
+ `"channels_first"` corresponds to inputs with shape
26
+ `(batch, channels, height, width)`.
27
+ Defaults to the value found in your Keras config file at
28
+ `~/.keras/keras.json`. If never set, `"channels_last"` is used.
29
+
30
+ Input shape:
31
+ - If `data_format="channels_last"`: 4D tensor
32
+ `(batch_size, height, width, channels)`
33
+ - If `data_format="channels_first"`: 4D tensor
34
+ `(batch_size, channels, height, width)`
35
+
36
+ Output shape:
37
+ - If `data_format="channels_last"`:
38
+ `(batch_size, output_height, output_width, channels)`
39
+ - If `data_format="channels_first"`:
40
+ `(batch_size, channels, output_height, output_width)`
41
+
42
+ Examples:
43
+ >>> import numpy as np
44
+ >>> input_img = np.random.rand(1, 64, 64, 3)
45
+ >>> layer = AdaptiveAveragePooling2D(output_size=32)
46
+ >>> output_img = layer(input_img)
47
+ >>> output_img.shape
48
+ (1, 32, 32, 3)
49
+ """
50
+
51
+ def __init__(self, output_size, data_format=None, **kwargs):
52
+ if isinstance(output_size, int):
53
+ output_size_tuple = (output_size, output_size)
54
+ elif isinstance(output_size, (tuple, list)) and len(output_size) == 2:
55
+ output_size_tuple = tuple(output_size)
56
+ else:
57
+ raise TypeError(
58
+ f"`output_size` must be an integer or (height, width) tuple. "
59
+ f"Received: {output_size} of type {type(output_size)}"
60
+ )
61
+
62
+ super().__init__(output_size_tuple, data_format, **kwargs)
@@ -0,0 +1,63 @@
1
+ """Adaptive Average Pooling 3D layer."""
2
+
3
+ from keras.src.api_export import keras_export
4
+ from keras.src.layers.pooling.base_adaptive_pooling import (
5
+ BaseAdaptiveAveragePooling,
6
+ )
7
+
8
+
9
+ @keras_export("keras.layers.AdaptiveAveragePooling3D")
10
+ class AdaptiveAveragePooling3D(BaseAdaptiveAveragePooling):
11
+ """Adaptive average pooling operation for 3D volumetric data.
12
+
13
+ This layer applies an adaptive average pooling operation, which pools the
14
+ input such that the output has a target spatial size specified by
15
+ `output_size`, regardless of the input spatial size. The kernel size
16
+ and stride are automatically computed to achieve the target output size.
17
+
18
+ Args:
19
+ output_size: Integer or tuple of 3 integers specifying the
20
+ target output size.
21
+ If an integer, the same value is used for depth, height, and width.
22
+ data_format: string, either `"channels_last"` or `"channels_first"`.
23
+ `"channels_last"` corresponds to inputs with shape
24
+ `(batch, depth, height, width, channels)`.
25
+ `"channels_first"` corresponds to inputs with shape
26
+ `(batch, channels, depth, height, width)`.
27
+ Defaults to the value found in your Keras config file at
28
+ `~/.keras/keras.json`. If never set, `"channels_last"` is used.
29
+
30
+ Input shape:
31
+ - If `data_format="channels_last"`: 5D tensor
32
+ `(batch_size, depth, height, width, channels)`
33
+ - If `data_format="channels_first"`: 5D tensor
34
+ `(batch_size, channels, depth, height, width)`
35
+
36
+ Output shape:
37
+ - If `data_format="channels_last"`:
38
+ `(batch_size, output_depth, output_height, output_width, channels)`
39
+ - If `data_format="channels_first"`:
40
+ `(batch_size, channels, output_depth, output_height, output_width)`
41
+
42
+ Examples:
43
+ >>> import numpy as np
44
+ >>> input_vol = np.random.rand(1, 32, 32, 32, 3)
45
+ >>> layer = AdaptiveAveragePooling3D(output_size=16)
46
+ >>> output_vol = layer(input_vol)
47
+ >>> output_vol.shape
48
+ (1, 16, 16, 16, 3)
49
+ """
50
+
51
+ def __init__(self, output_size, data_format=None, **kwargs):
52
+ if isinstance(output_size, int):
53
+ output_size_tuple = (output_size, output_size, output_size)
54
+ elif isinstance(output_size, (tuple, list)) and len(output_size) == 3:
55
+ output_size_tuple = tuple(output_size)
56
+ else:
57
+ raise TypeError(
58
+ f"`output_size` must be an integer or "
59
+ f"(depth, height, width) tuple. "
60
+ f"Received: {output_size} of type {type(output_size)}"
61
+ )
62
+
63
+ super().__init__(output_size_tuple, data_format, **kwargs)
@@ -0,0 +1,65 @@
1
+ """Adaptive Max Pooling 1D layer."""
2
+
3
+ from keras.src.api_export import keras_export
4
+ from keras.src.layers.pooling.base_adaptive_pooling import (
5
+ BaseAdaptiveMaxPooling,
6
+ )
7
+
8
+
9
+ @keras_export("keras.layers.AdaptiveMaxPooling1D")
10
+ class AdaptiveMaxPooling1D(BaseAdaptiveMaxPooling):
11
+ """Adaptive max pooling operation for 1D temporal or spatial data.
12
+
13
+ This layer applies an adaptive max pooling operation, which pools the
14
+ input such that the output has a target length specified by `output_size`,
15
+ regardless of the input length. The kernel size and stride are automatically
16
+ computed to achieve the target output size.
17
+
18
+ Args:
19
+ output_size: Integer specifying the target output length.
20
+ data_format: string, either `"channels_last"` or `"channels_first"`.
21
+ `"channels_last"` corresponds to inputs with shape
22
+ `(batch, length, channels)`.
23
+ `"channels_first"` corresponds to inputs with shape
24
+ `(batch, channels, length)`.
25
+ Defaults to the value found in your Keras config file at
26
+ `~/.keras/keras.json`. If never set, `"channels_last"` is used.
27
+
28
+ Input shape:
29
+ - If `data_format="channels_last"`: 3D tensor
30
+ `(batch_size, length, channels)`
31
+ - If `data_format="channels_first"`: 3D tensor
32
+ `(batch_size, channels, length)`
33
+
34
+ Output shape:
35
+ - If `data_format="channels_last"`:
36
+ `(batch_size, output_length, channels)`
37
+ - If `data_format="channels_first"`:
38
+ `(batch_size, channels, output_length)`
39
+
40
+ Examples:
41
+ >>> import numpy as np
42
+ >>> input_seq = np.random.rand(1, 64, 3)
43
+ >>> layer = AdaptiveMaxPooling1D(output_size=32)
44
+ >>> output_seq = layer(input_seq)
45
+ >>> output_seq.shape
46
+ (1, 32, 3)
47
+ """
48
+
49
+ def __init__(self, output_size, data_format=None, **kwargs):
50
+ if isinstance(output_size, int):
51
+ output_size = (output_size,)
52
+ elif isinstance(output_size, (tuple, list)):
53
+ if len(output_size) != 1:
54
+ raise ValueError(
55
+ f"For 1D input, `output_size` tuple must have length 1. "
56
+ f"Received: {output_size}"
57
+ )
58
+ output_size = tuple(output_size)
59
+ else:
60
+ raise TypeError(
61
+ f"`output_size` must be an integer or tuple of 1 integer. "
62
+ f"Received: {output_size} of type {type(output_size)}"
63
+ )
64
+
65
+ super().__init__(output_size, data_format, **kwargs)
@@ -0,0 +1,62 @@
1
+ """Adaptive Max Pooling 2D layer."""
2
+
3
+ from keras.src.api_export import keras_export
4
+ from keras.src.layers.pooling.base_adaptive_pooling import (
5
+ BaseAdaptiveMaxPooling,
6
+ )
7
+
8
+
9
+ @keras_export("keras.layers.AdaptiveMaxPooling2D")
10
+ class AdaptiveMaxPooling2D(BaseAdaptiveMaxPooling):
11
+ """Adaptive max pooling operation for 2D spatial data.
12
+
13
+ This layer applies an adaptive max pooling operation, which pools the
14
+ input such that the output has a target spatial size specified by
15
+ `output_size`, regardless of the input spatial size. The kernel size
16
+ and stride are automatically computed to achieve the target output size.
17
+
18
+ Args:
19
+ output_size: Integer or tuple of 2 integers specifying the
20
+ target output size.
21
+ If an integer, the same value is used for both height and width.
22
+ data_format: string, either `"channels_last"` or `"channels_first"`.
23
+ `"channels_last"` corresponds to inputs with shape
24
+ `(batch, height, width, channels)`.
25
+ `"channels_first"` corresponds to inputs with shape
26
+ `(batch, channels, height, width)`.
27
+ Defaults to the value found in your Keras config file at
28
+ `~/.keras/keras.json`. If never set, `"channels_last"` is used.
29
+
30
+ Input shape:
31
+ - If `data_format="channels_last"`: 4D tensor
32
+ `(batch_size, height, width, channels)`
33
+ - If `data_format="channels_first"`: 4D tensor
34
+ `(batch_size, channels, height, width)`
35
+
36
+ Output shape:
37
+ - If `data_format="channels_last"`:
38
+ `(batch_size, output_height, output_width, channels)`
39
+ - If `data_format="channels_first"`:
40
+ `(batch_size, channels, output_height, output_width)`
41
+
42
+ Examples:
43
+ >>> import numpy as np
44
+ >>> input_img = np.random.rand(1, 64, 64, 3)
45
+ >>> layer = AdaptiveMaxPooling2D(output_size=32)
46
+ >>> output_img = layer(input_img)
47
+ >>> output_img.shape
48
+ (1, 32, 32, 3)
49
+ """
50
+
51
+ def __init__(self, output_size, data_format=None, **kwargs):
52
+ if isinstance(output_size, int):
53
+ output_size_tuple = (output_size, output_size)
54
+ elif isinstance(output_size, (tuple, list)) and len(output_size) == 2:
55
+ output_size_tuple = tuple(output_size)
56
+ else:
57
+ raise TypeError(
58
+ f"`output_size` must be an integer or (height, width) tuple. "
59
+ f"Received: {output_size} of type {type(output_size)}"
60
+ )
61
+
62
+ super().__init__(output_size_tuple, data_format, **kwargs)
@@ -0,0 +1,63 @@
1
+ """Adaptive Max Pooling 3D layer."""
2
+
3
+ from keras.src.api_export import keras_export
4
+ from keras.src.layers.pooling.base_adaptive_pooling import (
5
+ BaseAdaptiveMaxPooling,
6
+ )
7
+
8
+
9
+ @keras_export("keras.layers.AdaptiveMaxPooling3D")
10
+ class AdaptiveMaxPooling3D(BaseAdaptiveMaxPooling):
11
+ """Adaptive max pooling operation for 3D volumetric data.
12
+
13
+ This layer applies an adaptive max pooling operation, which pools the
14
+ input such that the output has a target spatial size specified by
15
+ `output_size`, regardless of the input spatial size. The kernel size
16
+ and stride are automatically computed to achieve the target output size.
17
+
18
+ Args:
19
+ output_size: Integer or tuple of 3 integers specifying the
20
+ target output size.
21
+ If an integer, the same value is used for depth, height, and width.
22
+ data_format: string, either `"channels_last"` or `"channels_first"`.
23
+ `"channels_last"` corresponds to inputs with shape
24
+ `(batch, depth, height, width, channels)`.
25
+ `"channels_first"` corresponds to inputs with shape
26
+ `(batch, channels, depth, height, width)`.
27
+ Defaults to the value found in your Keras config file at
28
+ `~/.keras/keras.json`. If never set, `"channels_last"` is used.
29
+
30
+ Input shape:
31
+ - If `data_format="channels_last"`: 5D tensor
32
+ `(batch_size, depth, height, width, channels)`
33
+ - If `data_format="channels_first"`: 5D tensor
34
+ `(batch_size, channels, depth, height, width)`
35
+
36
+ Output shape:
37
+ - If `data_format="channels_last"`:
38
+ `(batch_size, output_depth, output_height, output_width, channels)`
39
+ - If `data_format="channels_first"`:
40
+ `(batch_size, channels, output_depth, output_height, output_width)`
41
+
42
+ Examples:
43
+ >>> import numpy as np
44
+ >>> input_vol = np.random.rand(1, 32, 32, 32, 3)
45
+ >>> layer = AdaptiveMaxPooling3D(output_size=16)
46
+ >>> output_vol = layer(input_vol)
47
+ >>> output_vol.shape
48
+ (1, 16, 16, 16, 3)
49
+ """
50
+
51
+ def __init__(self, output_size, data_format=None, **kwargs):
52
+ if isinstance(output_size, int):
53
+ output_size_tuple = (output_size, output_size, output_size)
54
+ elif isinstance(output_size, (tuple, list)) and len(output_size) == 3:
55
+ output_size_tuple = tuple(output_size)
56
+ else:
57
+ raise TypeError(
58
+ f"`output_size` must be an integer or "
59
+ f"(depth, height, width) tuple. "
60
+ f"Received: {output_size} of type {type(output_size)}"
61
+ )
62
+
63
+ super().__init__(output_size_tuple, data_format, **kwargs)
@@ -0,0 +1,63 @@
1
+ """Base classes for adaptive pooling layers."""
2
+
3
+ from keras.src import ops
4
+ from keras.src.backend import config
5
+ from keras.src.layers.layer import Layer
6
+
7
+
8
+ class BaseAdaptivePooling(Layer):
9
+ """Base class shared by all adaptive pooling layers."""
10
+
11
+ def __init__(self, output_size, data_format=None, **kwargs):
12
+ """Initialize base adaptive pooling layer.
13
+
14
+ Args:
15
+ output_size: Normalized spatial output size as a tuple
16
+ (for example, (32,), (32, 32), or (32, 32, 32)).
17
+ data_format: Either "channels_last" or "channels_first".
18
+ **kwargs: Additional layer keyword arguments.
19
+ """
20
+ super().__init__(**kwargs)
21
+ self.output_size = output_size
22
+ self.data_format = data_format or config.image_data_format()
23
+ if self.data_format not in {"channels_first", "channels_last"}:
24
+ raise ValueError(
25
+ f"Invalid data_format: {self.data_format}. "
26
+ "Expected 'channels_first' or 'channels_last'."
27
+ )
28
+
29
+ def compute_output_shape(self, input_shape):
30
+ """Return the output shape tensor after pooling."""
31
+ batch_size = input_shape[0]
32
+ if self.data_format == "channels_last":
33
+ channels = input_shape[-1]
34
+ return (batch_size, *self.output_size, channels)
35
+ else:
36
+ channels = input_shape[1]
37
+ return (batch_size, channels, *self.output_size)
38
+
39
+ def get_config(self):
40
+ config_dict = {
41
+ "output_size": self.output_size,
42
+ "data_format": self.data_format,
43
+ }
44
+ base_config = super().get_config()
45
+ return {**base_config, **config_dict}
46
+
47
+
48
+ class BaseAdaptiveAveragePooling(BaseAdaptivePooling):
49
+ """Base class for adaptive average pooling in 1D, 2D, and 3D."""
50
+
51
+ def call(self, inputs):
52
+ return ops.adaptive_average_pool(
53
+ inputs, output_size=self.output_size, data_format=self.data_format
54
+ )
55
+
56
+
57
+ class BaseAdaptiveMaxPooling(BaseAdaptivePooling):
58
+ """Base class for adaptive max pooling in 1D, 2D, and 3D."""
59
+
60
+ def call(self, inputs):
61
+ return ops.adaptive_max_pool(
62
+ inputs, output_size=self.output_size, data_format=self.data_format
63
+ )
@@ -95,9 +95,6 @@ class Discretization(DataLayer):
95
95
  dtype=None,
96
96
  name=None,
97
97
  ):
98
- if dtype is None:
99
- dtype = "int64" if output_mode == "int" else backend.floatx()
100
-
101
98
  super().__init__(name=name, dtype=dtype)
102
99
 
103
100
  if sparse and not backend.SUPPORTS_SPARSE_TENSORS:
@@ -155,6 +152,10 @@ class Discretization(DataLayer):
155
152
  def input_dtype(self):
156
153
  return backend.floatx()
157
154
 
155
+ @property
156
+ def output_dtype(self):
157
+ return self.compute_dtype if self.output_mode != "int" else "int32"
158
+
158
159
  def adapt(self, data, steps=None):
159
160
  """Computes bin boundaries from quantiles in a input dataset.
160
161
 
@@ -213,7 +214,7 @@ class Discretization(DataLayer):
213
214
  self.summary = np.array([[], []], dtype="float32")
214
215
 
215
216
  def compute_output_spec(self, inputs):
216
- return backend.KerasTensor(shape=inputs.shape, dtype=self.compute_dtype)
217
+ return backend.KerasTensor(shape=inputs.shape, dtype=self.output_dtype)
217
218
 
218
219
  def load_own_variables(self, store):
219
220
  if len(store) == 1:
@@ -234,7 +235,7 @@ class Discretization(DataLayer):
234
235
  indices,
235
236
  output_mode=self.output_mode,
236
237
  depth=len(self.bin_boundaries) + 1,
237
- dtype=self.compute_dtype,
238
+ dtype=self.output_dtype,
238
239
  sparse=self.sparse,
239
240
  backend_module=self.backend,
240
241
  )
@@ -507,10 +507,14 @@ class FeatureSpace(Layer):
507
507
 
508
508
  def adapt(self, dataset):
509
509
  if not isinstance(dataset, tf.data.Dataset):
510
- raise ValueError(
511
- "`adapt()` can only be called on a tf.data.Dataset. "
512
- f"Received instead: {dataset} (of type {type(dataset)})"
513
- )
510
+ if isinstance(dataset, dict):
511
+ dataset = tf.data.Dataset.from_tensor_slices(dataset)
512
+ else:
513
+ raise ValueError(
514
+ "`adapt()` can only be called on a tf.data.Dataset or a "
515
+ "dict of arrays/lists. "
516
+ f"Received instead: {dataset} (of type {type(dataset)})"
517
+ )
514
518
 
515
519
  for name in self._list_adaptable_preprocessors():
516
520
  # Call adapt() on each individual adaptable layer.
@@ -316,8 +316,8 @@ class AugMix(BaseImagePreprocessingLayer):
316
316
  def get_config(self):
317
317
  config = {
318
318
  "value_range": self.value_range,
319
- "num_chains": self.chain_depth,
320
- "chain_depth": self.num_chains,
319
+ "num_chains": self.num_chains,
320
+ "chain_depth": self.chain_depth,
321
321
  "factor": self.factor,
322
322
  "alpha": self.alpha,
323
323
  "all_ops": self.all_ops,
@@ -92,8 +92,8 @@ class RandomContrast(BaseImagePreprocessingLayer):
92
92
 
93
93
  def transform_images(self, images, transformation, training=True):
94
94
  if training:
95
- constrast_factor = transformation["contrast_factor"]
96
- outputs = self._adjust_constrast(images, constrast_factor)
95
+ contrast_factor = transformation["contrast_factor"]
96
+ outputs = self._adjust_contrast(images, contrast_factor)
97
97
  outputs = self.backend.numpy.clip(
98
98
  outputs, self.value_range[0], self.value_range[1]
99
99
  )
@@ -117,7 +117,7 @@ class RandomContrast(BaseImagePreprocessingLayer):
117
117
  ):
118
118
  return segmentation_masks
119
119
 
120
- def _adjust_constrast(self, inputs, contrast_factor):
120
+ def _adjust_contrast(self, inputs, contrast_factor):
121
121
  if self.data_format == "channels_first":
122
122
  height_axis = -2
123
123
  width_axis = -1
@@ -66,6 +66,16 @@ class Resizing(BaseImagePreprocessingLayer):
66
66
  `~/.keras/keras.json`. If you never set it, then it will be
67
67
  `"channels_last"`.
68
68
  **kwargs: Base layer keyword arguments, such as `name` and `dtype`.
69
+
70
+ Example:
71
+
72
+ ```python
73
+ (x_train, y_train), _ = keras.datasets.cifar10.load_data()
74
+ image = x_train[0]
75
+ resizer = keras.layers.Resizing(128, 128)
76
+ resized_image = resizer(image)
77
+ print("original:", image.shape, "resized:", resized_image.shape)
78
+ ```
69
79
  """
70
80
 
71
81
  _USE_BASE_FACTOR = False
@@ -4,6 +4,7 @@ import numpy as np
4
4
 
5
5
  from keras.src import backend
6
6
  from keras.src.layers.layer import Layer
7
+ from keras.src.saving import serialization_lib
7
8
  from keras.src.utils import argument_validation
8
9
  from keras.src.utils import numerical_utils
9
10
  from keras.src.utils import tf_utils
@@ -178,7 +179,12 @@ class IndexLookup(Layer):
178
179
  self.vocabulary_dtype = tf.as_dtype(vocabulary_dtype).name
179
180
  self._frozen_vocab_size = kwargs.pop("vocabulary_size", None)
180
181
 
181
- self.input_vocabulary = vocabulary
182
+ # Remember original `vocabulary` as `input_vocabulary` for serialization
183
+ # via `get_config`. However, if `vocabulary` is a file path or a URL, we
184
+ # serialize the vocabulary as an asset and clear the original path/URL.
185
+ self.input_vocabulary = (
186
+ vocabulary if not isinstance(vocabulary, str) else None
187
+ )
182
188
  self.input_idf_weights = idf_weights
183
189
 
184
190
  # We set this hidden attr to
@@ -382,6 +388,18 @@ class IndexLookup(Layer):
382
388
  )
383
389
 
384
390
  if isinstance(vocabulary, str):
391
+ if serialization_lib.in_safe_mode():
392
+ raise ValueError(
393
+ "Requested the loading of a vocabulary file outside of the "
394
+ "model archive. This carries a potential risk of loading "
395
+ "arbitrary and sensitive files and thus it is disallowed "
396
+ "by default. If you trust the source of the artifact, you "
397
+ "can override this error by passing `safe_mode=False` to "
398
+ "the loading function, or calling "
399
+ "`keras.config.enable_unsafe_deserialization(). "
400
+ f"Vocabulary file: '{vocabulary}'"
401
+ )
402
+
385
403
  if not tf.io.gfile.exists(vocabulary):
386
404
  raise ValueError(
387
405
  f"Vocabulary file {vocabulary} does not exist."
@@ -6,6 +6,7 @@ from keras.src import backend
6
6
  from keras.src import ops
7
7
  from keras.src.api_export import keras_export
8
8
  from keras.src.layers.preprocessing.data_layer import DataLayer
9
+ from keras.src.trainers.data_adapters.py_dataset_adapter import PyDataset
9
10
  from keras.src.utils.module_utils import tensorflow as tf
10
11
 
11
12
 
@@ -229,6 +230,18 @@ class Normalization(DataLayer):
229
230
  # Batch dataset if it isn't batched
230
231
  data = data.batch(128)
231
232
  input_shape = tuple(data.element_spec.shape)
233
+ elif isinstance(data, PyDataset):
234
+ data = data[0]
235
+ if isinstance(data, tuple):
236
+ # handling (x, y) or (x, y, sample_weight)
237
+ data = data[0]
238
+ input_shape = data.shape
239
+ else:
240
+ raise TypeError(
241
+ f"Unsupported data type: {type(data)}. `adapt` supports "
242
+ f"`np.ndarray`, backend tensors, `tf.data.Dataset`, and "
243
+ f"`keras.utils.PyDataset`."
244
+ )
232
245
 
233
246
  if not self.built:
234
247
  self.build(input_shape)
@@ -248,7 +261,7 @@ class Normalization(DataLayer):
248
261
  elif backend.is_tensor(data):
249
262
  total_mean = ops.mean(data, axis=self._reduce_axis)
250
263
  total_var = ops.var(data, axis=self._reduce_axis)
251
- elif isinstance(data, tf.data.Dataset):
264
+ elif isinstance(data, (tf.data.Dataset, PyDataset)):
252
265
  total_mean = ops.zeros(self._mean_and_var_shape)
253
266
  total_var = ops.zeros(self._mean_and_var_shape)
254
267
  total_count = 0