
    2VhS"                         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 d dl	m
Z
  edd	g       G d
 de             Zd ZddZddZ	 	 	 	 ddZd Zd Zd Zy)    )backend)dtype_policies)ops)tree)keras_export)KerasSaveable)	auto_namez
keras.Losszkeras.losses.Lossc                   R    e Zd ZdZd
dZed        ZddZd Zd Z	e
d        Zd	 Zy)Lossa  Loss base class.

    This is the class to subclass in order to create new custom losses.

    Args:
        reduction: Type of reduction to apply to the loss. In almost all cases
            this should be `"sum_over_batch_size"`. Supported options are
            `"sum"`, `"sum_over_batch_size"`, `"mean"`,
            `"mean_with_sample_weight"` or `None`. `"sum"` sums the loss,
            `"sum_over_batch_size"` and `"mean"` sum the loss and divide by the
            sample size, and `"mean_with_sample_weight"` sums the loss and
            divides by the sum of the sample weights. `"none"` and `None`
            perform no aggregation. Defaults to `"sum_over_batch_size"`.
        name: Optional name for the loss instance.
        dtype: The dtype of the loss's computations. Defaults to `None`, which
            means using `keras.backend.floatx()`. `keras.backend.floatx()` is a
            `"float32"` unless set to different value
            (via `keras.backend.set_floatx()`). If a `keras.DTypePolicy` is
            provided, then the `compute_dtype` will be utilized.

    To be implemented by subclasses:

    * `call()`: Contains the logic for loss calculation using `y_true`,
        `y_pred`.

    Example subclass implementation:

    ```python
    class MeanSquaredError(Loss):
        def call(self, y_true, y_pred):
            return ops.mean(ops.square(y_pred - y_true), axis=-1)
    ```
    Nc                 
   |xs t        | j                  j                        | _        t	        |      | _        t        j                  |xs t        j                               | _
        | j                  j                  | _        y N)r	   	__class____name__namestandardize_reduction	reductionr   getr   floatx_dtype_policycompute_dtype_dtype)selfr   r   dtypes       E/home/dcms/DCMS/lib/python3.12/site-packages/keras/src/losses/loss.py__init__zLoss.__init__.   s[    >Idnn&=&=>	.y9+//0I9IJ((66    c                     | j                   S r   )r   r   s    r   r   z
Loss.dtype4   s    {{r   c                     t        j                  |      }t        j                   j                        5  t        j                   fd|      }t        j                   fd|      } j                  ||      }t        j                  |      }||||z  }n||}n||}nd }t        ||| j                   j                        cd d d        S # 1 sw Y   y xY w)Nc                 F    t        j                  | j                        S Nr   r   convert_to_tensorr   xr   s    r   <lambda>zLoss.__call__.<locals>.<lambda>=       #//D r   c                 F    t        j                  | j                        S r!   r#   r%   s    r   r'   zLoss.__call__.<locals>.<lambda>@   r(   r   )sample_weightmaskr   r   )r   get_keras_maskr   
name_scoper   r   map_structurecallreduce_weighted_valuesr   r   )r   y_truey_predr*   in_masklossesout_maskr+   s   `       r   __call__zLoss.__call__8   s    ((0^^DII& 	''DfF ''DfF YYvv.F--f5H"x';)$%)+..jj)	 	 	s   BCCc                     t         r   )NotImplementedError)r   r1   r2   s      r   r/   z	Loss.callW   s    !!r   c                 4    | j                   | j                  dS )Nr   r   r:   r   s    r   
get_configzLoss.get_configZ   s    		??r   c                      | di |S )N r=   )clsconfigs     r   from_configzLoss.from_config]   s    }V}r   c                      y)Nr   r=   r   s    r   	_obj_typezLoss._obj_typea   s    r   )Nsum_over_batch_sizeNr   )r   
__module____qualname____doc__r   propertyr   r6   r/   r;   classmethodr@   rB   r=   r   r   r   r   
   sJ     D7  >"@  r   r   c                 8    h d}| |vrt        d| d|        | S )N>   NsummeannonerC   mean_with_sample_weightz8Invalid value for argument `reduction`. Expected one of z. Received: reduction=)
ValueError)r   alloweds     r   r   r   e   sA    G &i ("%
 	

 r   c                    t        | j                        }t        |j                        }||k(  r| |fS ||dz   k(  rH| j                  d   dk(  r6|dk(  r|rt        j                  |d      }nt        j                  | d      } ||dz   k(  rK|j                  d   dk(  r9|dk(  r|rt        j                  | d      } | |fS t        j                  |d      }| |fS )zCSqueeze/expand last dim if ranks differ from expected by exactly 1.   )axis)lenshaper   expand_dimssqueeze)x1x2expand_rank_1x1_rankx2_ranks        r   squeeze_or_expand_to_same_rankr]   w   s    "((mG"((mG'2v'A+88B<1!|__Rb1[["-'A+88B<1!|__Rb1 r6M [["-r6Mr   Nc           	         |5|dk(  s0t        | j                        dk(  st        | j                        dk(  r| S t        j                  |       }|dv r|dk(  r6|4t        j                  t        j                  |      |j
                        }n[t        j                  t        j                  t        j                  t        j                  |       d            |j
                        }t        j                  ||      }t        |      }|S )NrL   r=   )r   )rC   rK   rM   rM   int32r"   )
tuplerU   r   rJ   castr   prodr$   divide_no_nanscale_loss_for_distribution)valuesr*   r   lossdivisors        r   reduce_valuesrh      s    "$$&776?DNN11m6Ohhsww}5tzzBGhh))#))F*;7K 

	G   w/*40Kr   c                 f   t        |      }t        j                  | |      } |t        j                  ||      }|t        j                  ||      }t        ||| j                  |      }|4t        j
                  || j                        }t        | |      \  } }| |z  } t        | ||      }|S )Nr"   )r   r   )r   r   r$   
apply_maskr   ra   r]   rh   )re   r*   r+   r   r   rf   s         r   r0   r0      s     &i0I""67F --m5I$$T7 t6<<9M  = >M!
 -' 	:DKr   c           	         |t        j                  ||      }|dv rt        j                  t        j                  t        j                  t        j                  |      d            |      }t        j
                  |      }|||t        j                         z   z  z  }| -t        j                  | |      } t        ||       \  }} | |z  } | S |} | S )z2Applies any mask on predictions to sample weights.r"   )rK   rC   r_   )	r   ra   rb   r$   rU   rJ   r   epsilonr]   )r*   r+   r   r   totalvalids         r   rj   rj      s    xxE*77 HH..syygNOE GGDMEEUW__%6677D$HH]%@M"@m#D- T!M  !Mr   c                     t        j                          dk(  rdddl}|j                  j                         j                  }|dkD  r7t        j                  | t        j                  d|z  | j                              } | S )zScales the given value by the number of replicas in the strategy.

    Currently, this function is only effective when using the tensorflow backend
    and `tf.distribute`.
    
tensorflowr   NrQ   g      ?	r   rp   
distributeget_strategynum_replicas_in_syncr   multiplyra   r   valuetfnum_replicass      r   rd   rd      sd     L(}}113HH!LLsxxl 2EKK@E Lr   c                     t        j                          dk(  raddl}|j                  j                         j                  }|dkD  r4t        j                  | t        j                  || j                              } | S )zUnscales the given value by the number of replicas in the strategy.

    Currently, this function is only effective when using the tensorflow backend
    and `tf.distribute`.
    rp   r   NrQ   rq   rv   s      r   unscale_loss_for_distributionr{      sZ     L(}}113HH!LLu{{(KLELr   )T)NrC   )NNrC   N)	keras.srcr   r   r   r   keras.src.api_exportr   keras.src.saving.keras_saveabler   keras.src.utils.namingr	   r   r   r]   rh   r0   rj   rd   r{   r=   r   r   <module>r      sv     $   - 9 , |012W= W 3Wt$*4 	#
B<"r   