keras-nightly 3.12.0.dev2025092403__py3-none-any.whl → 3.14.0.dev2026010104__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.
- keras/__init__.py +1 -0
- keras/_tf_keras/keras/__init__.py +1 -0
- keras/_tf_keras/keras/callbacks/__init__.py +3 -0
- keras/_tf_keras/keras/distillation/__init__.py +16 -0
- keras/_tf_keras/keras/distribution/__init__.py +3 -0
- keras/_tf_keras/keras/layers/__init__.py +21 -0
- keras/_tf_keras/keras/ops/__init__.py +13 -0
- keras/_tf_keras/keras/ops/image/__init__.py +1 -0
- keras/_tf_keras/keras/ops/linalg/__init__.py +1 -0
- keras/_tf_keras/keras/ops/nn/__init__.py +3 -0
- keras/_tf_keras/keras/ops/numpy/__init__.py +9 -0
- keras/_tf_keras/keras/quantizers/__init__.py +12 -0
- keras/callbacks/__init__.py +3 -0
- keras/distillation/__init__.py +16 -0
- keras/distribution/__init__.py +3 -0
- keras/layers/__init__.py +21 -0
- keras/ops/__init__.py +13 -0
- keras/ops/image/__init__.py +1 -0
- keras/ops/linalg/__init__.py +1 -0
- keras/ops/nn/__init__.py +3 -0
- keras/ops/numpy/__init__.py +9 -0
- keras/quantizers/__init__.py +12 -0
- keras/src/applications/imagenet_utils.py +4 -1
- keras/src/backend/common/backend_utils.py +30 -6
- keras/src/backend/common/dtypes.py +1 -1
- keras/src/backend/common/name_scope.py +2 -1
- keras/src/backend/common/variables.py +33 -16
- keras/src/backend/jax/core.py +92 -3
- keras/src/backend/jax/distribution_lib.py +16 -2
- keras/src/backend/jax/linalg.py +4 -0
- keras/src/backend/jax/nn.py +485 -20
- keras/src/backend/jax/numpy.py +92 -23
- keras/src/backend/jax/optimizer.py +3 -2
- keras/src/backend/jax/trainer.py +14 -2
- keras/src/backend/numpy/linalg.py +4 -0
- keras/src/backend/numpy/nn.py +313 -2
- keras/src/backend/numpy/numpy.py +76 -7
- keras/src/backend/openvino/__init__.py +1 -0
- keras/src/backend/openvino/core.py +2 -23
- keras/src/backend/openvino/linalg.py +4 -0
- keras/src/backend/openvino/nn.py +271 -20
- keras/src/backend/openvino/numpy.py +1030 -185
- keras/src/backend/openvino/random.py +7 -14
- keras/src/backend/tensorflow/layer.py +43 -9
- keras/src/backend/tensorflow/linalg.py +24 -0
- keras/src/backend/tensorflow/nn.py +545 -1
- keras/src/backend/tensorflow/numpy.py +264 -54
- keras/src/backend/torch/core.py +3 -1
- keras/src/backend/torch/linalg.py +4 -0
- keras/src/backend/torch/nn.py +125 -0
- keras/src/backend/torch/numpy.py +84 -8
- keras/src/callbacks/__init__.py +1 -0
- keras/src/callbacks/callback_list.py +45 -11
- keras/src/callbacks/model_checkpoint.py +5 -0
- keras/src/callbacks/orbax_checkpoint.py +299 -0
- keras/src/callbacks/terminate_on_nan.py +54 -5
- keras/src/datasets/cifar10.py +5 -0
- keras/src/distillation/__init__.py +1 -0
- keras/src/distillation/distillation_loss.py +390 -0
- keras/src/distillation/distiller.py +598 -0
- keras/src/distribution/distribution_lib.py +14 -0
- keras/src/export/__init__.py +2 -0
- keras/src/export/export_utils.py +39 -2
- keras/src/export/litert.py +248 -0
- keras/src/export/openvino.py +1 -1
- keras/src/export/tf2onnx_lib.py +3 -0
- keras/src/layers/__init__.py +13 -0
- keras/src/layers/activations/softmax.py +9 -4
- keras/src/layers/attention/attention.py +1 -1
- keras/src/layers/attention/multi_head_attention.py +4 -1
- keras/src/layers/core/dense.py +191 -172
- keras/src/layers/core/einsum_dense.py +235 -186
- keras/src/layers/core/embedding.py +83 -93
- keras/src/layers/core/input_layer.py +1 -0
- keras/src/layers/core/reversible_embedding.py +390 -0
- keras/src/layers/input_spec.py +17 -17
- keras/src/layers/layer.py +40 -15
- keras/src/layers/merging/dot.py +4 -1
- keras/src/layers/pooling/adaptive_average_pooling1d.py +65 -0
- keras/src/layers/pooling/adaptive_average_pooling2d.py +62 -0
- keras/src/layers/pooling/adaptive_average_pooling3d.py +63 -0
- keras/src/layers/pooling/adaptive_max_pooling1d.py +65 -0
- keras/src/layers/pooling/adaptive_max_pooling2d.py +62 -0
- keras/src/layers/pooling/adaptive_max_pooling3d.py +63 -0
- keras/src/layers/pooling/base_adaptive_pooling.py +63 -0
- keras/src/layers/preprocessing/discretization.py +6 -5
- keras/src/layers/preprocessing/index_lookup.py +19 -1
- keras/src/layers/preprocessing/normalization.py +16 -1
- keras/src/layers/regularization/dropout.py +43 -1
- keras/src/layers/rnn/gru.py +1 -1
- keras/src/layers/rnn/lstm.py +2 -2
- keras/src/layers/rnn/rnn.py +19 -0
- keras/src/layers/rnn/simple_rnn.py +1 -1
- keras/src/losses/loss.py +1 -1
- keras/src/metrics/confusion_metrics.py +7 -6
- keras/src/models/cloning.py +4 -0
- keras/src/models/functional.py +11 -3
- keras/src/models/model.py +156 -27
- keras/src/ops/image.py +184 -3
- keras/src/ops/linalg.py +93 -0
- keras/src/ops/nn.py +268 -2
- keras/src/ops/numpy.py +541 -43
- keras/src/optimizers/adafactor.py +29 -10
- keras/src/optimizers/base_optimizer.py +22 -3
- keras/src/optimizers/loss_scale_optimizer.py +51 -18
- keras/src/optimizers/muon.py +65 -31
- keras/src/optimizers/schedules/learning_rate_schedule.py +4 -3
- keras/src/quantizers/__init__.py +12 -1
- keras/src/quantizers/gptq.py +8 -6
- keras/src/quantizers/gptq_config.py +36 -1
- keras/src/quantizers/gptq_core.py +150 -78
- keras/src/quantizers/quantization_config.py +232 -0
- keras/src/quantizers/quantizers.py +114 -38
- keras/src/quantizers/utils.py +23 -0
- keras/src/random/seed_generator.py +4 -2
- keras/src/saving/file_editor.py +81 -6
- keras/src/saving/saving_lib.py +1 -1
- keras/src/testing/__init__.py +1 -0
- keras/src/testing/test_case.py +45 -5
- keras/src/trainers/compile_utils.py +14 -5
- keras/src/utils/backend_utils.py +31 -4
- keras/src/utils/dataset_utils.py +234 -35
- keras/src/utils/file_utils.py +49 -11
- keras/src/utils/image_utils.py +14 -2
- keras/src/utils/jax_layer.py +187 -36
- keras/src/utils/module_utils.py +18 -0
- keras/src/utils/progbar.py +10 -12
- keras/src/utils/rng_utils.py +9 -1
- keras/src/version.py +1 -1
- {keras_nightly-3.12.0.dev2025092403.dist-info → keras_nightly-3.14.0.dev2026010104.dist-info}/METADATA +16 -6
- {keras_nightly-3.12.0.dev2025092403.dist-info → keras_nightly-3.14.0.dev2026010104.dist-info}/RECORD +133 -116
- {keras_nightly-3.12.0.dev2025092403.dist-info → keras_nightly-3.14.0.dev2026010104.dist-info}/WHEEL +0 -0
- {keras_nightly-3.12.0.dev2025092403.dist-info → keras_nightly-3.14.0.dev2026010104.dist-info}/top_level.txt +0 -0
|
@@ -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.
|
|
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.
|
|
238
|
+
dtype=self.output_dtype,
|
|
238
239
|
sparse=self.sparse,
|
|
239
240
|
backend_module=self.backend,
|
|
240
241
|
)
|
|
@@ -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
|
-
|
|
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
|
|
|
@@ -43,10 +44,12 @@ class Normalization(DataLayer):
|
|
|
43
44
|
will be broadcast to the shape of the kept axes above;
|
|
44
45
|
if the value(s) cannot be broadcast, an error will be raised when
|
|
45
46
|
this layer's `build()` method is called.
|
|
47
|
+
`mean` and `variance` must be specified together.
|
|
46
48
|
variance: The variance value(s) to use during normalization. The passed
|
|
47
49
|
value(s) will be broadcast to the shape of the kept axes above;
|
|
48
50
|
if the value(s) cannot be broadcast, an error will be raised when
|
|
49
51
|
this layer's `build()` method is called.
|
|
52
|
+
`mean` and `variance` must be specified together.
|
|
50
53
|
invert: If `True`, this layer will apply the inverse transformation
|
|
51
54
|
to its inputs: it would turn a normalized input back into its
|
|
52
55
|
original form.
|
|
@@ -227,6 +230,18 @@ class Normalization(DataLayer):
|
|
|
227
230
|
# Batch dataset if it isn't batched
|
|
228
231
|
data = data.batch(128)
|
|
229
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
|
+
)
|
|
230
245
|
|
|
231
246
|
if not self.built:
|
|
232
247
|
self.build(input_shape)
|
|
@@ -246,7 +261,7 @@ class Normalization(DataLayer):
|
|
|
246
261
|
elif backend.is_tensor(data):
|
|
247
262
|
total_mean = ops.mean(data, axis=self._reduce_axis)
|
|
248
263
|
total_var = ops.var(data, axis=self._reduce_axis)
|
|
249
|
-
elif isinstance(data, tf.data.Dataset):
|
|
264
|
+
elif isinstance(data, (tf.data.Dataset, PyDataset)):
|
|
250
265
|
total_mean = ops.zeros(self._mean_and_var_shape)
|
|
251
266
|
total_var = ops.zeros(self._mean_and_var_shape)
|
|
252
267
|
total_count = 0
|
|
@@ -48,13 +48,55 @@ class Dropout(Layer):
|
|
|
48
48
|
)
|
|
49
49
|
self.rate = rate
|
|
50
50
|
self.seed = seed
|
|
51
|
-
self.noise_shape = noise_shape
|
|
51
|
+
self.noise_shape = self._validate_noise_shape(noise_shape)
|
|
52
52
|
if rate > 0:
|
|
53
53
|
self.seed_generator = backend.random.SeedGenerator(seed)
|
|
54
54
|
self.supports_masking = True
|
|
55
55
|
|
|
56
56
|
self._build_at_init()
|
|
57
57
|
|
|
58
|
+
def _validate_noise_shape(self, noise_shape):
|
|
59
|
+
if noise_shape is None:
|
|
60
|
+
return None
|
|
61
|
+
|
|
62
|
+
if isinstance(noise_shape, str):
|
|
63
|
+
raise ValueError(
|
|
64
|
+
f"Invalid value received for argument `noise_shape`. "
|
|
65
|
+
f"Expected a tuple or list of integers. "
|
|
66
|
+
f"Received: noise_shape={noise_shape}"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
if not isinstance(noise_shape, tuple):
|
|
70
|
+
try:
|
|
71
|
+
noise_shape = tuple(noise_shape)
|
|
72
|
+
except TypeError:
|
|
73
|
+
raise ValueError(
|
|
74
|
+
f"Invalid value received for argument `noise_shape`. "
|
|
75
|
+
f"Expected an iterable of integers "
|
|
76
|
+
f"(e.g., a tuple or list). "
|
|
77
|
+
f"Received: noise_shape={noise_shape}"
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
for i, dim in enumerate(noise_shape):
|
|
81
|
+
if dim is not None:
|
|
82
|
+
if not isinstance(dim, int):
|
|
83
|
+
raise ValueError(
|
|
84
|
+
f"Invalid value received for argument `noise_shape`. "
|
|
85
|
+
f"Expected all elements to be integers or None. "
|
|
86
|
+
f"Received element at index {i}: {dim} "
|
|
87
|
+
f"(type: {type(dim).__name__})"
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
if dim <= 0:
|
|
91
|
+
raise ValueError(
|
|
92
|
+
f"Invalid value received for argument `noise_shape`. "
|
|
93
|
+
f"Expected all dimensions to be positive integers "
|
|
94
|
+
f"or None. "
|
|
95
|
+
f"Received negative or zero value at index {i}: {dim}"
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
return noise_shape
|
|
99
|
+
|
|
58
100
|
def call(self, inputs, training=False):
|
|
59
101
|
if training and self.rate > 0:
|
|
60
102
|
return backend.random.dropout(
|
keras/src/layers/rnn/gru.py
CHANGED
|
@@ -261,7 +261,7 @@ class GRUCell(Layer, DropoutRNNCell):
|
|
|
261
261
|
matrix_x = ops.matmul(inputs, self.kernel)
|
|
262
262
|
if self.use_bias:
|
|
263
263
|
# biases: bias_z_i, bias_r_i, bias_h_i
|
|
264
|
-
matrix_x
|
|
264
|
+
matrix_x = ops.add(matrix_x, input_bias)
|
|
265
265
|
|
|
266
266
|
x_z, x_r, x_h = ops.split(matrix_x, 3, axis=-1)
|
|
267
267
|
|
keras/src/layers/rnn/lstm.py
CHANGED
|
@@ -276,9 +276,9 @@ class LSTMCell(Layer, DropoutRNNCell):
|
|
|
276
276
|
|
|
277
277
|
z = ops.matmul(inputs, self.kernel)
|
|
278
278
|
|
|
279
|
-
z
|
|
279
|
+
z = ops.add(z, ops.matmul(h_tm1, self.recurrent_kernel))
|
|
280
280
|
if self.use_bias:
|
|
281
|
-
z
|
|
281
|
+
z = ops.add(z, self.bias)
|
|
282
282
|
|
|
283
283
|
z = ops.split(z, 4, axis=1)
|
|
284
284
|
c, o = self._compute_carry_and_output_fused(z, c_tm1)
|
keras/src/layers/rnn/rnn.py
CHANGED
|
@@ -212,6 +212,7 @@ class RNN(Layer):
|
|
|
212
212
|
self.supports_masking = True
|
|
213
213
|
self.input_spec = None
|
|
214
214
|
self.states = None
|
|
215
|
+
self._expected_batch_size = None
|
|
215
216
|
|
|
216
217
|
state_size = getattr(self.cell, "state_size", None)
|
|
217
218
|
if state_size is None:
|
|
@@ -283,6 +284,9 @@ class RNN(Layer):
|
|
|
283
284
|
f"batch size: sequence.shape={sequences_shape}"
|
|
284
285
|
)
|
|
285
286
|
self._create_state_variables(sequences_shape[0])
|
|
287
|
+
self._expected_batch_size = ops.shape(
|
|
288
|
+
tree.flatten(self.states)[0]
|
|
289
|
+
)[0]
|
|
286
290
|
|
|
287
291
|
@tracking.no_automatic_dependency_tracking
|
|
288
292
|
def _create_state_variables(self, batch_size):
|
|
@@ -382,6 +386,21 @@ class RNN(Layer):
|
|
|
382
386
|
initial_state = self.get_initial_state(
|
|
383
387
|
batch_size=ops.shape(sequences)[0]
|
|
384
388
|
)
|
|
389
|
+
if self.stateful:
|
|
390
|
+
actual_batch_size = sequences.shape[0]
|
|
391
|
+
if (
|
|
392
|
+
self._expected_batch_size is not None
|
|
393
|
+
and actual_batch_size is not None
|
|
394
|
+
and actual_batch_size != self._expected_batch_size
|
|
395
|
+
):
|
|
396
|
+
raise ValueError(
|
|
397
|
+
f"If an RNN is stateful, the batch size of the "
|
|
398
|
+
f"input sequences must be the same as the batch "
|
|
399
|
+
f"size of the initial state. \n"
|
|
400
|
+
f"- Expected batch size: {self._expected_batch_size}\n"
|
|
401
|
+
f"- Received batch size: {actual_batch_size}"
|
|
402
|
+
)
|
|
403
|
+
|
|
385
404
|
# RNN expect the states in a list, even if single state.
|
|
386
405
|
if not tree.is_nested(initial_state):
|
|
387
406
|
initial_state = [initial_state]
|
|
@@ -160,7 +160,7 @@ class SimpleRNNCell(Layer, DropoutRNNCell):
|
|
|
160
160
|
sequence = sequence * dp_mask
|
|
161
161
|
h = ops.matmul(sequence, self.kernel)
|
|
162
162
|
if self.bias is not None:
|
|
163
|
-
h
|
|
163
|
+
h = ops.add(h, self.bias)
|
|
164
164
|
|
|
165
165
|
if training and rec_dp_mask is not None:
|
|
166
166
|
prev_output = prev_output * rec_dp_mask
|
keras/src/losses/loss.py
CHANGED
|
@@ -211,7 +211,7 @@ def apply_mask(sample_weight, mask, dtype, reduction):
|
|
|
211
211
|
dtype,
|
|
212
212
|
)
|
|
213
213
|
valid = ops.sum(mask) # May be 0!
|
|
214
|
-
mask *= total
|
|
214
|
+
mask *= ops.divide_no_nan(total, valid)
|
|
215
215
|
|
|
216
216
|
if sample_weight is not None:
|
|
217
217
|
sample_weight = ops.cast(sample_weight, dtype=dtype)
|