
    6bi}6                        S r SSKrSSKJs  Jr  SSKJr  SSKJ	r
  SSKJr  SSKJr  SSKJr  SSKJr  \" S	5       " S
 S5      5       r\" SS5       " S S\5      5       r\" SS5       " S S\5      5       r\" SS5       " S S\5      5       r\" SS5       " S S\5      5       r\" SS5       " S S\5      5       r\r\r\r\r\r\r\r\r\" S 5      S&S! j5       r \" S"5      S'S# j5       r!\" S$5      S% 5       r"g)(z@Constraints: functions that impose constraints on weight values.    N)backend)serialization)deserialize_keras_object)serialize_keras_object)keras_export)doc_controlszkeras.constraints.Constraintc                   4    \ rS rSrSrS rS r\S 5       rSr	g)
Constraint!   a+  Base class for weight constraints.

A `Constraint` instance works like a stateless function.
Users who subclass this
class should override the `__call__` method, which takes a single
weight parameter and return a projected version of that parameter
(e.g. normalized or clipped). Constraints can be used with various Keras
layers via the `kernel_constraint` or `bias_constraint` arguments.

Here's a simple example of a non-negative weight constraint:

>>> class NonNegative(tf.keras.constraints.Constraint):
...
...  def __call__(self, w):
...    return w * tf.cast(tf.math.greater_equal(w, 0.), w.dtype)

>>> weight = tf.constant((-1.0, 1.0))
>>> NonNegative()(weight)
<tf.Tensor: shape=(2,), dtype=float32, numpy=array([0.,  1.],
dtype=float32)>

>>> tf.keras.layers.Dense(4, kernel_constraint=NonNegative())
c                     U$ )a'  Applies the constraint to the input weight variable.

By default, the inputs weight variable is not modified.
Users should override this method to implement their own projection
function.

Args:
  w: Input weight variable.

Returns:
  Projected variable (by default, returns unmodified inputs).
 selfws     R/home/james-whalen/.local/lib/python3.13/site-packages/tf_keras/src/constraints.py__call__Constraint.__call__;   s	         c                     0 $ )zReturns a Python dict of the object config.

A constraint config is a Python dictionary (JSON-serializable) that can
be used to reinstantiate the same object.

Returns:
  Python dict containing the configuration of the constraint object.
r   r   s    r   
get_configConstraint.get_configJ   s	     	r   c                     U " S0 UD6$ )a:  Instantiates a weight constraint from a configuration dictionary.

Example:

```python
constraint = UnitNorm()
config = constraint.get_config()
constraint = UnitNorm.from_config(config)
```

Args:
  config: A Python dictionary, the output of `get_config`.

Returns:
  A `tf.keras.constraints.Constraint` instance.
r   r   )clsconfigs     r   from_configConstraint.from_configU   s    $ }V}r   r   N)
__name__
__module____qualname____firstlineno____doc__r   r   classmethodr   __static_attributes__r   r   r   r
   r
   !   s%    0	  r   r
   zkeras.constraints.MaxNormzkeras.constraints.max_normc                   j    \ rS rSrSrSS jr\R                  S 5       r\R                  S 5       r	Sr
g)	MaxNormj   a  MaxNorm weight constraint.

Constrains the weights incident to each hidden unit
to have a norm less than or equal to a desired value.

Also available via the shortcut function `tf.keras.constraints.max_norm`.

Args:
  max_value: the maximum norm value for the incoming weights.
  axis: integer, axis along which to calculate weight norms.
    For instance, in a `Dense` layer the weight matrix
    has shape `(input_dim, output_dim)`,
    set `axis` to `0` to constrain each weight vector
    of length `(input_dim,)`.
    In a `Conv2D` layer with `data_format="channels_last"`,
    the weight tensor has shape
    `(rows, cols, input_depth, output_depth)`,
    set `axis` to `[0, 1, 2]`
    to constrain the weights of each filter tensor of size
    `(rows, cols, input_depth)`.

