keras-nightly 3.14.0.dev2026012604__py3-none-any.whl → 3.14.0.dev2026012704__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/src/backend/openvino/numpy.py +52 -6
- keras/src/backend/torch/export.py +19 -3
- keras/src/layers/normalization/batch_normalization.py +248 -14
- keras/src/version.py +1 -1
- {keras_nightly-3.14.0.dev2026012604.dist-info → keras_nightly-3.14.0.dev2026012704.dist-info}/METADATA +1 -1
- {keras_nightly-3.14.0.dev2026012604.dist-info → keras_nightly-3.14.0.dev2026012704.dist-info}/RECORD +8 -8
- {keras_nightly-3.14.0.dev2026012604.dist-info → keras_nightly-3.14.0.dev2026012704.dist-info}/WHEEL +0 -0
- {keras_nightly-3.14.0.dev2026012604.dist-info → keras_nightly-3.14.0.dev2026012704.dist-info}/top_level.txt +0 -0
|
@@ -2270,7 +2270,16 @@ def prod(x, axis=None, keepdims=False, dtype=None):
|
|
|
2270
2270
|
|
|
2271
2271
|
|
|
2272
2272
|
def ptp(x, axis=None, keepdims=False):
|
|
2273
|
-
|
|
2273
|
+
if axis == ():
|
|
2274
|
+
return zeros_like(x)
|
|
2275
|
+
x = get_ov_output(x)
|
|
2276
|
+
|
|
2277
|
+
x_resolved, resolved_axis = _resolve_axis(x, axis)
|
|
2278
|
+
|
|
2279
|
+
max_val = ov_opset.reduce_max(x_resolved, resolved_axis, keepdims)
|
|
2280
|
+
min_val = ov_opset.reduce_min(x_resolved, resolved_axis, keepdims)
|
|
2281
|
+
|
|
2282
|
+
return OpenVINOKerasTensor(ov_opset.subtract(max_val, min_val).output(0))
|
|
2274
2283
|
|
|
2275
2284
|
|
|
2276
2285
|
def quantile(x, q, axis=None, method="linear", keepdims=False):
|
|
@@ -2682,7 +2691,23 @@ def tensordot(x1, x2, axes=2):
|
|
|
2682
2691
|
|
|
2683
2692
|
|
|
2684
2693
|
def round(x, decimals=0):
|
|
2685
|
-
|
|
2694
|
+
x = get_ov_output(x)
|
|
2695
|
+
x_type = x.get_element_type()
|
|
2696
|
+
if x_type.is_integral() or x_type == Type.boolean:
|
|
2697
|
+
x = ov_opset.convert(x, OPENVINO_DTYPES[config.floatx()])
|
|
2698
|
+
|
|
2699
|
+
if decimals == 0:
|
|
2700
|
+
result = ov_opset.round(x, "half_to_even")
|
|
2701
|
+
else:
|
|
2702
|
+
factor = ov_opset.constant(10.0**decimals, x.get_element_type())
|
|
2703
|
+
scaled = ov_opset.multiply(x, factor)
|
|
2704
|
+
rounded = ov_opset.round(scaled, "half_to_even")
|
|
2705
|
+
result = ov_opset.divide(rounded, factor)
|
|
2706
|
+
|
|
2707
|
+
if x_type.is_integral():
|
|
2708
|
+
result = ov_opset.convert(result, x_type)
|
|
2709
|
+
|
|
2710
|
+
return OpenVINOKerasTensor(result.output(0))
|
|
2686
2711
|
|
|
2687
2712
|
|
|
2688
2713
|
def tile(x, repeats):
|
|
@@ -2803,7 +2828,17 @@ def vdot(x1, x2):
|
|
|
2803
2828
|
|
|
2804
2829
|
|
|
2805
2830
|
def vstack(xs):
|
|
2806
|
-
|
|
2831
|
+
if not isinstance(xs, (list, tuple)):
|
|
2832
|
+
xs = (xs,)
|
|
2833
|
+
elems = [convert_to_tensor(elem) for elem in xs]
|
|
2834
|
+
element_type = elems[0].output.get_element_type()
|
|
2835
|
+
elems = [get_ov_output(elem, element_type) for elem in elems]
|
|
2836
|
+
axis = 0
|
|
2837
|
+
for i in range(1, len(elems)):
|
|
2838
|
+
elems[0], elems[i] = _align_operand_types(
|
|
2839
|
+
elems[0], elems[i], "vstack()"
|
|
2840
|
+
)
|
|
2841
|
+
return OpenVINOKerasTensor(ov_opset.concat(elems, axis).output(0))
|
|
2807
2842
|
|
|
2808
2843
|
|
|
2809
2844
|
def vectorize(pyfunc, *, excluded=None, signature=None):
|
|
@@ -2859,9 +2894,20 @@ def divide(x1, x2):
|
|
|
2859
2894
|
|
|
2860
2895
|
|
|
2861
2896
|
def divide_no_nan(x1, x2):
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2897
|
+
element_type = None
|
|
2898
|
+
if isinstance(x1, OpenVINOKerasTensor):
|
|
2899
|
+
element_type = x1.output.get_element_type()
|
|
2900
|
+
if isinstance(x2, OpenVINOKerasTensor):
|
|
2901
|
+
element_type = x2.output.get_element_type()
|
|
2902
|
+
x1 = get_ov_output(x1, element_type)
|
|
2903
|
+
x2 = get_ov_output(x2, element_type)
|
|
2904
|
+
x1, x2 = _align_operand_types(x1, x2, "divide_no_nan()")
|
|
2905
|
+
|
|
2906
|
+
zero = ov_opset.constant(0, x2.get_element_type())
|
|
2907
|
+
div = ov_opset.divide(x1, x2)
|
|
2908
|
+
is_zero = ov_opset.equal(x2, zero)
|
|
2909
|
+
result = ov_opset.select(is_zero, zero, div)
|
|
2910
|
+
return OpenVINOKerasTensor(result.output(0))
|
|
2865
2911
|
|
|
2866
2912
|
|
|
2867
2913
|
def true_divide(x1, x2):
|
|
@@ -36,15 +36,31 @@ class TorchExportArchive:
|
|
|
36
36
|
)
|
|
37
37
|
|
|
38
38
|
sample_inputs = tree.map_structure(
|
|
39
|
-
lambda x: convert_spec_to_tensor(x, replace_none_number=
|
|
39
|
+
lambda x: convert_spec_to_tensor(x, replace_none_number=2),
|
|
40
40
|
input_signature,
|
|
41
41
|
)
|
|
42
42
|
sample_inputs = tuple(sample_inputs)
|
|
43
43
|
|
|
44
|
+
# Build dynamic_shapes from input_signature where shape has None
|
|
45
|
+
# Use a shared "batch" dim for dimension 0 across all inputs
|
|
46
|
+
batch_dim = torch.export.Dim("batch", min=1)
|
|
47
|
+
dynamic_shapes = []
|
|
48
|
+
for spec in input_signature:
|
|
49
|
+
dim_spec = {}
|
|
50
|
+
for dim_idx, dim_val in enumerate(spec.shape):
|
|
51
|
+
if dim_val is None:
|
|
52
|
+
if dim_idx == 0:
|
|
53
|
+
dim_spec[dim_idx] = batch_dim
|
|
54
|
+
else:
|
|
55
|
+
dim_spec[dim_idx] = torch.export.Dim(
|
|
56
|
+
f"dim_{len(dynamic_shapes)}_{dim_idx}", min=1
|
|
57
|
+
)
|
|
58
|
+
dynamic_shapes.append(dim_spec if dim_spec else None)
|
|
59
|
+
dynamic_shapes = tuple(dynamic_shapes) if any(dynamic_shapes) else None
|
|
60
|
+
|
|
44
61
|
# Ref: torch_xla.tf_saved_model_integration
|
|
45
|
-
# TODO: Utilize `dynamic_shapes`
|
|
46
62
|
exported = torch.export.export(
|
|
47
|
-
resource, sample_inputs, dynamic_shapes=
|
|
63
|
+
resource, sample_inputs, dynamic_shapes=dynamic_shapes, strict=False
|
|
48
64
|
)
|
|
49
65
|
options = torch_xla.stablehlo.StableHLOExportOptions(
|
|
50
66
|
override_tracing_arguments=sample_inputs
|
|
@@ -8,6 +8,26 @@ from keras.src.layers.input_spec import InputSpec
|
|
|
8
8
|
from keras.src.layers.layer import Layer
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
# TODO(abheesht17): Move this to utils?
|
|
12
|
+
def _clone_initializer(initializer):
|
|
13
|
+
"""Clones an initializer to ensure a new seed.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
initializer: The initializer to clone.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
A cloned initializer if it is clonable, otherwise the original one.
|
|
20
|
+
|
|
21
|
+
As of tensorflow 2.10, we need to clone user passed initializers when
|
|
22
|
+
invoking them twice to avoid creating the same randomized initialization.
|
|
23
|
+
"""
|
|
24
|
+
if isinstance(initializer, initializers.Initializer):
|
|
25
|
+
config = initializer.get_config()
|
|
26
|
+
return initializer.__class__.from_config(config)
|
|
27
|
+
# If we get a string or dict, just return as we cannot and should not clone.
|
|
28
|
+
return initializer
|
|
29
|
+
|
|
30
|
+
|
|
11
31
|
@keras_export("keras.layers.BatchNormalization")
|
|
12
32
|
class BatchNormalization(Layer):
|
|
13
33
|
"""Layer that normalizes its inputs.
|
|
@@ -72,6 +92,22 @@ class BatchNormalization(Layer):
|
|
|
72
92
|
variance) for the layer across all devices at each training step
|
|
73
93
|
in a distributed training strategy.
|
|
74
94
|
If `False`, each replica uses its own local batch statistics.
|
|
95
|
+
renorm: Whether to use
|
|
96
|
+
[Batch Renormalization](https://arxiv.org/abs/1702.03275). This
|
|
97
|
+
adds extra variables during training. The inference is the same
|
|
98
|
+
for either value of this parameter.
|
|
99
|
+
renorm_clipping: Dictionary, valid only if `renorm = True`.
|
|
100
|
+
Maps optional keys `"rmax"`, `"rmin"`, `"dmax"` to floats used to
|
|
101
|
+
clip the renorm correction. The correction `(r, d)` is used as
|
|
102
|
+
`corrected_value = normalized_value * r + d`, with `r` clipped to
|
|
103
|
+
`[rmin, rmax]`, and `d` to `[-dmax, dmax]`. Missing `rmax`, `rmin`,
|
|
104
|
+
`dmax` are set to `inf`, `0`, `inf`, respectively.
|
|
105
|
+
renorm_momentum: Momentum used to update the moving means and standard
|
|
106
|
+
deviations with renorm. Valid only if `renorm= True`. Unlike
|
|
107
|
+
`momentum`, this affects training and should be neither too small
|
|
108
|
+
(which would add noise) nor too large (which would give stale
|
|
109
|
+
estimates). Note that `momentum` is still applied to get the means
|
|
110
|
+
and variances for inference.
|
|
75
111
|
**kwargs: Base layer keyword arguments (e.g. `name` and `dtype`).
|
|
76
112
|
|
|
77
113
|
Call arguments:
|
|
@@ -136,6 +172,9 @@ class BatchNormalization(Layer):
|
|
|
136
172
|
gamma_regularizer=None,
|
|
137
173
|
beta_constraint=None,
|
|
138
174
|
gamma_constraint=None,
|
|
175
|
+
renorm=False,
|
|
176
|
+
renorm_clipping=None,
|
|
177
|
+
renorm_momentum=0.99,
|
|
139
178
|
synchronized=False,
|
|
140
179
|
**kwargs,
|
|
141
180
|
):
|
|
@@ -165,6 +204,33 @@ class BatchNormalization(Layer):
|
|
|
165
204
|
self.gamma_constraint = constraints.get(gamma_constraint)
|
|
166
205
|
self.supports_masking = True
|
|
167
206
|
|
|
207
|
+
self.renorm = renorm
|
|
208
|
+
if renorm:
|
|
209
|
+
renorm_clipping = renorm_clipping or {}
|
|
210
|
+
keys = ["rmax", "rmin", "dmax"]
|
|
211
|
+
if set(renorm_clipping) - set(keys):
|
|
212
|
+
raise ValueError(
|
|
213
|
+
"Received invalid keys for `renorm_clipping` argument: "
|
|
214
|
+
f"{renorm_clipping}. Supported values: {keys}."
|
|
215
|
+
)
|
|
216
|
+
rmax = renorm_clipping.get("rmax")
|
|
217
|
+
rmin = renorm_clipping.get("rmin")
|
|
218
|
+
dmax = renorm_clipping.get("dmax")
|
|
219
|
+
|
|
220
|
+
if rmax is not None and rmin is not None and rmax < rmin:
|
|
221
|
+
raise ValueError(
|
|
222
|
+
"rmax should be greater than rmin in the `renorm_clipping` "
|
|
223
|
+
"argument. Received: rmax={rmax}, rmin={rmin}."
|
|
224
|
+
)
|
|
225
|
+
if dmax is not None and dmax < 0:
|
|
226
|
+
raise ValueError(
|
|
227
|
+
"dmax should be non-negative in the `renorm_clipping` "
|
|
228
|
+
"""argument. Received: dmax={dmax}."""
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
self.renorm_clipping = renorm_clipping
|
|
232
|
+
self.renorm_momentum = renorm_momentum
|
|
233
|
+
|
|
168
234
|
self.gamma = None
|
|
169
235
|
self.beta = None
|
|
170
236
|
self.moving_mean = None
|
|
@@ -208,6 +274,40 @@ class BatchNormalization(Layer):
|
|
|
208
274
|
autocast=False,
|
|
209
275
|
)
|
|
210
276
|
|
|
277
|
+
if self.renorm:
|
|
278
|
+
# In batch renormalization we track the inference moving stddev
|
|
279
|
+
# instead of the moving variance to more closely align with the
|
|
280
|
+
# paper. The stddev is initialized as sqrt of the variance
|
|
281
|
+
# initializer.
|
|
282
|
+
def moving_stddev_initializer(shape, dtype=None):
|
|
283
|
+
cloned = _clone_initializer(self.moving_variance_initializer)
|
|
284
|
+
return ops.sqrt(cloned(shape, dtype=dtype))
|
|
285
|
+
|
|
286
|
+
self.moving_stddev = self.add_weight(
|
|
287
|
+
shape=shape,
|
|
288
|
+
name="moving_stddev",
|
|
289
|
+
initializer=moving_stddev_initializer,
|
|
290
|
+
trainable=False,
|
|
291
|
+
autocast=False,
|
|
292
|
+
)
|
|
293
|
+
# Create variables to maintain the moving mean and standard
|
|
294
|
+
# deviation. These are used in training and thus are different
|
|
295
|
+
# from the moving averages above.
|
|
296
|
+
self.renorm_mean = self.add_weight(
|
|
297
|
+
shape=shape,
|
|
298
|
+
name="renorm_mean",
|
|
299
|
+
initializer=_clone_initializer(self.moving_mean_initializer),
|
|
300
|
+
trainable=False,
|
|
301
|
+
autocast=False,
|
|
302
|
+
)
|
|
303
|
+
self.renorm_stddev = self.add_weight(
|
|
304
|
+
shape=shape,
|
|
305
|
+
name="renorm_stddev",
|
|
306
|
+
initializer=moving_stddev_initializer,
|
|
307
|
+
trainable=False,
|
|
308
|
+
autocast=False,
|
|
309
|
+
)
|
|
310
|
+
|
|
211
311
|
self.input_spec = InputSpec(
|
|
212
312
|
ndim=len(input_shape), axes={self.axis: input_shape[self.axis]}
|
|
213
313
|
)
|
|
@@ -250,20 +350,6 @@ class BatchNormalization(Layer):
|
|
|
250
350
|
moving_mean = ops.cast(self.moving_mean, inputs.dtype)
|
|
251
351
|
moving_variance = ops.cast(self.moving_variance, inputs.dtype)
|
|
252
352
|
|
|
253
|
-
if training and self.trainable:
|
|
254
|
-
mean, variance = self._moments(inputs, mask)
|
|
255
|
-
|
|
256
|
-
self.moving_mean.assign(
|
|
257
|
-
moving_mean * self.momentum + mean * (1.0 - self.momentum)
|
|
258
|
-
)
|
|
259
|
-
self.moving_variance.assign(
|
|
260
|
-
moving_variance * self.momentum
|
|
261
|
-
+ variance * (1.0 - self.momentum)
|
|
262
|
-
)
|
|
263
|
-
else:
|
|
264
|
-
mean = moving_mean
|
|
265
|
-
variance = moving_variance
|
|
266
|
-
|
|
267
353
|
if self.scale:
|
|
268
354
|
gamma = ops.cast(self.gamma, inputs.dtype)
|
|
269
355
|
else:
|
|
@@ -274,6 +360,39 @@ class BatchNormalization(Layer):
|
|
|
274
360
|
else:
|
|
275
361
|
beta = None
|
|
276
362
|
|
|
363
|
+
if training and self.trainable:
|
|
364
|
+
mean, variance = self._moments(inputs, mask)
|
|
365
|
+
|
|
366
|
+
if self.renorm:
|
|
367
|
+
# Compute renorm corrections (r and d).
|
|
368
|
+
(
|
|
369
|
+
r,
|
|
370
|
+
d,
|
|
371
|
+
mean,
|
|
372
|
+
variance,
|
|
373
|
+
) = self._renorm_correction_and_moments(mean, variance)
|
|
374
|
+
|
|
375
|
+
# x = x * gamma + beta without renorm, and
|
|
376
|
+
# (x * r + d) * gamma + beta = x * (r * gamma) + (d * gamma +
|
|
377
|
+
# beta) with renorm.
|
|
378
|
+
gamma, beta = self._compose_transforms(
|
|
379
|
+
r, d, gamma, beta, inputs.dtype
|
|
380
|
+
)
|
|
381
|
+
|
|
382
|
+
# Update moving statistics.
|
|
383
|
+
self._update_renorm_statistics(mean, variance)
|
|
384
|
+
else:
|
|
385
|
+
self.moving_mean.assign(
|
|
386
|
+
moving_mean * self.momentum + mean * (1.0 - self.momentum)
|
|
387
|
+
)
|
|
388
|
+
self.moving_variance.assign(
|
|
389
|
+
moving_variance * self.momentum
|
|
390
|
+
+ variance * (1.0 - self.momentum)
|
|
391
|
+
)
|
|
392
|
+
else:
|
|
393
|
+
mean = moving_mean
|
|
394
|
+
variance = moving_variance
|
|
395
|
+
|
|
277
396
|
outputs = ops.batch_normalization(
|
|
278
397
|
x=inputs,
|
|
279
398
|
mean=mean,
|
|
@@ -306,6 +425,9 @@ class BatchNormalization(Layer):
|
|
|
306
425
|
"beta_constraint": constraints.serialize(self.beta_constraint),
|
|
307
426
|
"gamma_constraint": constraints.serialize(self.gamma_constraint),
|
|
308
427
|
"synchronized": self.synchronized,
|
|
428
|
+
"renorm": self.renorm,
|
|
429
|
+
"renorm_clipping": self.renorm_clipping,
|
|
430
|
+
"renorm_momentum": self.renorm_momentum,
|
|
309
431
|
}
|
|
310
432
|
return {**base_config, **config}
|
|
311
433
|
|
|
@@ -346,3 +468,115 @@ class BatchNormalization(Layer):
|
|
|
346
468
|
variance = weighted_distsq / (sum_of_weights + backend.epsilon())
|
|
347
469
|
|
|
348
470
|
return ops.squeeze(mean), ops.squeeze(variance)
|
|
471
|
+
|
|
472
|
+
def _renorm_correction_and_moments(self, mean, variance):
|
|
473
|
+
"""Computes the correction for batch renormalization.
|
|
474
|
+
|
|
475
|
+
This method computes the r and d correction factors.
|
|
476
|
+
|
|
477
|
+
Args:
|
|
478
|
+
mean: The mean of the current batch.
|
|
479
|
+
variance: The variance of the current batch.
|
|
480
|
+
|
|
481
|
+
Returns:
|
|
482
|
+
A tuple (r, s, mean, variance) where r and d are the correction
|
|
483
|
+
factors, and mean/variance are passed through unchanged.
|
|
484
|
+
"""
|
|
485
|
+
stddev = ops.sqrt(variance + self.epsilon)
|
|
486
|
+
|
|
487
|
+
# Get the renorm moving statistics.
|
|
488
|
+
renorm_mean = ops.cast(self.renorm_mean, mean.dtype)
|
|
489
|
+
# Avoid divide by zero early on in training.
|
|
490
|
+
renorm_stddev = ops.maximum(
|
|
491
|
+
ops.cast(self.renorm_stddev, mean.dtype),
|
|
492
|
+
ops.sqrt(ops.cast(self.epsilon, mean.dtype)),
|
|
493
|
+
)
|
|
494
|
+
|
|
495
|
+
# Compute the corrections for batch renorm.
|
|
496
|
+
r = ops.divide(stddev, renorm_stddev)
|
|
497
|
+
d = ops.divide(ops.subtract(mean, renorm_mean), renorm_stddev)
|
|
498
|
+
|
|
499
|
+
# Apply clipping.
|
|
500
|
+
rmin = self.renorm_clipping.get("rmin")
|
|
501
|
+
rmax = self.renorm_clipping.get("rmax")
|
|
502
|
+
dmax = self.renorm_clipping.get("dmax")
|
|
503
|
+
|
|
504
|
+
if rmin is not None:
|
|
505
|
+
r = ops.maximum(r, rmin)
|
|
506
|
+
if rmax is not None:
|
|
507
|
+
r = ops.minimum(r, rmax)
|
|
508
|
+
if dmax is not None:
|
|
509
|
+
d = ops.clip(d, -dmax, dmax)
|
|
510
|
+
|
|
511
|
+
return r, d, mean, variance
|
|
512
|
+
|
|
513
|
+
def _compose_transforms(self, r, d, gamma, beta, dtype):
|
|
514
|
+
"""Composes the renorm correction with gamma and beta.
|
|
515
|
+
|
|
516
|
+
When training with renorm, the normalized values (x) are transformed
|
|
517
|
+
as: (x * r + d) * gamma + beta = x * (r * gamma) + (d * gamma + beta).
|
|
518
|
+
This method computes the effective scale and offset.
|
|
519
|
+
|
|
520
|
+
Args:
|
|
521
|
+
r: The r correction factor.
|
|
522
|
+
d: The d correction factor.
|
|
523
|
+
gamma: The gamma (scale) parameter, or None.
|
|
524
|
+
beta: The beta (offset) parameter, or None.
|
|
525
|
+
dtype: The dtype for the output.
|
|
526
|
+
|
|
527
|
+
Returns:
|
|
528
|
+
A tuple (effective_gamma, effective_beta).
|
|
529
|
+
"""
|
|
530
|
+
r = ops.stop_gradient(r)
|
|
531
|
+
d = ops.stop_gradient(d)
|
|
532
|
+
|
|
533
|
+
if gamma is not None:
|
|
534
|
+
effective_gamma = ops.multiply(r, gamma)
|
|
535
|
+
effective_beta = ops.multiply(d, gamma)
|
|
536
|
+
else:
|
|
537
|
+
effective_gamma = ops.cast(r, dtype)
|
|
538
|
+
effective_beta = ops.cast(d, dtype)
|
|
539
|
+
|
|
540
|
+
if beta is not None:
|
|
541
|
+
effective_beta = ops.add(effective_beta, beta)
|
|
542
|
+
|
|
543
|
+
return effective_gamma, effective_beta
|
|
544
|
+
|
|
545
|
+
def _update_renorm_statistics(self, mean, variance):
|
|
546
|
+
"""Updates the renorm and moving statistics.
|
|
547
|
+
Args:
|
|
548
|
+
mean: The mean of the current batch.
|
|
549
|
+
variance: The variance of the current batch.
|
|
550
|
+
"""
|
|
551
|
+
stddev = ops.sqrt(variance + self.epsilon)
|
|
552
|
+
|
|
553
|
+
# Update renorm moving mean and stddev.
|
|
554
|
+
renorm_mean = ops.cast(self.renorm_mean, mean.dtype)
|
|
555
|
+
renorm_stddev = ops.cast(self.renorm_stddev, mean.dtype)
|
|
556
|
+
|
|
557
|
+
self.renorm_mean.assign(
|
|
558
|
+
renorm_mean * self.renorm_momentum
|
|
559
|
+
+ mean * (1.0 - self.renorm_momentum)
|
|
560
|
+
)
|
|
561
|
+
self.renorm_stddev.assign(
|
|
562
|
+
renorm_stddev * self.renorm_momentum
|
|
563
|
+
+ stddev * (1.0 - self.renorm_momentum)
|
|
564
|
+
)
|
|
565
|
+
|
|
566
|
+
moving_mean = ops.cast(self.moving_mean, mean.dtype)
|
|
567
|
+
moving_stddev = ops.cast(self.moving_stddev, mean.dtype)
|
|
568
|
+
|
|
569
|
+
self.moving_mean.assign(
|
|
570
|
+
moving_mean * self.momentum + mean * (1.0 - self.momentum)
|
|
571
|
+
)
|
|
572
|
+
|
|
573
|
+
new_moving_stddev = moving_stddev * self.momentum + stddev * (
|
|
574
|
+
1.0 - self.momentum
|
|
575
|
+
)
|
|
576
|
+
self.moving_stddev.assign(new_moving_stddev)
|
|
577
|
+
|
|
578
|
+
# Derive `moving_variance` from `moving_stddev`, applying ReLU in case
|
|
579
|
+
# floating point rounding causes it to go negative.
|
|
580
|
+
self.moving_variance.assign(
|
|
581
|
+
ops.relu(new_moving_stddev * new_moving_stddev - self.epsilon)
|
|
582
|
+
)
|
keras/src/version.py
CHANGED
{keras_nightly-3.14.0.dev2026012604.dist-info → keras_nightly-3.14.0.dev2026012704.dist-info}/RECORD
RENAMED
|
@@ -128,7 +128,7 @@ keras/regularizers/__init__.py,sha256=542Shphw7W8h4Dyf2rmqMKUECVZ8IVBvN9g1LWhz-b
|
|
|
128
128
|
keras/saving/__init__.py,sha256=KvL2GZxjvgFgEhvEnkvqjIR9JSNHKz-NWZacXajsjLI,1298
|
|
129
129
|
keras/src/__init__.py,sha256=Gi4S7EiCMkE03PbdGNpFdaUYySWDs_FcAJ8Taz9Y1BE,684
|
|
130
130
|
keras/src/api_export.py,sha256=gXOkBOnmscV013WAc75lc4Up01-Kkg9EylIAT_QWctg,1173
|
|
131
|
-
keras/src/version.py,sha256=
|
|
131
|
+
keras/src/version.py,sha256=NJIml5PJgVtz-3KeL-ybBmxHJGE7ed1_h7tLzegDbmY,204
|
|
132
132
|
keras/src/activations/__init__.py,sha256=0nL3IFDB9unlrMz8ninKOWo-uCHasTUpTo1tXZb2u44,4433
|
|
133
133
|
keras/src/activations/activations.py,sha256=mogPggtp4CGldI3VOPNmesRxp6EbiR1_i4KLGaVwzL8,17614
|
|
134
134
|
keras/src/applications/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -198,7 +198,7 @@ keras/src/backend/openvino/layer.py,sha256=5RdvaH1yOyPAphjKiuQAK1H_yZFYKE1Hp7c5b
|
|
|
198
198
|
keras/src/backend/openvino/linalg.py,sha256=L6a4MFGND2wWzPVCh44cwuOgkcC4wJTo8Xy3HwW04lg,1614
|
|
199
199
|
keras/src/backend/openvino/math.py,sha256=qw9kX2sJ2qr0dBJF12Ey0E2GcwixPUqoev6UcNra4NI,3944
|
|
200
200
|
keras/src/backend/openvino/nn.py,sha256=zULPxdwVO7JDZUUtsuoEEPCLQ09ew8z8T6G_i_NEqrM,23741
|
|
201
|
-
keras/src/backend/openvino/numpy.py,sha256=
|
|
201
|
+
keras/src/backend/openvino/numpy.py,sha256=ML-PW8BvLpdqkYVo0KsebSHRwH8OaAnZUbmfB1LZAy4,111639
|
|
202
202
|
keras/src/backend/openvino/random.py,sha256=4hRUtIP6qJxO3Qy9uH1x6jSuJna3nWPdUf4x2QU8-ew,5575
|
|
203
203
|
keras/src/backend/openvino/rnn.py,sha256=ErmuZLPSgG9qU-NfYPPvBZ6Ysy8k-fA4g19Vhqq7OVQ,866
|
|
204
204
|
keras/src/backend/openvino/trainer.py,sha256=bMmtSALqydqdS6ke-5sYW5fgxZDshDH810p_C0xCRTg,9087
|
|
@@ -221,7 +221,7 @@ keras/src/backend/tensorflow/trackable.py,sha256=QZn0JvpBJ7Kx4e6zM2IVIWz9ADcWDB-
|
|
|
221
221
|
keras/src/backend/tensorflow/trainer.py,sha256=otJ4CciSmE2-QH17bEyjaL-oQxiCD5eWgbkEglxjt4w,37191
|
|
222
222
|
keras/src/backend/torch/__init__.py,sha256=0SiJ91WMaE_tO5q1zUsLEnU6hmPTpGKPIOkmIWaHlhk,2131
|
|
223
223
|
keras/src/backend/torch/core.py,sha256=cMo5dCDxWicWgezOargrq1qx-tlS1GJzzYXm--PS1l0,24506
|
|
224
|
-
keras/src/backend/torch/export.py,sha256=
|
|
224
|
+
keras/src/backend/torch/export.py,sha256=9efHPdN_xvSWB0pndr_X9JJmQNwWyvrGBQOr_xOQDHc,5685
|
|
225
225
|
keras/src/backend/torch/image.py,sha256=eer8LZwDMz3k2Dh5gxeTQfwrxPemM_H6eHMIP3AwRss,39149
|
|
226
226
|
keras/src/backend/torch/layer.py,sha256=htECdpv9ioHWM8_zqQkEdxgDsgLu8XJi5yXgnLl-JFw,2084
|
|
227
227
|
keras/src/backend/torch/linalg.py,sha256=wgPCfnscp5HOBmX9_-m-57lzxs1ttLNzmHqj2VYYq7k,2108
|
|
@@ -344,7 +344,7 @@ keras/src/layers/merging/minimum.py,sha256=f8RN1O5yYzDqJbXuVTBKC0TKdEw_VU4bC4pZX
|
|
|
344
344
|
keras/src/layers/merging/multiply.py,sha256=WvBX5gOpouqfQYnpioKMw2Tj6HRQQ2LNBuvKsRo_6P0,3185
|
|
345
345
|
keras/src/layers/merging/subtract.py,sha256=ijpJDomo1JSMCw97Rn55LXiVLsI50lcvUxmZiv_HIzo,2684
|
|
346
346
|
keras/src/layers/normalization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
347
|
-
keras/src/layers/normalization/batch_normalization.py,sha256=
|
|
347
|
+
keras/src/layers/normalization/batch_normalization.py,sha256=RXvCB4Nq0I9c5qPtL9UlhuOaomfsjBtrs7B-sAUYZhg,23453
|
|
348
348
|
keras/src/layers/normalization/group_normalization.py,sha256=S8w40kMCi_aEN079vwDPxaV7K02Ny0HocZJ1ATX4SpA,9367
|
|
349
349
|
keras/src/layers/normalization/layer_normalization.py,sha256=4GHBLQf2BSRLv2-73rPRWTgLKwYU7V0wXKZ99dA2jhw,8622
|
|
350
350
|
keras/src/layers/normalization/rms_normalization.py,sha256=IJMNWEg41ELWWd_V5PfUZaseB2lIKKpE0KC-M-T4INY,3008
|
|
@@ -618,7 +618,7 @@ keras/utils/bounding_boxes/__init__.py,sha256=jtvQll4u8ZY0Z96HwNhP1nxWEG9FM3gI-6
|
|
|
618
618
|
keras/utils/legacy/__init__.py,sha256=oSYZz6uS8UxSElRaaJYWJEoweJ4GAasZjnn7fNaOlog,342
|
|
619
619
|
keras/visualization/__init__.py,sha256=UKWmiy6sps4SWlmQi9WX8_Z53cPpLlphz2zIeHdwJpQ,722
|
|
620
620
|
keras/wrappers/__init__.py,sha256=QkS-O5K8qGS7C3sytF8MpmO6PasATpNVGF8qtb7Ojsw,407
|
|
621
|
-
keras_nightly-3.14.0.
|
|
622
|
-
keras_nightly-3.14.0.
|
|
623
|
-
keras_nightly-3.14.0.
|
|
624
|
-
keras_nightly-3.14.0.
|
|
621
|
+
keras_nightly-3.14.0.dev2026012704.dist-info/METADATA,sha256=wRM5XhLX-CtFBWe6lPjmVjDb-4-WwjDQT2DTE--cn5s,6339
|
|
622
|
+
keras_nightly-3.14.0.dev2026012704.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
623
|
+
keras_nightly-3.14.0.dev2026012704.dist-info/top_level.txt,sha256=ptcw_-QuGZ4ZDjMdwi_Z0clZm8QAqFdvzzFnDEOTs9o,6
|
|
624
|
+
keras_nightly-3.14.0.dev2026012704.dist-info/RECORD,,
|
{keras_nightly-3.14.0.dev2026012604.dist-info → keras_nightly-3.14.0.dev2026012704.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|