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.
- 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/dtype_policies/__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 +13 -0
- keras/callbacks/__init__.py +3 -0
- keras/distillation/__init__.py +16 -0
- keras/distribution/__init__.py +3 -0
- keras/dtype_policies/__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 +13 -0
- keras/src/applications/imagenet_utils.py +4 -1
- keras/src/backend/common/backend_utils.py +30 -6
- keras/src/backend/common/name_scope.py +2 -1
- keras/src/backend/common/variables.py +30 -15
- 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 +509 -29
- keras/src/backend/jax/numpy.py +59 -8
- keras/src/backend/jax/trainer.py +14 -2
- keras/src/backend/numpy/linalg.py +4 -0
- keras/src/backend/numpy/nn.py +311 -1
- keras/src/backend/numpy/numpy.py +65 -2
- 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 +943 -189
- 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 +250 -50
- 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 +80 -2
- keras/src/callbacks/__init__.py +1 -0
- keras/src/callbacks/model_checkpoint.py +5 -0
- keras/src/callbacks/orbax_checkpoint.py +332 -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/dtype_policies/__init__.py +2 -0
- keras/src/dtype_policies/dtype_policy.py +90 -1
- 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/multi_head_attention.py +4 -1
- keras/src/layers/core/dense.py +241 -111
- keras/src/layers/core/einsum_dense.py +316 -131
- keras/src/layers/core/embedding.py +84 -94
- keras/src/layers/core/input_layer.py +1 -0
- keras/src/layers/core/reversible_embedding.py +399 -0
- keras/src/layers/input_spec.py +17 -17
- keras/src/layers/layer.py +45 -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/feature_space.py +8 -4
- keras/src/layers/preprocessing/image_preprocessing/aug_mix.py +2 -2
- keras/src/layers/preprocessing/image_preprocessing/random_contrast.py +3 -3
- keras/src/layers/preprocessing/image_preprocessing/resizing.py +10 -0
- keras/src/layers/preprocessing/index_lookup.py +19 -1
- keras/src/layers/preprocessing/normalization.py +14 -1
- keras/src/layers/regularization/dropout.py +43 -1
- keras/src/layers/rnn/rnn.py +19 -0
- keras/src/losses/loss.py +1 -1
- keras/src/losses/losses.py +24 -0
- 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 +172 -34
- keras/src/ops/image.py +257 -20
- keras/src/ops/linalg.py +93 -0
- keras/src/ops/nn.py +258 -0
- keras/src/ops/numpy.py +569 -36
- keras/src/optimizers/muon.py +65 -31
- keras/src/optimizers/schedules/learning_rate_schedule.py +4 -3
- keras/src/quantizers/__init__.py +14 -1
- 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 +2 -8
- keras/src/quantizers/gptq_config.py +36 -1
- keras/src/quantizers/gptq_core.py +65 -79
- keras/src/quantizers/quantization_config.py +246 -0
- keras/src/quantizers/quantizers.py +127 -61
- keras/src/quantizers/utils.py +23 -0
- keras/src/random/seed_generator.py +6 -4
- keras/src/saving/file_editor.py +81 -6
- keras/src/saving/orbax_util.py +26 -0
- keras/src/saving/saving_api.py +37 -14
- 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/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 +244 -55
- keras/src/utils/module_utils.py +29 -0
- keras/src/utils/progbar.py +10 -2
- keras/src/utils/rng_utils.py +9 -1
- keras/src/utils/tracking.py +5 -5
- keras/src/version.py +1 -1
- {keras_nightly-3.12.0.dev2025100503.dist-info → keras_nightly-3.14.0.dev2026011604.dist-info}/METADATA +16 -6
- {keras_nightly-3.12.0.dev2025100503.dist-info → keras_nightly-3.14.0.dev2026011604.dist-info}/RECORD +136 -115
- {keras_nightly-3.12.0.dev2025100503.dist-info → keras_nightly-3.14.0.dev2026011604.dist-info}/WHEEL +0 -0
- {keras_nightly-3.12.0.dev2025100503.dist-info → keras_nightly-3.14.0.dev2026011604.dist-info}/top_level.txt +0 -0
keras/src/ops/numpy.py
CHANGED
|
@@ -301,33 +301,6 @@ def all(x, axis=None, keepdims=False):
|
|
|
301
301
|
return backend.numpy.all(x, axis=axis, keepdims=keepdims)
|
|
302
302
|
|
|
303
303
|
|
|
304
|
-
class Any(Operation):
|
|
305
|
-
def __init__(self, axis=None, keepdims=False, *, name=None):
|
|
306
|
-
super().__init__(name=name)
|
|
307
|
-
if isinstance(axis, int):
|
|
308
|
-
self.axis = [axis]
|
|
309
|
-
else:
|
|
310
|
-
self.axis = axis
|
|
311
|
-
self.keepdims = keepdims
|
|
312
|
-
|
|
313
|
-
def call(self, x):
|
|
314
|
-
return backend.numpy.any(
|
|
315
|
-
x,
|
|
316
|
-
axis=self.axis,
|
|
317
|
-
keepdims=self.keepdims,
|
|
318
|
-
)
|
|
319
|
-
|
|
320
|
-
def compute_output_spec(self, x):
|
|
321
|
-
return KerasTensor(
|
|
322
|
-
reduce_shape(
|
|
323
|
-
x.shape,
|
|
324
|
-
axis=self.axis,
|
|
325
|
-
keepdims=self.keepdims,
|
|
326
|
-
),
|
|
327
|
-
dtype="bool",
|
|
328
|
-
)
|
|
329
|
-
|
|
330
|
-
|
|
331
304
|
class Angle(Operation):
|
|
332
305
|
def call(self, x):
|
|
333
306
|
return backend.numpy.angle(x)
|
|
@@ -363,6 +336,33 @@ def angle(x):
|
|
|
363
336
|
return backend.numpy.angle(x)
|
|
364
337
|
|
|
365
338
|
|
|
339
|
+
class Any(Operation):
|
|
340
|
+
def __init__(self, axis=None, keepdims=False, *, name=None):
|
|
341
|
+
super().__init__(name=name)
|
|
342
|
+
if isinstance(axis, int):
|
|
343
|
+
self.axis = [axis]
|
|
344
|
+
else:
|
|
345
|
+
self.axis = axis
|
|
346
|
+
self.keepdims = keepdims
|
|
347
|
+
|
|
348
|
+
def call(self, x):
|
|
349
|
+
return backend.numpy.any(
|
|
350
|
+
x,
|
|
351
|
+
axis=self.axis,
|
|
352
|
+
keepdims=self.keepdims,
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
def compute_output_spec(self, x):
|
|
356
|
+
return KerasTensor(
|
|
357
|
+
reduce_shape(
|
|
358
|
+
x.shape,
|
|
359
|
+
axis=self.axis,
|
|
360
|
+
keepdims=self.keepdims,
|
|
361
|
+
),
|
|
362
|
+
dtype="bool",
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
|
|
366
366
|
@keras_export(["keras.ops.any", "keras.ops.numpy.any"])
|
|
367
367
|
def any(x, axis=None, keepdims=False):
|
|
368
368
|
"""Test whether any array element along a given axis evaluates to `True`.
|
|
@@ -924,6 +924,11 @@ def arctanh(x):
|
|
|
924
924
|
|
|
925
925
|
Returns:
|
|
926
926
|
Output tensor of same shape as `x`.
|
|
927
|
+
|
|
928
|
+
Example:
|
|
929
|
+
>>> x = keras.ops.convert_to_tensor([0, -0.5])
|
|
930
|
+
>>> keras.ops.arctanh(x)
|
|
931
|
+
array([ 0. , -0.54930615], dtype=float32)
|
|
927
932
|
"""
|
|
928
933
|
if any_symbolic_tensors((x,)):
|
|
929
934
|
return Arctanh().symbolic_call(x)
|
|
@@ -1124,6 +1129,68 @@ def array(x, dtype=None):
|
|
|
1124
1129
|
return backend.numpy.array(x, dtype=dtype)
|
|
1125
1130
|
|
|
1126
1131
|
|
|
1132
|
+
class View(Operation):
|
|
1133
|
+
def __init__(self, dtype=None, *, name=None):
|
|
1134
|
+
super().__init__(name=name)
|
|
1135
|
+
self.dtype = None if dtype is None else backend.standardize_dtype(dtype)
|
|
1136
|
+
|
|
1137
|
+
def call(self, x):
|
|
1138
|
+
return backend.numpy.view(x, dtype=self.dtype)
|
|
1139
|
+
|
|
1140
|
+
def compute_output_spec(self, x):
|
|
1141
|
+
old_dtype = backend.standardize_dtype(x.dtype)
|
|
1142
|
+
new_dtype = backend.standardize_dtype(
|
|
1143
|
+
self.dtype if self.dtype else x.dtype
|
|
1144
|
+
)
|
|
1145
|
+
|
|
1146
|
+
old_itemsize = np.dtype(old_dtype).itemsize
|
|
1147
|
+
new_itemsize = np.dtype(new_dtype).itemsize
|
|
1148
|
+
|
|
1149
|
+
if old_itemsize == new_itemsize:
|
|
1150
|
+
return KerasTensor(x.shape, dtype=new_dtype)
|
|
1151
|
+
|
|
1152
|
+
if not x.shape:
|
|
1153
|
+
raise ValueError(
|
|
1154
|
+
"Cannot view a scalar as a different dtype if item sizes "
|
|
1155
|
+
"are different."
|
|
1156
|
+
)
|
|
1157
|
+
|
|
1158
|
+
output_shape = list(x.shape)
|
|
1159
|
+
if output_shape[-1] is not None:
|
|
1160
|
+
if (output_shape[-1] * old_itemsize) % new_itemsize != 0:
|
|
1161
|
+
raise ValueError(
|
|
1162
|
+
f"Cannot view array of shape {x.shape} and dtype {x.dtype} "
|
|
1163
|
+
f"as dtype {new_dtype} because the total number of bytes "
|
|
1164
|
+
"is not divisible by the new itemsize."
|
|
1165
|
+
)
|
|
1166
|
+
output_shape[-1] = output_shape[-1] * old_itemsize // new_itemsize
|
|
1167
|
+
return KerasTensor(tuple(output_shape), dtype=new_dtype)
|
|
1168
|
+
|
|
1169
|
+
|
|
1170
|
+
@keras_export(["keras.ops.view", "keras.ops.numpy.view"])
|
|
1171
|
+
def view(x, dtype=None):
|
|
1172
|
+
"""Create a new bitwise view of the same data with the specified dtype.
|
|
1173
|
+
|
|
1174
|
+
Args:
|
|
1175
|
+
x: Input tensor.
|
|
1176
|
+
dtype: Data-type descriptor of the returned view,
|
|
1177
|
+
e.g., float32 or int16.
|
|
1178
|
+
|
|
1179
|
+
Returns:
|
|
1180
|
+
View of a tensor with data type dtype.
|
|
1181
|
+
|
|
1182
|
+
Examples:
|
|
1183
|
+
>>> x = keras.ops.array([1, 2, 3])
|
|
1184
|
+
>>> x
|
|
1185
|
+
array([1, 2, 3], dtype=int32)
|
|
1186
|
+
>>> keras.ops.view(x, dtype="float32")
|
|
1187
|
+
array([1.0e-45, 3.0e-45, 4.0e-45], dtype=float32)
|
|
1188
|
+
"""
|
|
1189
|
+
if any_symbolic_tensors((x,)):
|
|
1190
|
+
return View(dtype=dtype).symbolic_call(x)
|
|
1191
|
+
return backend.numpy.view(x, dtype=dtype)
|
|
1192
|
+
|
|
1193
|
+
|
|
1127
1194
|
class Average(Operation):
|
|
1128
1195
|
def __init__(self, axis=None, *, name=None):
|
|
1129
1196
|
super().__init__(name=name)
|
|
@@ -3052,6 +3119,48 @@ def empty(shape, dtype=None):
|
|
|
3052
3119
|
return backend.numpy.empty(shape, dtype=dtype)
|
|
3053
3120
|
|
|
3054
3121
|
|
|
3122
|
+
class EmptyLike(Operation):
|
|
3123
|
+
def __init__(self, dtype=None, *, name=None):
|
|
3124
|
+
super().__init__(name=name)
|
|
3125
|
+
self.dtype = None if dtype is None else backend.standardize_dtype(dtype)
|
|
3126
|
+
|
|
3127
|
+
def call(self, x):
|
|
3128
|
+
return backend.numpy.empty_like(x, dtype=self.dtype)
|
|
3129
|
+
|
|
3130
|
+
def compute_output_spec(self, x):
|
|
3131
|
+
dtype = (
|
|
3132
|
+
backend.standardize_dtype(x.dtype)
|
|
3133
|
+
if self.dtype is None
|
|
3134
|
+
else self.dtype
|
|
3135
|
+
)
|
|
3136
|
+
return KerasTensor(x.shape, dtype=dtype)
|
|
3137
|
+
|
|
3138
|
+
|
|
3139
|
+
@keras_export(["keras.ops.empty_like", "keras.ops.numpy.empty_like"])
|
|
3140
|
+
def empty_like(x, dtype=None):
|
|
3141
|
+
"""Return a new uninitialized tensor with the same shape and dtype as `x`.
|
|
3142
|
+
|
|
3143
|
+
Args:
|
|
3144
|
+
x: Input tensor to mimic shape and dtype.
|
|
3145
|
+
dtype: Optional data type. If None, uses `x.dtype`.
|
|
3146
|
+
|
|
3147
|
+
Returns:
|
|
3148
|
+
A tensor with the same shape and dtype as `x`, with arbitrary contents.
|
|
3149
|
+
|
|
3150
|
+
Example:
|
|
3151
|
+
>>> from keras import ops
|
|
3152
|
+
>>> x = ops.ones((2, 3), dtype="float32")
|
|
3153
|
+
>>> y = ops.empty_like(x)
|
|
3154
|
+
>>> y.shape
|
|
3155
|
+
(2, 3)
|
|
3156
|
+
>>> y.dtype
|
|
3157
|
+
dtype('float32')
|
|
3158
|
+
"""
|
|
3159
|
+
if any_symbolic_tensors((x,)):
|
|
3160
|
+
return EmptyLike(dtype=dtype).symbolic_call(x)
|
|
3161
|
+
return backend.numpy.empty_like(x, dtype=dtype)
|
|
3162
|
+
|
|
3163
|
+
|
|
3055
3164
|
class Equal(Operation):
|
|
3056
3165
|
def call(self, x1, x2):
|
|
3057
3166
|
return backend.numpy.equal(x1, x2)
|
|
@@ -3846,6 +3955,35 @@ def isposinf(x):
|
|
|
3846
3955
|
return backend.numpy.isposinf(x)
|
|
3847
3956
|
|
|
3848
3957
|
|
|
3958
|
+
class Isreal(Operation):
|
|
3959
|
+
def call(self, x):
|
|
3960
|
+
return backend.numpy.isreal(x)
|
|
3961
|
+
|
|
3962
|
+
def compute_output_spec(self, x):
|
|
3963
|
+
return KerasTensor(x.shape, dtype="bool")
|
|
3964
|
+
|
|
3965
|
+
|
|
3966
|
+
@keras_export(["keras.ops.isreal", "keras.ops.numpy.isreal"])
|
|
3967
|
+
def isreal(x):
|
|
3968
|
+
"""Test element-wise for real numbers.
|
|
3969
|
+
|
|
3970
|
+
Args:
|
|
3971
|
+
x: Input tensor.
|
|
3972
|
+
|
|
3973
|
+
Returns:
|
|
3974
|
+
Output boolean tensor.
|
|
3975
|
+
|
|
3976
|
+
Example:
|
|
3977
|
+
>>> from keras import ops
|
|
3978
|
+
>>> x = ops.array([1+1j, 1+0j, 4.5, 3, 2, 2j], dtype="complex64")
|
|
3979
|
+
>>> ops.isreal(x)
|
|
3980
|
+
array([False, True, True, True, True, False])
|
|
3981
|
+
"""
|
|
3982
|
+
if any_symbolic_tensors((x,)):
|
|
3983
|
+
return Isreal().symbolic_call(x)
|
|
3984
|
+
return backend.numpy.isreal(x)
|
|
3985
|
+
|
|
3986
|
+
|
|
3849
3987
|
class Kron(Operation):
|
|
3850
3988
|
def call(self, x1, x2):
|
|
3851
3989
|
return backend.numpy.kron(x1, x2)
|
|
@@ -3926,6 +4064,46 @@ def lcm(x1, x2):
|
|
|
3926
4064
|
return backend.numpy.lcm(x1, x2)
|
|
3927
4065
|
|
|
3928
4066
|
|
|
4067
|
+
class Ldexp(Operation):
|
|
4068
|
+
def call(self, x1, x2):
|
|
4069
|
+
return backend.numpy.ldexp(x1, x2)
|
|
4070
|
+
|
|
4071
|
+
def compute_output_spec(self, x1, x2):
|
|
4072
|
+
x1_shape = getattr(x1, "shape", [])
|
|
4073
|
+
x2_shape = getattr(x2, "shape", [])
|
|
4074
|
+
output_shape = broadcast_shapes(x1_shape, x2_shape)
|
|
4075
|
+
|
|
4076
|
+
x1_type = backend.standardize_dtype(getattr(x1, "dtype", type(x1)))
|
|
4077
|
+
x2_type = backend.standardize_dtype(getattr(x2, "dtype", type(x2)))
|
|
4078
|
+
dtype = dtypes.result_type(x1_type, x2_type, float)
|
|
4079
|
+
return KerasTensor(output_shape, dtype=dtype)
|
|
4080
|
+
|
|
4081
|
+
|
|
4082
|
+
@keras_export(["keras.ops.ldexp", "keras.ops.numpy.ldexp"])
|
|
4083
|
+
def ldexp(x1, x2):
|
|
4084
|
+
"""Multiply `x1` by 2 raised to the power of `x2`, element-wise.
|
|
4085
|
+
|
|
4086
|
+
This function computes:
|
|
4087
|
+
ldexp(x1, x2) = x1 * 2**x2
|
|
4088
|
+
|
|
4089
|
+
Args:
|
|
4090
|
+
x1: Float input tensor.
|
|
4091
|
+
x2: Integer exponent tensor.
|
|
4092
|
+
|
|
4093
|
+
Returns:
|
|
4094
|
+
Output tensor
|
|
4095
|
+
|
|
4096
|
+
Example:
|
|
4097
|
+
>>> x1 = keras.ops.convert_to_tensor([0.75, 1.5])
|
|
4098
|
+
>>> x2 = keras.ops.convert_to_tensor([1, 2])
|
|
4099
|
+
>>> keras.ops.ldexp(x1, x2)
|
|
4100
|
+
array([1.5, 6. ], dtype=float32)
|
|
4101
|
+
"""
|
|
4102
|
+
if any_symbolic_tensors((x1, x2)):
|
|
4103
|
+
return Ldexp().symbolic_call(x1, x2)
|
|
4104
|
+
return backend.numpy.ldexp(x1, x2)
|
|
4105
|
+
|
|
4106
|
+
|
|
3929
4107
|
class Less(Operation):
|
|
3930
4108
|
def call(self, x1, x2):
|
|
3931
4109
|
return backend.numpy.less(x1, x2)
|
|
@@ -5278,6 +5456,74 @@ def prod(x, axis=None, keepdims=False, dtype=None):
|
|
|
5278
5456
|
return backend.numpy.prod(x, axis=axis, keepdims=keepdims, dtype=dtype)
|
|
5279
5457
|
|
|
5280
5458
|
|
|
5459
|
+
class Ptp(Operation):
|
|
5460
|
+
def __init__(self, axis=None, keepdims=False, *, name=None):
|
|
5461
|
+
super().__init__(name=name)
|
|
5462
|
+
self.axis = axis
|
|
5463
|
+
self.keepdims = keepdims
|
|
5464
|
+
|
|
5465
|
+
def call(self, x):
|
|
5466
|
+
return backend.numpy.ptp(
|
|
5467
|
+
x,
|
|
5468
|
+
axis=self.axis,
|
|
5469
|
+
keepdims=self.keepdims,
|
|
5470
|
+
)
|
|
5471
|
+
|
|
5472
|
+
def compute_output_spec(self, x):
|
|
5473
|
+
dtype = backend.standardize_dtype(x.dtype)
|
|
5474
|
+
return KerasTensor(
|
|
5475
|
+
reduce_shape(x.shape, axis=self.axis, keepdims=self.keepdims),
|
|
5476
|
+
dtype=dtype,
|
|
5477
|
+
)
|
|
5478
|
+
|
|
5479
|
+
|
|
5480
|
+
@keras_export(["keras.ops.ptp", "keras.ops.numpy.ptp"])
|
|
5481
|
+
def ptp(x, axis=None, keepdims=False):
|
|
5482
|
+
"""Return the peak-to-peak (max - min) value of tensor elements
|
|
5483
|
+
over a given axis.
|
|
5484
|
+
|
|
5485
|
+
The peak-to-peak value is defined as the difference between the
|
|
5486
|
+
maximum and minimum values along the specified axis.
|
|
5487
|
+
|
|
5488
|
+
Args:
|
|
5489
|
+
x: Input tensor.
|
|
5490
|
+
axis: Axis or axes along which the peak-to-peak value is computed.
|
|
5491
|
+
The default, `axis=None`, will compute the peak-to-peak value
|
|
5492
|
+
over all elements in the input tensor.
|
|
5493
|
+
keepdims: If this is set to `True`, the axes which are reduced
|
|
5494
|
+
are left in the result as dimensions with size one.
|
|
5495
|
+
|
|
5496
|
+
Returns:
|
|
5497
|
+
A tensor containing the peak-to-peak values of `x` over the
|
|
5498
|
+
given axis or axes.
|
|
5499
|
+
|
|
5500
|
+
Examples:
|
|
5501
|
+
>>> x = keras.ops.array([[1., 3., 2.],
|
|
5502
|
+
... [4., 0., 5.]])
|
|
5503
|
+
|
|
5504
|
+
>>> # Peak-to-peak over all elements
|
|
5505
|
+
>>> keras.ops.ptp(x)
|
|
5506
|
+
5.0
|
|
5507
|
+
|
|
5508
|
+
>>> # Peak-to-peak along axis 1
|
|
5509
|
+
>>> keras.ops.ptp(x, axis=1)
|
|
5510
|
+
array([2., 5.], dtype=float32)
|
|
5511
|
+
|
|
5512
|
+
>>> # Peak-to-peak over multiple axes
|
|
5513
|
+
>>> x = keras.ops.reshape(x, (1, 2, 3))
|
|
5514
|
+
>>> keras.ops.ptp(x, axis=(1, 2))
|
|
5515
|
+
array([5.], dtype=float32)
|
|
5516
|
+
|
|
5517
|
+
>>> # Keep reduced dimensions
|
|
5518
|
+
>>> keras.ops.ptp(x, axis=2, keepdims=True)
|
|
5519
|
+
array([[[2.],
|
|
5520
|
+
[5.]]], dtype=float32)
|
|
5521
|
+
"""
|
|
5522
|
+
if any_symbolic_tensors((x,)):
|
|
5523
|
+
return Ptp(axis=axis, keepdims=keepdims).symbolic_call(x)
|
|
5524
|
+
return backend.numpy.ptp(x, axis=axis, keepdims=keepdims)
|
|
5525
|
+
|
|
5526
|
+
|
|
5281
5527
|
class Quantile(Operation):
|
|
5282
5528
|
def __init__(
|
|
5283
5529
|
self, axis=None, method="linear", keepdims=False, *, name=None
|
|
@@ -5418,10 +5664,10 @@ def unravel_index(indices, shape):
|
|
|
5418
5664
|
Tuple of arrays for each dimension with unraveled indices.
|
|
5419
5665
|
|
|
5420
5666
|
Example:
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5667
|
+
>>> indices = 5
|
|
5668
|
+
>>> shape = (3, 3)
|
|
5669
|
+
>>> unravel_index(indices, shape)
|
|
5670
|
+
(1, 2) # 5 is at row 1, column 2 in a 3x3 array
|
|
5425
5671
|
"""
|
|
5426
5672
|
if any_symbolic_tensors((indices,)):
|
|
5427
5673
|
return UnravelIndex(shape).symbolic_call(indices)
|
|
@@ -6278,6 +6524,9 @@ class Tile(Operation):
|
|
|
6278
6524
|
repeats = self.repeats
|
|
6279
6525
|
if isinstance(repeats, int):
|
|
6280
6526
|
repeats = [repeats]
|
|
6527
|
+
else:
|
|
6528
|
+
repeats = list(repeats)
|
|
6529
|
+
|
|
6281
6530
|
if len(x_shape) > len(repeats):
|
|
6282
6531
|
repeats = [1] * (len(x_shape) - len(repeats)) + repeats
|
|
6283
6532
|
else:
|
|
@@ -6285,10 +6534,10 @@ class Tile(Operation):
|
|
|
6285
6534
|
|
|
6286
6535
|
output_shape = []
|
|
6287
6536
|
for x_size, repeat in zip(x_shape, repeats):
|
|
6288
|
-
if x_size
|
|
6289
|
-
output_shape.append(None)
|
|
6290
|
-
else:
|
|
6537
|
+
if isinstance(x_size, int):
|
|
6291
6538
|
output_shape.append(x_size * repeat)
|
|
6539
|
+
else:
|
|
6540
|
+
output_shape.append(None)
|
|
6292
6541
|
return KerasTensor(output_shape, dtype=x.dtype)
|
|
6293
6542
|
|
|
6294
6543
|
|
|
@@ -6336,8 +6585,13 @@ class Trace(Operation):
|
|
|
6336
6585
|
x_shape[self.axis2] = -1
|
|
6337
6586
|
output_shape = list(filter((-1).__ne__, x_shape))
|
|
6338
6587
|
output_dtype = backend.standardize_dtype(x.dtype)
|
|
6339
|
-
if output_dtype
|
|
6340
|
-
output_dtype =
|
|
6588
|
+
if output_dtype in ("bool", "int8", "int16"):
|
|
6589
|
+
output_dtype = "int32"
|
|
6590
|
+
elif output_dtype in ("uint8", "uint16"):
|
|
6591
|
+
output_dtype = "uint32"
|
|
6592
|
+
if output_dtype == "uint32" and backend.backend() == "torch":
|
|
6593
|
+
# Torch backend doesn't support uint32 dtype.
|
|
6594
|
+
output_dtype = "int32"
|
|
6341
6595
|
return KerasTensor(output_shape, dtype=output_dtype)
|
|
6342
6596
|
|
|
6343
6597
|
|
|
@@ -6918,6 +7172,49 @@ def negative(x):
|
|
|
6918
7172
|
return backend.numpy.negative(x)
|
|
6919
7173
|
|
|
6920
7174
|
|
|
7175
|
+
class Nextafter(Operation):
|
|
7176
|
+
def call(self, x1, x2):
|
|
7177
|
+
return backend.numpy.nextafter(x1, x2)
|
|
7178
|
+
|
|
7179
|
+
def compute_output_spec(self, x1, x2):
|
|
7180
|
+
x1_shape = getattr(x1, "shape", [])
|
|
7181
|
+
x2_shape = getattr(x2, "shape", [])
|
|
7182
|
+
output_shape = broadcast_shapes(x1_shape, x2_shape)
|
|
7183
|
+
|
|
7184
|
+
x1_type = backend.standardize_dtype(getattr(x1, "dtype", type(x1)))
|
|
7185
|
+
x2_type = backend.standardize_dtype(getattr(x2, "dtype", type(x2)))
|
|
7186
|
+
dtype = dtypes.result_type(x1_type, x2_type, float)
|
|
7187
|
+
return KerasTensor(output_shape, dtype=dtype)
|
|
7188
|
+
|
|
7189
|
+
|
|
7190
|
+
@keras_export(["keras.ops.nextafter", "keras.ops.numpy.nextafter"])
|
|
7191
|
+
def nextafter(x1, x2):
|
|
7192
|
+
"""
|
|
7193
|
+
Return the next representable floating-point value after `x1` towards `x2`.
|
|
7194
|
+
|
|
7195
|
+
This function computes the next floating-point value
|
|
7196
|
+
following `x1` in the direction of `x2`, element-wise.
|
|
7197
|
+
|
|
7198
|
+
Args:
|
|
7199
|
+
x1: Input tensor whose values will be moved to the next
|
|
7200
|
+
representable floating-point value.
|
|
7201
|
+
x2: Input tensor indicating the direction toward which
|
|
7202
|
+
`x1` is moved.
|
|
7203
|
+
|
|
7204
|
+
Returns:
|
|
7205
|
+
Output tensor
|
|
7206
|
+
|
|
7207
|
+
Example:
|
|
7208
|
+
>>> x1 = keras.ops.convert_to_tensor([1.0, 1.0])
|
|
7209
|
+
>>> x2 = keras.ops.convert_to_tensor([2.0, 0.0])
|
|
7210
|
+
>>> keras.ops.nextafter(x1, x2)
|
|
7211
|
+
array([1.0000001, 0.99999994], dtype=float32)
|
|
7212
|
+
"""
|
|
7213
|
+
if any_symbolic_tensors((x1, x2)):
|
|
7214
|
+
return Nextafter().symbolic_call(x1, x2)
|
|
7215
|
+
return backend.numpy.nextafter(x1, x2)
|
|
7216
|
+
|
|
7217
|
+
|
|
6921
7218
|
class Square(Operation):
|
|
6922
7219
|
def call(self, x):
|
|
6923
7220
|
return backend.numpy.square(x)
|
|
@@ -7054,6 +7351,48 @@ def transpose(x, axes=None):
|
|
|
7054
7351
|
return backend.numpy.transpose(x, axes=axes)
|
|
7055
7352
|
|
|
7056
7353
|
|
|
7354
|
+
class Trapezoid(Operation):
|
|
7355
|
+
def __init__(self, x=None, dx=1.0, axis=-1, *, name=None):
|
|
7356
|
+
super().__init__(name=name)
|
|
7357
|
+
self.x = x
|
|
7358
|
+
self.dx = dx
|
|
7359
|
+
self.axis = axis
|
|
7360
|
+
|
|
7361
|
+
def call(self, y):
|
|
7362
|
+
return backend.numpy.trapezoid(y, x=self.x, dx=self.dx, axis=self.axis)
|
|
7363
|
+
|
|
7364
|
+
def compute_output_spec(self, y):
|
|
7365
|
+
out_shape = list(y.shape)
|
|
7366
|
+
if self.axis is not None and len(out_shape) > 0:
|
|
7367
|
+
out_shape.pop(self.axis % len(out_shape))
|
|
7368
|
+
dtype = backend.result_type(getattr(y, "dtype", type(y)), float)
|
|
7369
|
+
return KerasTensor(tuple(out_shape), dtype=dtype)
|
|
7370
|
+
|
|
7371
|
+
|
|
7372
|
+
@keras_export(["keras.ops.trapezoid", "keras.ops.numpy.trapezoid"])
|
|
7373
|
+
def trapezoid(y, x=None, dx=1.0, axis=-1):
|
|
7374
|
+
"""Integrate along the given axis using the composite trapezoidal rule.
|
|
7375
|
+
|
|
7376
|
+
Args:
|
|
7377
|
+
y: Input tensor.
|
|
7378
|
+
x: Optional tensor specifying sample points corresponding to `y`.
|
|
7379
|
+
If `None`, spacing is assumed to be `dx`.
|
|
7380
|
+
dx: Spacing between sample points when `x` is `None`.
|
|
7381
|
+
axis: Axis along which to integrate. Default is the last axis.
|
|
7382
|
+
|
|
7383
|
+
Returns:
|
|
7384
|
+
The approximate integral of `y` along the given axis.
|
|
7385
|
+
|
|
7386
|
+
Example:
|
|
7387
|
+
>>> y = keras.ops.convert_to_tensor([[1, 2, 3], [4, 5, 6]])
|
|
7388
|
+
>>> keras.ops.trapezoid(y, axis=1)
|
|
7389
|
+
array([ 4., 10.], dtype=float32)
|
|
7390
|
+
"""
|
|
7391
|
+
if any_symbolic_tensors((y,)):
|
|
7392
|
+
return Trapezoid(x=x, dx=dx, axis=axis).symbolic_call(y)
|
|
7393
|
+
return backend.numpy.trapezoid(y, x=x, dx=dx, axis=axis)
|
|
7394
|
+
|
|
7395
|
+
|
|
7057
7396
|
class Mean(Operation):
|
|
7058
7397
|
def __init__(self, axis=None, keepdims=False, *, name=None):
|
|
7059
7398
|
super().__init__(name=name)
|
|
@@ -7099,6 +7438,77 @@ def mean(x, axis=None, keepdims=False):
|
|
|
7099
7438
|
return backend.numpy.mean(x, axis=axis, keepdims=keepdims)
|
|
7100
7439
|
|
|
7101
7440
|
|
|
7441
|
+
class Vander(Operation):
|
|
7442
|
+
def __init__(self, N=None, increasing=False, *, name=None):
|
|
7443
|
+
super().__init__(name=name)
|
|
7444
|
+
self.N = N
|
|
7445
|
+
self.increasing = increasing
|
|
7446
|
+
|
|
7447
|
+
def call(self, x):
|
|
7448
|
+
return backend.numpy.vander(x, self.N, self.increasing)
|
|
7449
|
+
|
|
7450
|
+
def compute_output_spec(self, x):
|
|
7451
|
+
if self.N is None:
|
|
7452
|
+
N = x.shape[0]
|
|
7453
|
+
else:
|
|
7454
|
+
N = self.N
|
|
7455
|
+
|
|
7456
|
+
out_shape = x.shape + (N,)
|
|
7457
|
+
return KerasTensor(tuple(out_shape), dtype=x.dtype)
|
|
7458
|
+
|
|
7459
|
+
|
|
7460
|
+
@keras_export(["keras.ops.vander", "keras.ops.numpy.vander"])
|
|
7461
|
+
def vander(x, N=None, increasing=False):
|
|
7462
|
+
"""Generate a Vandermonde matrix.
|
|
7463
|
+
|
|
7464
|
+
Args:
|
|
7465
|
+
x: 1D input tensor.
|
|
7466
|
+
N: Number of columns. If `None`, `N` = `len(x)`.
|
|
7467
|
+
increasing: Order of powers. If True, powers increase left to right.
|
|
7468
|
+
|
|
7469
|
+
Returns:
|
|
7470
|
+
Output tensor, Vandermonde matrix of shape `(len(x), N)`.
|
|
7471
|
+
|
|
7472
|
+
Example:
|
|
7473
|
+
>>> import numpy as np
|
|
7474
|
+
>>> import keras
|
|
7475
|
+
>>> x = np.array([1, 2, 3, 5])
|
|
7476
|
+
>>> keras.ops.vander(x)
|
|
7477
|
+
array([[ 1, 1, 1, 1],
|
|
7478
|
+
[ 8, 4, 2, 1],
|
|
7479
|
+
[ 27, 9, 3, 1],
|
|
7480
|
+
[125, 25, 5, 1]])
|
|
7481
|
+
"""
|
|
7482
|
+
|
|
7483
|
+
if len(x.shape) != 1:
|
|
7484
|
+
raise ValueError(
|
|
7485
|
+
"Input tensor must be 1-dimensional. "
|
|
7486
|
+
f"Received: input.shape={x.shape}"
|
|
7487
|
+
)
|
|
7488
|
+
|
|
7489
|
+
if N is not None:
|
|
7490
|
+
if not isinstance(N, int):
|
|
7491
|
+
raise TypeError(
|
|
7492
|
+
f"Argument `N` must be of type `int`. "
|
|
7493
|
+
f"Received: N={N} of type {type(N)}"
|
|
7494
|
+
)
|
|
7495
|
+
|
|
7496
|
+
if N < 0:
|
|
7497
|
+
raise ValueError(
|
|
7498
|
+
f"Argument 'N' must be nonnegative. Received: N={N}"
|
|
7499
|
+
)
|
|
7500
|
+
|
|
7501
|
+
if not isinstance(increasing, bool):
|
|
7502
|
+
raise TypeError(
|
|
7503
|
+
f"Argument `increasing` must be of type `bool`. "
|
|
7504
|
+
f"Received: increasing={increasing} of type {type(increasing)}"
|
|
7505
|
+
)
|
|
7506
|
+
|
|
7507
|
+
if any_symbolic_tensors((x,)):
|
|
7508
|
+
return Vander(N=N, increasing=increasing).symbolic_call(x)
|
|
7509
|
+
return backend.numpy.vander(x, N=N, increasing=increasing)
|
|
7510
|
+
|
|
7511
|
+
|
|
7102
7512
|
class Var(Operation):
|
|
7103
7513
|
def __init__(self, axis=None, keepdims=False, *, name=None):
|
|
7104
7514
|
super().__init__(name=name)
|
|
@@ -7228,6 +7638,19 @@ def eye(N, M=None, k=0, dtype=None):
|
|
|
7228
7638
|
Returns:
|
|
7229
7639
|
Tensor with ones on the k-th diagonal and zeros elsewhere.
|
|
7230
7640
|
"""
|
|
7641
|
+
|
|
7642
|
+
def is_floating_type(v):
|
|
7643
|
+
return (
|
|
7644
|
+
isinstance(v, float)
|
|
7645
|
+
or getattr(v, "dtype", None) in dtypes.FLOAT_TYPES
|
|
7646
|
+
)
|
|
7647
|
+
|
|
7648
|
+
if is_floating_type(N):
|
|
7649
|
+
raise TypeError("Argument `N` must be an integer or an integer tensor.")
|
|
7650
|
+
if is_floating_type(M):
|
|
7651
|
+
raise TypeError(
|
|
7652
|
+
"Argument `M` must be an integer, an integer tensor, or `None`."
|
|
7653
|
+
)
|
|
7231
7654
|
return backend.numpy.eye(N, M=M, k=k, dtype=dtype)
|
|
7232
7655
|
|
|
7233
7656
|
|
|
@@ -7379,6 +7802,15 @@ def correlate(x1, x2, mode="valid"):
|
|
|
7379
7802
|
|
|
7380
7803
|
Returns:
|
|
7381
7804
|
Output tensor, cross-correlation of `x1` and `x2`.
|
|
7805
|
+
|
|
7806
|
+
Notes:
|
|
7807
|
+
Complex-valued inputs are currently not fully supported on the
|
|
7808
|
+
TensorFlow and PyTorch backends. When complex tensors are passed,
|
|
7809
|
+
they are cast to floating-point types and the imaginary component
|
|
7810
|
+
is discarded.
|
|
7811
|
+
|
|
7812
|
+
This behavior is documented for clarity and may change in the
|
|
7813
|
+
future. See discussion in issue #21617.
|
|
7382
7814
|
"""
|
|
7383
7815
|
if any_symbolic_tensors((x1, x2)):
|
|
7384
7816
|
return Correlate(mode=mode).symbolic_call(x1, x2)
|
|
@@ -7611,3 +8043,104 @@ def histogram(x, bins=10, range=None):
|
|
|
7611
8043
|
f"Received: input.shape={x.shape}"
|
|
7612
8044
|
)
|
|
7613
8045
|
return backend.numpy.histogram(x, bins=bins, range=range)
|
|
8046
|
+
|
|
8047
|
+
|
|
8048
|
+
class ArraySplit(Operation):
|
|
8049
|
+
def __init__(self, indices_or_sections, axis=0, *, name=None):
|
|
8050
|
+
super().__init__(name=name)
|
|
8051
|
+
|
|
8052
|
+
self.indices_or_sections = indices_or_sections
|
|
8053
|
+
self.axis = axis
|
|
8054
|
+
|
|
8055
|
+
def call(self, x):
|
|
8056
|
+
return backend.numpy.array_split(
|
|
8057
|
+
x,
|
|
8058
|
+
indices_or_sections=self.indices_or_sections,
|
|
8059
|
+
axis=self.axis,
|
|
8060
|
+
)
|
|
8061
|
+
|
|
8062
|
+
def compute_output_spec(self, x):
|
|
8063
|
+
num_splits = self.indices_or_sections
|
|
8064
|
+
|
|
8065
|
+
axis = self.axis
|
|
8066
|
+
if axis < 0:
|
|
8067
|
+
axis += len(x.shape)
|
|
8068
|
+
|
|
8069
|
+
total_size = x.shape[axis]
|
|
8070
|
+
|
|
8071
|
+
if total_size is None:
|
|
8072
|
+
output_specs = []
|
|
8073
|
+
base_shape = list(x.shape)
|
|
8074
|
+
base_shape[axis] = None
|
|
8075
|
+
for _ in range(num_splits):
|
|
8076
|
+
output_specs.append(
|
|
8077
|
+
KerasTensor(shape=tuple(base_shape), dtype=x.dtype)
|
|
8078
|
+
)
|
|
8079
|
+
return tuple(output_specs)
|
|
8080
|
+
|
|
8081
|
+
split_size = total_size // num_splits
|
|
8082
|
+
remainder = total_size % num_splits
|
|
8083
|
+
|
|
8084
|
+
output_specs = []
|
|
8085
|
+
base_shape = list(x.shape)
|
|
8086
|
+
for i in range(num_splits):
|
|
8087
|
+
size = split_size + (1 if i < remainder else 0)
|
|
8088
|
+
shape = base_shape.copy()
|
|
8089
|
+
shape[axis] = size
|
|
8090
|
+
output_specs.append(KerasTensor(shape=tuple(shape), dtype=x.dtype))
|
|
8091
|
+
|
|
8092
|
+
return list(output_specs)
|
|
8093
|
+
|
|
8094
|
+
|
|
8095
|
+
@keras_export(["keras.ops.array_split", "keras.ops.numpy.array_split"])
|
|
8096
|
+
def array_split(x, indices_or_sections, axis=0):
|
|
8097
|
+
"""Splits an array into multiple sub-arrays (unevenly).
|
|
8098
|
+
|
|
8099
|
+
This is similar to `keras.ops.split`, but it allows for
|
|
8100
|
+
unequal splits. `indices_or_sections` must be an integer
|
|
8101
|
+
that indicates the total number of sub-arrays to create.
|
|
8102
|
+
If the tensor cannot be divided evenly, the first `remainder`
|
|
8103
|
+
splits will have size `quotient + 1`, and the rest will
|
|
8104
|
+
have size `quotient`.
|
|
8105
|
+
|
|
8106
|
+
Args:
|
|
8107
|
+
x: Input tensor.
|
|
8108
|
+
indices_or_sections: An integer indicating the number of
|
|
8109
|
+
sub-arrays to create.
|
|
8110
|
+
axis: The axis along which to split. Defaults to 0.
|
|
8111
|
+
|
|
8112
|
+
Returns:
|
|
8113
|
+
A list of sub-tensors.
|
|
8114
|
+
|
|
8115
|
+
Example:
|
|
8116
|
+
>>> x = keras.ops.arange(10)
|
|
8117
|
+
>>> keras.ops.array_split(x, 3)
|
|
8118
|
+
(array([0, 1, 2, 3], dtype=int32),
|
|
8119
|
+
array([4, 5, 6], dtype=int32),
|
|
8120
|
+
array([7, 8, 9], dtype=int32))
|
|
8121
|
+
"""
|
|
8122
|
+
if not isinstance(indices_or_sections, int):
|
|
8123
|
+
raise TypeError(
|
|
8124
|
+
"Argument `indices_or_sections` must be of type `int`. "
|
|
8125
|
+
f"Received: indices_or_sections={indices_or_sections}"
|
|
8126
|
+
)
|
|
8127
|
+
|
|
8128
|
+
if indices_or_sections <= 0:
|
|
8129
|
+
raise ValueError(
|
|
8130
|
+
"Argument `indices_or_sections` must be a positive integer. "
|
|
8131
|
+
f"Received: indices_or_sections={indices_or_sections}"
|
|
8132
|
+
)
|
|
8133
|
+
|
|
8134
|
+
if not isinstance(axis, int):
|
|
8135
|
+
raise TypeError(
|
|
8136
|
+
f"Argument `axis` must be of type `int`. Received: {axis}"
|
|
8137
|
+
)
|
|
8138
|
+
|
|
8139
|
+
if any_symbolic_tensors((x,)):
|
|
8140
|
+
return ArraySplit(
|
|
8141
|
+
indices_or_sections=indices_or_sections, axis=axis
|
|
8142
|
+
).symbolic_call(x)
|
|
8143
|
+
|
|
8144
|
+
return backend.numpy.array_split(
|
|
8145
|
+
x, indices_or_sections=indices_or_sections, axis=axis
|
|
8146
|
+
)
|