c                     Xl         X l        g N	max_valueaxis)r   r+   r,   s      r   __init__MaxNorm.__init__   s    "	r   c                    [         R                  " [        R                  " [        R                  " U5      U R
                  SS95      n[         R                  " USU R                  5      nX[         R                  " 5       U-   -  -  $ )NTr,   keepdimsr   )	r   sqrttf
reduce_sumsquarer,   clipr+   epsilonr   r   normsdesireds       r   r   MaxNorm.__call__   s^    MM"))A,TYYF
 ,,ua8w0589::r   c                 4    U R                   U R                  S.$ )Nr*   r*   r   s    r   r   MaxNorm.get_config   s    !^^TYY??r   )r,   r+   N)   r   r   r   r    r!   r"   r-   r   do_not_generate_docsr   r   r$   r   r   r   r&   r&   j   sB    . &&; '; &&@ '@r   r&   zkeras.constraints.NonNegzkeras.constraints.non_negc                       \ rS rSrSrS rSrg)NonNeg   zuConstrains the weights to be non-negative.

Also available via the shortcut function `tf.keras.constraints.non_neg`.
c                     U[         R                  " [         R                  " US5      [        R                  " 5       5      -  $ )N        )r3   castgreater_equalr   floatxr   s     r   r   NonNeg.__call__   s,    2772++As3W^^5EFFFr   r   N)r   r   r    r!   r"   r   r$   r   r   r   rB   rB      s    
Gr   rB   zkeras.constraints.UnitNormzkeras.constraints.unit_normc                   j    \ rS rSrSrSS jr\R                  S 5       r\R                  S 5       r	Sr
g)	UnitNorm   a  Constrains the weights incident to each hidden unit to have unit norm.

Also available via the shortcut function `tf.keras.constraints.unit_norm`.

Args:
  axis: integer, axis along which to calculate weight norms.
    For instance, in a `Dense` layer the weight matrix
    has shape `(input_dim, output_dim)`,
    set `axis` to `0` to constrain each weight vector
    of length `(input_dim,)`.
    In a `Conv2D` layer with `data_format="channels_last"`,
    the weight tensor has shape
    `(rows, cols, input_depth, output_depth)`,
    set `axis` to `[0, 1, 2]`
    to constrain the weights of each filter tensor of size
    `(rows, cols, input_depth)`.
c                     Xl         g r)   r,   )r   r,   s     r   r-   UnitNorm.__init__   s    	r   c           
          U[         R                  " 5       [         R                  " [        R                  " [        R
                  " U5      U R                  SS95      -   -  $ )NTr0   )r   r7   r2   r3   r4   r5   r,   r   s     r   r   UnitNorm.__call__   sF    OOllbiilTJ
 	
r   c                     SU R                   0$ )Nr,   rN   r   s    r   r   UnitNorm.get_config   s    		""r   rN   N)r   r?   r   r   r   rK   rK      s@    $ &&
 '
 &&# '#r   rK   zkeras.constraints.MinMaxNormzkeras.constraints.min_max_normc                   j    \ rS rSrSrSS jr\R                  S 5       r\R                  S 5       r	Sr
g)	
MinMaxNorm   a  MinMaxNorm weight constraint.

Constrains the weights incident to each hidden unit
to have the norm between a lower bound and an upper bound.

Also available via the shortcut function
`tf.keras.constraints.min_max_norm`.

