
    |h}6                        d Z ddlZddlmc mZ ddlmZ ddlm	Z
 ddlmZ ddlmZ ddlmZ ddlmZ  ed	       G d
 d             Z edd       G d de             Z edd       G d de             Z edd       G d de             Z edd       G d de             Z edd       G d de             ZeZeZeZeZeZeZeZeZ ed       d&d!       Z  ed"      d'd#       Z! ed$      d%        Z"y)(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                   ,    e Zd ZdZd Zd Zed        Zy)
Constraintao  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                     |S )ag  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     W/var/www/html/test/engine/venv/lib/python3.12/site-packages/tf_keras/src/constraints.py__call__zConstraint.__call__;   s	         c                     i S )a  Returns 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_configzConstraint.get_configJ   s	     	r   c                      | di |S )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_configzConstraint.from_configU   s    $ }V}r   N)__name__
__module____qualname____doc__r   r   classmethodr   r   r   r   r
   r
   !   s%    0	  r   r
   zkeras.constraints.MaxNormzkeras.constraints.max_normc                   `    e Zd ZdZddZej                  d        Zej                  d        Zy)MaxNormaQ  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                      || _         || _        y N	max_valueaxis)r   r$   r%   s      r   __init__zMaxNorm.__init__   s    "	r   c                    t        j                  t        j                  t        j                  |      | j
                  d            }t        j                  |d| j                        }||t        j                         |z   z  z  S )NTr%   keepdimsr   )	r   sqrttf
reduce_sumsquarer%   clipr$   epsilonr   r   normsdesireds       r   r   zMaxNorm.__call__   s`    MM"))A,TYYF
 ,,ua8Gw0589::r   c                 4    | j                   | j                  dS )Nr#   r#   r   s    r   r   zMaxNorm.get_config   s    !^^TYY??r   N)   r   	r   r   r   r   r&   r   do_not_generate_docsr   r   r   r   r   r    r    j   sB    . &&; '; &&@ '@r   r    zkeras.constraints.NonNegzkeras.constraints.non_negc                       e Zd ZdZd Zy)NonNegz}Constrains the weights to be non-negative.

    Also available via the shortcut function `tf.keras.constraints.non_neg`.
    c                     |t        j                  t        j                  |d      t        j                               z  S )N        )r+   castgreater_equalr   floatxr   s     r   r   zNonNeg.__call__   s,    2772++As3W^^5EFFFr   N)r   r   r   r   r   r   r   r   r8   r8      s    
Gr   r8   zkeras.constraints.UnitNormzkeras.constraints.unit_normc                   `    e Zd ZdZddZej                  d        Zej                  d        Zy)UnitNorma  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                     || _         y r"   r%   )r   r%   s     r   r&   zUnitNorm.__init__   s	    	r   c           	          |t        j                         t        j                  t        j                  t        j
                  |      | j                  d            z   z  S )NTr(   )r   r/   r*   r+   r,   r-   r%   r   s     r   r   zUnitNorm.__call__   sF    OOllbiilTJ
 	
r   c                     d| j                   iS )Nr%   rA   r   s    r   r   zUnitNorm.get_config   s    		""r   N)r   r5   r   r   r   r?   r?      s@    $ &&
 '
 &&# '#r   r?   zkeras.constraints.MinMaxNormzkeras.constraints.min_max_normc                   `    e Zd ZdZddZej                  d        Zej                  d        Zy)
