keras-nightly 3.14.0.dev2026010104__py3-none-any.whl → 3.14.0.dev2026012204__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/_tf_keras/keras/dtype_policies/__init__.py +3 -0
- keras/_tf_keras/keras/ops/__init__.py +2 -0
- keras/_tf_keras/keras/ops/numpy/__init__.py +2 -0
- keras/_tf_keras/keras/quantizers/__init__.py +1 -0
- keras/dtype_policies/__init__.py +3 -0
- keras/ops/__init__.py +2 -0
- keras/ops/numpy/__init__.py +2 -0
- keras/quantizers/__init__.py +1 -0
- keras/src/backend/jax/nn.py +26 -9
- keras/src/backend/jax/numpy.py +10 -0
- keras/src/backend/numpy/numpy.py +15 -0
- keras/src/backend/openvino/numpy.py +338 -17
- keras/src/backend/tensorflow/numpy.py +24 -1
- keras/src/backend/tensorflow/rnn.py +17 -7
- keras/src/backend/torch/numpy.py +26 -0
- keras/src/backend/torch/rnn.py +28 -11
- keras/src/callbacks/orbax_checkpoint.py +75 -42
- keras/src/dtype_policies/__init__.py +2 -0
- keras/src/dtype_policies/dtype_policy.py +90 -1
- keras/src/layers/core/dense.py +122 -6
- keras/src/layers/core/einsum_dense.py +151 -7
- keras/src/layers/core/embedding.py +1 -1
- keras/src/layers/core/reversible_embedding.py +10 -1
- keras/src/layers/layer.py +5 -0
- keras/src/layers/preprocessing/feature_space.py +8 -4
- keras/src/layers/preprocessing/image_preprocessing/aug_mix.py +2 -2
- keras/src/layers/preprocessing/image_preprocessing/center_crop.py +13 -15
- keras/src/layers/preprocessing/image_preprocessing/random_contrast.py +3 -3
- keras/src/layers/preprocessing/image_preprocessing/resizing.py +10 -0
- keras/src/losses/losses.py +24 -0
- keras/src/models/model.py +18 -9
- keras/src/ops/image.py +106 -93
- keras/src/ops/numpy.py +138 -0
- keras/src/quantizers/__init__.py +2 -0
- keras/src/quantizers/awq.py +361 -0
- keras/src/quantizers/awq_config.py +140 -0
- keras/src/quantizers/awq_core.py +217 -0
- keras/src/quantizers/gptq.py +1 -2
- keras/src/quantizers/gptq_core.py +1 -1
- keras/src/quantizers/quantization_config.py +14 -0
- keras/src/quantizers/quantizers.py +61 -52
- keras/src/random/seed_generator.py +2 -2
- keras/src/saving/orbax_util.py +50 -0
- keras/src/saving/saving_api.py +37 -14
- keras/src/utils/jax_layer.py +69 -31
- keras/src/utils/module_utils.py +11 -0
- keras/src/utils/tracking.py +5 -5
- keras/src/version.py +1 -1
- {keras_nightly-3.14.0.dev2026010104.dist-info → keras_nightly-3.14.0.dev2026012204.dist-info}/METADATA +1 -1
- {keras_nightly-3.14.0.dev2026010104.dist-info → keras_nightly-3.14.0.dev2026012204.dist-info}/RECORD +52 -48
- {keras_nightly-3.14.0.dev2026010104.dist-info → keras_nightly-3.14.0.dev2026012204.dist-info}/WHEEL +1 -1
- {keras_nightly-3.14.0.dev2026010104.dist-info → keras_nightly-3.14.0.dev2026012204.dist-info}/top_level.txt +0 -0
keras/src/models/model.py
CHANGED
|
@@ -9,6 +9,7 @@ from keras.src import utils
|
|
|
9
9
|
from keras.src.api_export import keras_export
|
|
10
10
|
from keras.src.layers.layer import Layer
|
|
11
11
|
from keras.src.models.variable_mapping import map_saveable_variables
|
|
12
|
+
from keras.src.quantizers.awq_core import awq_quantize
|
|
12
13
|
from keras.src.quantizers.gptq_core import gptq_quantize
|
|
13
14
|
from keras.src.quantizers.utils import should_quantize_layer
|
|
14
15
|
from keras.src.saving import saving_api
|
|
@@ -547,7 +548,7 @@ class Model(Trainer, base_trainer.Trainer, Layer):
|
|
|
547
548
|
except AttributeError:
|
|
548
549
|
pass
|
|
549
550
|
|
|
550
|
-
if mode
|
|
551
|
+
if mode in ["gptq", "awq"]:
|
|
551
552
|
# Resolve model structure.
|
|
552
553
|
# 1. If quantization_layer_structure is provided inside the config,
|
|
553
554
|
# use that.
|
|
@@ -559,14 +560,17 @@ class Model(Trainer, base_trainer.Trainer, Layer):
|
|
|
559
560
|
|
|
560
561
|
if structure is None:
|
|
561
562
|
raise ValueError(
|
|
562
|
-
"For
|
|
563
|
+
f"For {mode=}, a valid quantization structure must be "
|
|
563
564
|
"provided either via `config.quantization_layer_structure` "
|
|
564
565
|
"or by overriding "
|
|
565
566
|
"`model.get_quantization_layer_structure(mode)`. The "
|
|
566
567
|
"structure should be a dictionary with keys "
|
|
567
568
|
"'pre_block_layers' and 'sequential_blocks'."
|
|
568
569
|
)
|
|
569
|
-
|
|
570
|
+
if mode == "gptq":
|
|
571
|
+
gptq_quantize(config, structure, filters=filters)
|
|
572
|
+
elif mode == "awq":
|
|
573
|
+
awq_quantize(config, structure, filters=filters)
|
|
570
574
|
|
|
571
575
|
# If any layer was changed, we must rebuild the execution functions.
|
|
572
576
|
if graph_modified:
|
|
@@ -992,13 +996,18 @@ class Model(Trainer, base_trainer.Trainer, Layer):
|
|
|
992
996
|
self.non_trainable_variables, path_value_dict
|
|
993
997
|
)
|
|
994
998
|
elif k == "optimizer_variables":
|
|
995
|
-
self.
|
|
996
|
-
self.
|
|
997
|
-
|
|
999
|
+
if hasattr(self, "optimizer") and self.optimizer is not None:
|
|
1000
|
+
self._assign_variable_values(
|
|
1001
|
+
self.optimizer.variables, path_value_dict
|
|
1002
|
+
)
|
|
998
1003
|
elif k == "metrics_variables":
|
|
999
|
-
|
|
1000
|
-
self
|
|
1001
|
-
|
|
1004
|
+
if (
|
|
1005
|
+
hasattr(self, "metrics_variables")
|
|
1006
|
+
and self.metrics_variables
|
|
1007
|
+
):
|
|
1008
|
+
self._assign_variable_values(
|
|
1009
|
+
self.metrics_variables, path_value_dict
|
|
1010
|
+
)
|
|
1002
1011
|
else:
|
|
1003
1012
|
raise ValueError(f"Unknown variable name: {k}")
|
|
1004
1013
|
|
keras/src/ops/image.py
CHANGED
|
@@ -565,6 +565,7 @@ class ExtractPatches(Operation):
|
|
|
565
565
|
if isinstance(size, int):
|
|
566
566
|
size = (size, size)
|
|
567
567
|
self.size = size
|
|
568
|
+
self.is_3d = len(self.size) == 3
|
|
568
569
|
if strides is None:
|
|
569
570
|
strides = size
|
|
570
571
|
self.strides = strides
|
|
@@ -588,11 +589,21 @@ class ExtractPatches(Operation):
|
|
|
588
589
|
if self.data_format == "channels_last":
|
|
589
590
|
channels_in = images_shape[-1]
|
|
590
591
|
else:
|
|
591
|
-
channels_in = images_shape[-3]
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
592
|
+
channels_in = images_shape[-4] if self.is_3d else images_shape[-3]
|
|
593
|
+
|
|
594
|
+
if self.is_3d:
|
|
595
|
+
# 3D patch extraction
|
|
596
|
+
if original_ndim == 4:
|
|
597
|
+
images_shape = [1] + images_shape
|
|
598
|
+
filters = self.size[0] * self.size[1] * self.size[2] * channels_in
|
|
599
|
+
kernel_size = (self.size[0], self.size[1], self.size[2])
|
|
600
|
+
else:
|
|
601
|
+
# 2D patch extraction
|
|
602
|
+
if original_ndim == 3:
|
|
603
|
+
images_shape = [1] + images_shape
|
|
604
|
+
filters = self.size[0] * self.size[1] * channels_in
|
|
605
|
+
kernel_size = (self.size[0], self.size[1])
|
|
606
|
+
|
|
596
607
|
out_shape = compute_conv_output_shape(
|
|
597
608
|
images_shape,
|
|
598
609
|
filters,
|
|
@@ -602,10 +613,24 @@ class ExtractPatches(Operation):
|
|
|
602
613
|
data_format=self.data_format,
|
|
603
614
|
dilation_rate=self.dilation_rate,
|
|
604
615
|
)
|
|
605
|
-
|
|
606
|
-
|
|
616
|
+
|
|
617
|
+
if self.is_3d:
|
|
618
|
+
if original_ndim == 4:
|
|
619
|
+
out_shape = out_shape[1:]
|
|
620
|
+
else:
|
|
621
|
+
if original_ndim == 3:
|
|
622
|
+
out_shape = out_shape[1:]
|
|
607
623
|
return KerasTensor(shape=out_shape, dtype=images.dtype)
|
|
608
624
|
|
|
625
|
+
def get_config(self):
|
|
626
|
+
return {
|
|
627
|
+
"size": self.size,
|
|
628
|
+
"strides": self.strides,
|
|
629
|
+
"dilation_rate": self.dilation_rate,
|
|
630
|
+
"padding": self.padding,
|
|
631
|
+
"data_format": self.data_format,
|
|
632
|
+
}
|
|
633
|
+
|
|
609
634
|
|
|
610
635
|
@keras_export("keras.ops.image.extract_patches")
|
|
611
636
|
def extract_patches(
|
|
@@ -616,42 +641,78 @@ def extract_patches(
|
|
|
616
641
|
padding="valid",
|
|
617
642
|
data_format=None,
|
|
618
643
|
):
|
|
619
|
-
"""Extracts patches from the image(s).
|
|
644
|
+
"""Extracts patches from the image(s) or volume(s).
|
|
645
|
+
|
|
646
|
+
This function supports both 2D and 3D patch extraction based on the
|
|
647
|
+
`size` argument length, similar to how `keras.ops.conv` handles
|
|
648
|
+
different dimensions.
|
|
620
649
|
|
|
621
650
|
Args:
|
|
622
|
-
images: Input image or batch of images.
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
651
|
+
images: Input image/volume or batch of images/volumes.
|
|
652
|
+
For 2D patches: 3D `(H, W, C)` or 4D `(N, H, W, C)`.
|
|
653
|
+
For 3D patches: 4D `(D, H, W, C)` or 5D `(N, D, H, W, C)`.
|
|
654
|
+
size: Patch size as int or tuple.
|
|
655
|
+
Length 2 tuple `(patch_height, patch_width)` or int for 2D patches.
|
|
656
|
+
Length 3 tuple `(patch_depth, patch_height, patch_width)` for
|
|
657
|
+
3D patches.
|
|
658
|
+
strides: Strides for patch extraction. If not specified, defaults
|
|
659
|
+
to `size` (non-overlapping patches).
|
|
660
|
+
dilation_rate: Dilation rate for patch extraction. Note that
|
|
661
|
+
`dilation_rate > 1` is not supported with `strides > 1`.
|
|
630
662
|
padding: The type of padding algorithm to use: `"same"` or `"valid"`.
|
|
631
663
|
data_format: A string specifying the data format of the input tensor.
|
|
632
664
|
It can be either `"channels_last"` or `"channels_first"`.
|
|
633
|
-
|
|
634
|
-
`(batch, height, width, channels)`, while `"channels_first"`
|
|
635
|
-
corresponds to inputs with shape `(batch, channels, height, width)`.
|
|
636
|
-
If not specified, the value will default to
|
|
637
|
-
`keras.config.image_data_format`.
|
|
665
|
+
If not specified, defaults to `keras.config.image_data_format`.
|
|
638
666
|
|
|
639
667
|
Returns:
|
|
640
|
-
Extracted patches
|
|
668
|
+
Extracted patches with shape depending on input and `size`:
|
|
669
|
+
- 2D patches: 3D (unbatched) or 4D (batched)
|
|
670
|
+
- 3D patches: 4D (unbatched) or 5D (batched)
|
|
641
671
|
|
|
642
672
|
Examples:
|
|
643
673
|
|
|
674
|
+
>>> # 2D patches from batch of images
|
|
644
675
|
>>> image = np.random.random(
|
|
645
676
|
... (2, 20, 20, 3)
|
|
646
|
-
... ).astype("float32")
|
|
677
|
+
... ).astype("float32")
|
|
647
678
|
>>> patches = keras.ops.image.extract_patches(image, (5, 5))
|
|
648
679
|
>>> patches.shape
|
|
649
680
|
(2, 4, 4, 75)
|
|
650
|
-
|
|
681
|
+
|
|
682
|
+
>>> # 2D patches from single image
|
|
683
|
+
>>> image = np.random.random((20, 20, 3)).astype("float32")
|
|
651
684
|
>>> patches = keras.ops.image.extract_patches(image, (3, 3), (1, 1))
|
|
652
685
|
>>> patches.shape
|
|
653
686
|
(18, 18, 27)
|
|
687
|
+
|
|
688
|
+
>>> # 3D patches from batch of volumes
|
|
689
|
+
>>> volumes = np.random.random(
|
|
690
|
+
... (2, 10, 10, 10, 3)
|
|
691
|
+
... ).astype("float32")
|
|
692
|
+
>>> patches = keras.ops.image.extract_patches(volumes, (3, 3, 3))
|
|
693
|
+
>>> patches.shape
|
|
694
|
+
(2, 3, 3, 3, 81)
|
|
695
|
+
|
|
696
|
+
>>> # 3D patches from single volume
|
|
697
|
+
>>> volume = np.random.random((10, 10, 10, 3)).astype("float32")
|
|
698
|
+
>>> patches = keras.ops.image.extract_patches(volume, (3, 3, 3))
|
|
699
|
+
>>> patches.shape
|
|
700
|
+
(3, 3, 3, 81)
|
|
654
701
|
"""
|
|
702
|
+
# Validate size argument
|
|
703
|
+
if not isinstance(size, int):
|
|
704
|
+
if not isinstance(size, (tuple, list)):
|
|
705
|
+
raise TypeError(
|
|
706
|
+
"Invalid `size` argument. Expected an int or a tuple. "
|
|
707
|
+
f"Received: size={size} of type {type(size).__name__}"
|
|
708
|
+
)
|
|
709
|
+
if len(size) not in (2, 3):
|
|
710
|
+
raise ValueError(
|
|
711
|
+
"Invalid `size` argument. Expected a tuple of length 2 or 3. "
|
|
712
|
+
f"Received: size={size} with length {len(size)}"
|
|
713
|
+
)
|
|
714
|
+
|
|
715
|
+
# 2D patch extraction (default)
|
|
655
716
|
if any_symbolic_tensors((images,)):
|
|
656
717
|
return ExtractPatches(
|
|
657
718
|
size=size,
|
|
@@ -673,6 +734,23 @@ def _extract_patches(
|
|
|
673
734
|
dilation_rate=1,
|
|
674
735
|
padding="valid",
|
|
675
736
|
data_format=None,
|
|
737
|
+
):
|
|
738
|
+
if not isinstance(size, int) and len(size) == 3:
|
|
739
|
+
return _extract_patches_3d(
|
|
740
|
+
images, size, strides, dilation_rate, padding, data_format
|
|
741
|
+
)
|
|
742
|
+
return _extract_patches_2d(
|
|
743
|
+
images, size, strides, dilation_rate, padding, data_format
|
|
744
|
+
)
|
|
745
|
+
|
|
746
|
+
|
|
747
|
+
def _extract_patches_2d(
|
|
748
|
+
images,
|
|
749
|
+
size,
|
|
750
|
+
strides=None,
|
|
751
|
+
dilation_rate=1,
|
|
752
|
+
padding="valid",
|
|
753
|
+
data_format=None,
|
|
676
754
|
):
|
|
677
755
|
if isinstance(size, int):
|
|
678
756
|
patch_h = patch_w = size
|
|
@@ -712,74 +790,6 @@ def _extract_patches(
|
|
|
712
790
|
return patches
|
|
713
791
|
|
|
714
792
|
|
|
715
|
-
class ExtractPatches3D(Operation):
|
|
716
|
-
def __init__(
|
|
717
|
-
self,
|
|
718
|
-
size,
|
|
719
|
-
strides=None,
|
|
720
|
-
dilation_rate=1,
|
|
721
|
-
padding="valid",
|
|
722
|
-
data_format=None,
|
|
723
|
-
*,
|
|
724
|
-
name=None,
|
|
725
|
-
):
|
|
726
|
-
super().__init__(name=name)
|
|
727
|
-
if isinstance(size, int):
|
|
728
|
-
size = (size, size, size)
|
|
729
|
-
elif len(size) != 3:
|
|
730
|
-
raise TypeError(
|
|
731
|
-
"Invalid `size` argument. Expected an "
|
|
732
|
-
f"int or a tuple of length 3. Received: size={size}"
|
|
733
|
-
)
|
|
734
|
-
self.size = size
|
|
735
|
-
if strides is not None:
|
|
736
|
-
if isinstance(strides, int):
|
|
737
|
-
strides = (strides, strides, strides)
|
|
738
|
-
elif len(strides) != 3:
|
|
739
|
-
raise ValueError(f"Invalid `strides` argument. Got: {strides}")
|
|
740
|
-
else:
|
|
741
|
-
strides = size
|
|
742
|
-
self.strides = strides
|
|
743
|
-
self.dilation_rate = dilation_rate
|
|
744
|
-
self.padding = padding
|
|
745
|
-
self.data_format = backend.standardize_data_format(data_format)
|
|
746
|
-
|
|
747
|
-
def call(self, volumes):
|
|
748
|
-
return _extract_patches_3d(
|
|
749
|
-
volumes,
|
|
750
|
-
self.size,
|
|
751
|
-
self.strides,
|
|
752
|
-
self.dilation_rate,
|
|
753
|
-
self.padding,
|
|
754
|
-
self.data_format,
|
|
755
|
-
)
|
|
756
|
-
|
|
757
|
-
def compute_output_spec(self, volumes):
|
|
758
|
-
volumes_shape = list(volumes.shape)
|
|
759
|
-
original_ndim = len(volumes_shape)
|
|
760
|
-
strides = self.strides
|
|
761
|
-
if self.data_format == "channels_last":
|
|
762
|
-
channels_in = volumes_shape[-1]
|
|
763
|
-
else:
|
|
764
|
-
channels_in = volumes_shape[-4]
|
|
765
|
-
if original_ndim == 4:
|
|
766
|
-
volumes_shape = [1] + volumes_shape
|
|
767
|
-
filters = self.size[0] * self.size[1] * self.size[2] * channels_in
|
|
768
|
-
kernel_size = (self.size[0], self.size[1], self.size[2])
|
|
769
|
-
out_shape = compute_conv_output_shape(
|
|
770
|
-
volumes_shape,
|
|
771
|
-
filters,
|
|
772
|
-
kernel_size,
|
|
773
|
-
strides=strides,
|
|
774
|
-
padding=self.padding,
|
|
775
|
-
data_format=self.data_format,
|
|
776
|
-
dilation_rate=self.dilation_rate,
|
|
777
|
-
)
|
|
778
|
-
if original_ndim == 4:
|
|
779
|
-
out_shape = out_shape[1:]
|
|
780
|
-
return KerasTensor(shape=out_shape, dtype=volumes.dtype)
|
|
781
|
-
|
|
782
|
-
|
|
783
793
|
def _extract_patches_3d(
|
|
784
794
|
volumes,
|
|
785
795
|
size,
|
|
@@ -879,8 +889,11 @@ def extract_patches_3d(
|
|
|
879
889
|
>>> patches.shape
|
|
880
890
|
(3, 3, 3, 81)
|
|
881
891
|
"""
|
|
892
|
+
# Convert int to 3-tuple for 3D
|
|
893
|
+
if isinstance(size, int):
|
|
894
|
+
size = (size, size, size)
|
|
882
895
|
if any_symbolic_tensors((volumes,)):
|
|
883
|
-
return
|
|
896
|
+
return ExtractPatches(
|
|
884
897
|
size=size,
|
|
885
898
|
strides=strides,
|
|
886
899
|
dilation_rate=dilation_rate,
|
keras/src/ops/numpy.py
CHANGED
|
@@ -5064,6 +5064,67 @@ def moveaxis(x, source, destination):
|
|
|
5064
5064
|
return backend.numpy.moveaxis(x, source=source, destination=destination)
|
|
5065
5065
|
|
|
5066
5066
|
|
|
5067
|
+
class Nansum(Operation):
|
|
5068
|
+
def __init__(self, axis=None, keepdims=False, *, name=None):
|
|
5069
|
+
super().__init__(name=name)
|
|
5070
|
+
self.axis = axis
|
|
5071
|
+
self.keepdims = keepdims
|
|
5072
|
+
|
|
5073
|
+
def call(self, x):
|
|
5074
|
+
return backend.numpy.nansum(x, axis=self.axis, keepdims=self.keepdims)
|
|
5075
|
+
|
|
5076
|
+
def compute_output_spec(self, x):
|
|
5077
|
+
dtype = dtypes.result_type(getattr(x, "dtype", backend.floatx()))
|
|
5078
|
+
|
|
5079
|
+
if dtype in ("bool", "int8", "int16"):
|
|
5080
|
+
dtype = "int32"
|
|
5081
|
+
elif dtype in ("uint8", "uint16"):
|
|
5082
|
+
dtype = "uint32"
|
|
5083
|
+
|
|
5084
|
+
if backend.backend() == "torch" and dtype == "uint32":
|
|
5085
|
+
dtype = "int32"
|
|
5086
|
+
sparse = getattr(x, "sparse", False)
|
|
5087
|
+
return KerasTensor(
|
|
5088
|
+
reduce_shape(x.shape, axis=self.axis, keepdims=self.keepdims),
|
|
5089
|
+
dtype=dtype,
|
|
5090
|
+
sparse=sparse,
|
|
5091
|
+
)
|
|
5092
|
+
|
|
5093
|
+
|
|
5094
|
+
@keras_export(["keras.ops.nansum", "keras.ops.numpy.nansum"])
|
|
5095
|
+
def nansum(x, axis=None, keepdims=False):
|
|
5096
|
+
"""Sum of a tensor over the given axes, ignoring NaNs.
|
|
5097
|
+
|
|
5098
|
+
Args:
|
|
5099
|
+
x: Input tensor.
|
|
5100
|
+
axis: Axis or axes along which the sum is computed. The default is to
|
|
5101
|
+
compute the sum of the flattened tensor.
|
|
5102
|
+
keepdims: If this is set to `True`, the axes which are reduced are left
|
|
5103
|
+
in the result as dimensions with size one.
|
|
5104
|
+
|
|
5105
|
+
Returns:
|
|
5106
|
+
Output tensor containing the sum, with NaN values ignored.
|
|
5107
|
+
|
|
5108
|
+
Examples:
|
|
5109
|
+
>>> import numpy as np
|
|
5110
|
+
>>> from keras import ops
|
|
5111
|
+
>>> x = np.array([[1.0, np.nan, 3.0],
|
|
5112
|
+
... [np.nan, 2.0, 1.0]])
|
|
5113
|
+
>>> ops.nansum(x)
|
|
5114
|
+
7.0
|
|
5115
|
+
|
|
5116
|
+
>>> ops.nansum(x, axis=1)
|
|
5117
|
+
array([4., 3.])
|
|
5118
|
+
|
|
5119
|
+
>>> ops.nansum(x, axis=1, keepdims=True)
|
|
5120
|
+
array([[4.],
|
|
5121
|
+
[3.]])
|
|
5122
|
+
"""
|
|
5123
|
+
if any_symbolic_tensors((x,)):
|
|
5124
|
+
return Nansum(axis=axis, keepdims=keepdims).symbolic_call(x)
|
|
5125
|
+
return backend.numpy.nansum(x, axis=axis, keepdims=keepdims)
|
|
5126
|
+
|
|
5127
|
+
|
|
5067
5128
|
class NanToNum(Operation):
|
|
5068
5129
|
def __init__(self, nan=0.0, posinf=None, neginf=None, *, name=None):
|
|
5069
5130
|
super().__init__(name=name)
|
|
@@ -5456,6 +5517,74 @@ def prod(x, axis=None, keepdims=False, dtype=None):
|
|
|
5456
5517
|
return backend.numpy.prod(x, axis=axis, keepdims=keepdims, dtype=dtype)
|
|
5457
5518
|
|
|
5458
5519
|
|
|
5520
|
+
class Ptp(Operation):
|
|
5521
|
+
def __init__(self, axis=None, keepdims=False, *, name=None):
|
|
5522
|
+
super().__init__(name=name)
|
|
5523
|
+
self.axis = axis
|
|
5524
|
+
self.keepdims = keepdims
|
|
5525
|
+
|
|
5526
|
+
def call(self, x):
|
|
5527
|
+
return backend.numpy.ptp(
|
|
5528
|
+
x,
|
|
5529
|
+
axis=self.axis,
|
|
5530
|
+
keepdims=self.keepdims,
|
|
5531
|
+
)
|
|
5532
|
+
|
|
5533
|
+
def compute_output_spec(self, x):
|
|
5534
|
+
dtype = backend.standardize_dtype(x.dtype)
|
|
5535
|
+
return KerasTensor(
|
|
5536
|
+
reduce_shape(x.shape, axis=self.axis, keepdims=self.keepdims),
|
|
5537
|
+
dtype=dtype,
|
|
5538
|
+
)
|
|
5539
|
+
|
|
5540
|
+
|
|
5541
|
+
@keras_export(["keras.ops.ptp", "keras.ops.numpy.ptp"])
|
|
5542
|
+
def ptp(x, axis=None, keepdims=False):
|
|
5543
|
+
"""Return the peak-to-peak (max - min) value of tensor elements
|
|
5544
|
+
over a given axis.
|
|
5545
|
+
|
|
5546
|
+
The peak-to-peak value is defined as the difference between the
|
|
5547
|
+
maximum and minimum values along the specified axis.
|
|
5548
|
+
|
|
5549
|
+
Args:
|
|
5550
|
+
x: Input tensor.
|
|
5551
|
+
axis: Axis or axes along which the peak-to-peak value is computed.
|
|
5552
|
+
The default, `axis=None`, will compute the peak-to-peak value
|
|
5553
|
+
over all elements in the input tensor.
|
|
5554
|
+
keepdims: If this is set to `True`, the axes which are reduced
|
|
5555
|
+
are left in the result as dimensions with size one.
|
|
5556
|
+
|
|
5557
|
+
Returns:
|
|
5558
|
+
A tensor containing the peak-to-peak values of `x` over the
|
|
5559
|
+
given axis or axes.
|
|
5560
|
+
|
|
5561
|
+
Examples:
|
|
5562
|
+
>>> x = keras.ops.array([[1., 3., 2.],
|
|
5563
|
+
... [4., 0., 5.]])
|
|
5564
|
+
|
|
5565
|
+
>>> # Peak-to-peak over all elements
|
|
5566
|
+
>>> keras.ops.ptp(x)
|
|
5567
|
+
5.0
|
|
5568
|
+
|
|
5569
|
+
>>> # Peak-to-peak along axis 1
|
|
5570
|
+
>>> keras.ops.ptp(x, axis=1)
|
|
5571
|
+
array([2., 5.], dtype=float32)
|
|
5572
|
+
|
|
5573
|
+
>>> # Peak-to-peak over multiple axes
|
|
5574
|
+
>>> x = keras.ops.reshape(x, (1, 2, 3))
|
|
5575
|
+
>>> keras.ops.ptp(x, axis=(1, 2))
|
|
5576
|
+
array([5.], dtype=float32)
|
|
5577
|
+
|
|
5578
|
+
>>> # Keep reduced dimensions
|
|
5579
|
+
>>> keras.ops.ptp(x, axis=2, keepdims=True)
|
|
5580
|
+
array([[[2.],
|
|
5581
|
+
[5.]]], dtype=float32)
|
|
5582
|
+
"""
|
|
5583
|
+
if any_symbolic_tensors((x,)):
|
|
5584
|
+
return Ptp(axis=axis, keepdims=keepdims).symbolic_call(x)
|
|
5585
|
+
return backend.numpy.ptp(x, axis=axis, keepdims=keepdims)
|
|
5586
|
+
|
|
5587
|
+
|
|
5459
5588
|
class Quantile(Operation):
|
|
5460
5589
|
def __init__(
|
|
5461
5590
|
self, axis=None, method="linear", keepdims=False, *, name=None
|
|
@@ -7734,6 +7863,15 @@ def correlate(x1, x2, mode="valid"):
|
|
|
7734
7863
|
|
|
7735
7864
|
Returns:
|
|
7736
7865
|
Output tensor, cross-correlation of `x1` and `x2`.
|
|
7866
|
+
|
|
7867
|
+
Notes:
|
|
7868
|
+
Complex-valued inputs are currently not fully supported on the
|
|
7869
|
+
TensorFlow and PyTorch backends. When complex tensors are passed,
|
|
7870
|
+
they are cast to floating-point types and the imaginary component
|
|
7871
|
+
is discarded.
|
|
7872
|
+
|
|
7873
|
+
This behavior is documented for clarity and may change in the
|
|
7874
|
+
future. See discussion in issue #21617.
|
|
7737
7875
|
"""
|
|
7738
7876
|
if any_symbolic_tensors((x1, x2)):
|
|
7739
7877
|
return Correlate(mode=mode).symbolic_call(x1, x2)
|
keras/src/quantizers/__init__.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import inspect
|
|
2
2
|
|
|
3
3
|
from keras.src.api_export import keras_export
|
|
4
|
+
from keras.src.quantizers.awq_config import AWQConfig
|
|
4
5
|
from keras.src.quantizers.quantization_config import Float8QuantizationConfig
|
|
5
6
|
from keras.src.quantizers.quantization_config import Int4QuantizationConfig
|
|
6
7
|
from keras.src.quantizers.quantization_config import Int8QuantizationConfig
|
|
@@ -24,6 +25,7 @@ ALL_OBJECTS = {
|
|
|
24
25
|
Int8QuantizationConfig,
|
|
25
26
|
Int4QuantizationConfig,
|
|
26
27
|
Float8QuantizationConfig,
|
|
28
|
+
AWQConfig,
|
|
27
29
|
}
|
|
28
30
|
ALL_OBJECTS_DICT = {cls.__name__: cls for cls in ALL_OBJECTS}
|
|
29
31
|
ALL_OBJECTS_DICT.update(
|