Args:
  min_value: the minimum norm for the incoming weights.
  max_value: the maximum norm for the incoming weights.
  rate: rate for enforcing the constraint: weights will be
    rescaled to yield
    `(1 - rate) * norm + rate * norm.clip(min_value, max_value)`.
    Effectively, this means that rate=1.0 stands for strict
    enforcement of the constraint, while rate<1.0 means that
    weights will be rescaled at each step to slowly move
    towards a value inside the desired interval.
  axis: integer, axis along which to calculate weight norms.
    For instance, in a `Dense` layer the weight matrix
    has shape `(input_dim, output_dim)`,
    set `axis` to `0` to constrain each weight vector
    of length `(input_dim,)`.
    In a `Conv2D` layer with `data_format="channels_last"`,
    the weight tensor has shape
    `(rows, cols, input_depth, output_depth)`,
    set `axis` to `[0, 1, 2]`
    to constrain the weights of each filter tensor of size
    `(rows, cols, input_depth)`.
c                 4    Xl         X l        X0l        X@l        g r)   	min_valuer+   rater,   )r   rY   r+   rZ   r,   s        r   r-   MinMaxNorm.__init__   s    ""		r   c                 b   [         R                  " [        R                  " [        R                  " U5      U R
                  SS95      nU R                  [         R                  " X R                  U R                  5      -  SU R                  -
  U-  -   nX[         R                  " 5       U-   -  -  $ )NTr0      )r   r2   r3   r4   r5   r,   rZ   r6   rY   r+   r7   r8   s       r   r   MinMaxNorm.__call__   s    MM"))A,TYYF
 IIUNNDNNKK499}%& 	 w0589::r   c                 `    U R                   U R                  U R                  U R                  S.$ )NrX   rX   r   s    r   r   MinMaxNorm.get_config   s*     IIII	
 	
r   )r,   r+   rY   rZ   N)rE         ?ra   r   r?   r   r   r   rU   rU      s@    > &&; '; &&
 '
r   rU   z"keras.constraints.RadialConstraintz#keras.constraints.radial_constraintc                   B    \ rS rSrSr\R                  S 5       rS rSr	g)RadialConstraint   aI  Constrains `Conv2D` kernel weights to be the same for each radius.

Also available via the shortcut function
`tf.keras.constraints.radial_constraint`.

For example, the desired output for the following 4-by-4 kernel:

```
    kernel = [[v_00, v_01, v_02, v_03],
              [v_10, v_11, v_12, v_13],
              [v_20, v_21, v_22, v_23],
              [v_30, v_31, v_32, v_33]]
```

is this::

```
    kernel = [[v_11, v_11, v_11, v_11],
              [v_11, v_33, v_33, v_11],
              [v_11, v_33, v_33, v_11],
              [v_11, v_11, v_11, v_11]]
```

This constraint can be applied to any `Conv2D` layer version, including
`Conv2DTranspose` and `SeparableConv2D`, and with either `"channels_last"`
or `"channels_first"` data format. The method assumes the weight tensor is
of shape `(rows, cols, input_depth, output_depth)`.
c           
         UR                   nUR                  b  UR                  S:w  a  [        SU 35      eUu  p4pV[        R                  " XXEU-  45      n[        R
                  " U R                  [        R                  " [        R                  " USS9SS95      n[        R                  " [        R                  " [        R                  " USS9SS9X4XV45      $ )N   zGThe weight tensor must have rank 4. Received weight tensor with shape: rN   r   )
shaperank
ValueErrorr   reshapemap_fn_kernel_constraintstackr3   unstack)r   r   w_shapeheightwidthchannelskernelss          r   r   RadialConstraint.__call__!  s    ''<<7<<1#466=Y@ 
 ,3(xOOA'/ABC NN##MM"**QR0q9
 MM"**QQ/b9H.
 	
r   c           
        ^^^	 [         R                  " SS/SS//SS9m[         R                  " T5      S   n[         R                  " US-  S5      m	[         R                  " [         R                  " [
        R                  R                  US5      S5      UU	4S jUU	4S j5      n[         R                  " [         R                  " [
        R                  R                  US5      S5      S	 S
 5      nU	4S jnUUU	4S jn[
        R                  R                  R                  UUXC/UR                  5       [
        R                  " SS/5      /S9u  psU$ )zCRadially constraints a kernel with shape (height, width,
channels).r]   int32dtyper   r>   boolc                  &   > T TS-
  T2TS-
  T24   $ )Nr]   r   kernelstarts   r   <lambda>5RadialConstraint._kernel_constraint.<locals>.<lambda>A  s!    F519u,eai%.??@r   c                  f   > T TS-
  T2TS-
  T24   [         R                  " ST R                  S9-   $ )Nr]   )r>   r>   rx   )r   zerosry   r|   s   r   r   r   B  s8    F519u,eai%.??@mmF&,,78r   c                  ,    [         R                  " SSS9$ )Nr   rw   rx   r   constantr   r   r   r   r   G      G$$Qg6r   c                  ,    [         R                  " SSS9$ )Nr]   rw   rx   r   r   r   r   r   r   H  r   r   c                 2   > [         R                  " U T5      $ r)   )r   less)indexargsr~   s     r   r   r   J  s    w||E5/Ir   c           	      P   > U S-   [         R                  " UTTTU -   TU -   4   S94$ )Nr]   )constant_values)r3   pad)iarrayr}   paddingr~   s     r   body_fn4RadialConstraint._kernel_constraint.<locals>.body_fnL  s8    q5"&&wuqy%!)7K0L  r   N)shape_invariants)r   r   rh   rF   switchr3   mathfloormodcompatv1
while_loop	get_shapeTensorShape)
r   r}   kernel_shape
kernel_newr   while_conditionr   _r   r~   s
    `      @@r   rm   #RadialConstraint._kernel_constraint7  s    ""QFQF#37C}}V,Q/\A-w7^^LL)),:FC@8

 LL)),:FC66

 J	
 		//#oo/t1MN	 0 
 r   r   N)