MinMaxNorma(  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                 <    || _         || _        || _        || _        y r"   	min_valuer$   rater%   )r   rH   r$   rI   r%   s        r   r&   zMinMaxNorm.__init__   s    ""		r   c                 b   t        j                  t        j                  t        j                  |      | j
                  d            }| j                  t        j                  || j                  | j                        z  d| j                  z
  |z  z   }||t        j                         |z   z  z  S )NTr(      )r   r*   r+   r,   r-   r%   rI   r.   rH   r$   r/   r0   s       r   r   zMinMaxNorm.__call__   s    MM"))A,TYYF
 IIUDNNDNNKK499}%& 	 Gw0589::r   c                 `    | j                   | j                  | j                  | j                  dS )NrG   rG   r   s    r   r   zMinMaxNorm.get_config   s*     IIII	
 	
r   N)r:         ?rM   r   r5   r   r   r   rE   rE      s@    > &&; '; &&
 '
r   rE   z"keras.constraints.RadialConstraintz#keras.constraints.radial_constraintc                   :    e Zd ZdZej
                  d        Zd Zy)RadialConstrainta  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           	         |j                   }|j                  |j                  dk7  rt        d|       |\  }}}}t        j                  |||||z  f      }t        j
                  | j                  t        j                  t        j                  |d      d            }t        j                  t        j                  t        j                  |d      d      ||||f      S )N   zGThe weight tensor must have rank 4. Received weight tensor with shape: rA   r   )
shaperank
ValueErrorr   reshapemap_fn_kernel_constraintstackr+   unstack)r   r   w_shapeheightwidthchannelskernelss          r   r   zRadialConstraint.__call__!  s    ''<<7<<1#466=Y@ 
 ,3(xOOAx'/ABC NN##MM"**QR0q9
 MM"**QQ/b9UHg.
 	
r   c           
        	 t        j                  ddgddggd      t        j                        d   }t        j                  |dz  d      	t        j                  t        j                  t
        j                  j                  |d      d      	fd	fd      }t        j                  t        j                  t
        j                  j                  |d      d      d	 d
       }	fd}	fd}t
        j                  j                  j                  ||||g|j                         t        j                  ddg      g      \  }}|S )zKRadially constraints a kernel with shape (height, width,
        channels).rK   int32dtyper   r4   boolc                  &     dz
  dz
  f   S )NrK   r   kernelstarts   r   <lambda>z5RadialConstraint._kernel_constraint.<locals>.<lambda>A  s#    F519u,eai%.??@ r   c                  j     dz
  dz
  f   t        j                  d j                        z   S )NrK   )r4   r4   rb   )r   zerosrc   rf   s   r   ri   z5RadialConstraint._kernel_constraint.<locals>.<lambda>B  s:    F519u,eai%.??@mmF&,,78 r   c                  0    t        j                  dd      S )Nr   ra   rb   r   constantr   r   r   ri   z5RadialConstraint._kernel_constraint.<locals>.<lambda>G      G$$Qg6 r   c                  0    t        j                  dd      S )NrK   ra   rb   rm   r   r   r   ri   z5RadialConstraint._kernel_constraint.<locals>.<lambda>H  ro   r   c                 0    t        j                  |       S r"   )r   less)indexargsrh   s     r   ri   z5RadialConstraint._kernel_constraint.<locals>.<lambda>J  s    w||E5/I r   c           	      T    | dz   t        j                  || z   | z   f         fS )NrK   )constant_values)r+   pad)iarrayrg   paddingrh   s     r   body_fnz4RadialConstraint._kernel_constraint.<locals>.body_fnL  s8    q5"&&wuqy%!)7K0L  r   N)shape_invariants)r   rn   rS   r;   switchr+   mathfloormodcompatv1
while_loop	get_shapeTensorShape)
r   rg   kernel_shape
kernel_newrs   while_conditionr{   _rz   rh   s
    `      @@r   rX   z#RadialConstraint._kernel_constraint7  s    ""QFQF#37C}}V,Q/\A-w7^^LL)),:FC@8

 LL)),:FC66

 J	
 		//J#oo/t1MN	 0 
: r   N)r   r   r   r   r   r6   r   rX   r   r   r   rO   rO      s&    : &&
 '
* r   rO   zkeras.constraints.serializec                     | y t        | t              s"t        j                  dt	        |        d       |rt        j                  |       S t        |       S )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    |r!t        j                  | t               |d      S t        | t               |d      S )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                     | yt        | t              rd| v}t        | |      S t        | t              rt        |       i d}t	        |      S t        |       r| S t        d|        )z)Retrieves a TF-Keras constraint function.Nmodule)r   )
class_namer   z4Could not interpret constraint function identifier: )r   dictr   strgetcallablerU   )
identifierr   r   s      r   r   r     sw     *d#$J6:9JKK	J	$ #J2>6{	*	B:,O
 	
r   )F)NF)#r   r   tensorflow.compat.v2r   v2r+   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    r8   r?   rE   rO   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   