r   r   r    r!   r"   r   r@   r   rm   r$   r   r   r   rc   rc      s&    : &&
 '
* r   rc   zkeras.constraints.serializec                     U c  g [        U [        5      (       d#  [        R                  " S[	        U 5       S35        U(       a  [
        R                  " U 5      $ [        U 5      $ )NzThe `keras.constraints.serialize()` API should only be used for objects of type `keras.constraints.Constraint`. Found an instance of type z+, which may lead to improper serialization.)
isinstancer
   warningswarntypelegacy_serializationr   )
constraintuse_legacy_formats     r   	serializer   h  s_    j*--J'( )	
 #:::FF!*--r   zkeras.constraints.deserializec                 v    U(       a  [         R                  " U [        5       USS9$ [        U [        5       USS9$ )Nr   )module_objectscustom_objectsprintable_module_name)r   r   globals)r   r   r   s      r   deserializer   x  sC    #<<"9)".	
 	
 $y%*	 r   zkeras.constraints.getc                     U c  g[        U [        5      (       a  SU ;  n[        XS9$ [        U [        5      (       a  [        U 5      0 S.n[	        U5      $ [        U 5      (       a  U $ [        SU  35      e)z)Retrieves a TF-Keras constraint function.Nmodule)r   )
class_namer   z4Could not interpret constraint function identifier: )r   dictr   strgetcallablerj   )
identifierr   r   s      r   r   r     s}     *d##$J6:KK	J	$	$ #J2>6{	*		B:,O
 	
r   )F)NF)#r"   r   tensorflow.compat.v2r   v2r3   tf_keras.srcr   tf_keras.src.saving.legacyr   r   %tf_keras.src.saving.serialization_libr   r    tensorflow.python.util.tf_exportr   tensorflow.tools.docsr   r
   r&   rB   rK   rU   rc   max_normnon_neg	unit_normmin_max_normradial_constraintmaxnormnonnegunitnormr   r   r   r   r   r   <module>r      s  " G  ! !   L J H : . ,-E E .EP )+GH&@j &@ I&@R (*EFGZ G GG *,IJ!#z !# K!#H ,.NO8
 8
 P8
v (*OTz TTr 
	$  	 +,. -. -. /  %&
 '
r   