
    2Vh                     `    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e             Zy)	    )backend)ops)keras_export)Callbackzkeras.callbacks.SwapEMAWeightsc                   x     e Zd ZdZd fd	Zd Zd Zd Zd Zd Z	d Z
dd	Zdd
ZddZddZddZddZ xZS )SwapEMAWeightsa  Swaps model weights and EMA weights before and after evaluation.

    This callbacks replaces the model's weight values with the values of
    the optimizer's EMA weights (the exponential moving average of the past
    model weights values, implementing "Polyak averaging") before model
    evaluation, and restores the previous weights after evaluation.

    The `SwapEMAWeights` callback is to be used in conjunction with
    an optimizer that sets `use_ema=True`.

    Note that the weights are swapped in-place in order to save memory.
    The behavior is undefined if you modify the EMA weights
    or model weights in other callbacks.

    Example:

    ```python
    # Remember to set `use_ema=True` in the optimizer
    optimizer = SGD(use_ema=True)
    model.compile(optimizer=optimizer, loss=..., metrics=...)

    # Metrics will be computed with EMA weights
    model.fit(X_train, Y_train, callbacks=[SwapEMAWeights()])

    # If you want to save model checkpoint with EMA weights, you can set
    # `swap_on_epoch=True` and place ModelCheckpoint after SwapEMAWeights.
    model.fit(
        X_train,
        Y_train,
        callbacks=[SwapEMAWeights(swap_on_epoch=True), ModelCheckpoint(...)]
    )
    ```

    Args:
        swap_on_epoch: whether to perform swapping at `on_epoch_begin()`
            and `on_epoch_end()`. This is useful if you want to use
            EMA weights for other callbacks such as `ModelCheckpoint`.
            Defaults to `False`.
    c                 >    t         |           || _        d| _        y NF)super__init__swap_on_epoch_ema_weights_in_model)selfr   	__class__s     T/home/dcms/DCMS/lib/python3.12/site-packages/keras/src/callbacks/swap_ema_weights.pyr   zSwapEMAWeights.__init__1   s    *%*"    c                    t        | j                  j                  |j                        D ]  \  }}t	        |t
        j                        r|j                  }t	        |t
        j                        r|j                  }|j                  j                  j                  |d |f       |j                  j                  j                  |d |f       |j                  j                  j                  |d |f        y )Nc                 $    | j                  |      S N)
assign_addabs     r   <lambda>z3SwapEMAWeights._tf_swap_variables.<locals>.<lambda>C   s    Q\\!_ r   argsc                 *    |j                  | |z
        S r   assignr   s     r   r   z3SwapEMAWeights._tf_swap_variables.<locals>.<lambda>H       QXXa!e_ r   c                 *    | j                  | |z
        S r   r   r   s     r   r   z3SwapEMAWeights._tf_swap_variables.<locals>.<lambda>M   r    r   zipmodeltrainable_variables_model_variables_moving_average
isinstancer   Variablevalue_distribution_strategyextendedupdater   	optimizervaraverage_vars       r   _tf_swap_variablesz!SwapEMAWeights._tf_swap_variables7   s     #JJ**55!
 	C #w//0ii+w'7'78)//,,55<<,!^ = 
 ,,55<<,!^ = 
 ,,55<<,!^ = '	r   c                     t        | j                  j                  |j                        D ]<  \  }}t	        j
                  |      }|j                  |       |j                  |       > y r   )r#   r$   r%   r&   r   convert_to_numpyr   )r   r.   r/   r0   temporary_variables        r   _backend_swap_variablesz&SwapEMAWeights._backend_swap_variablesQ   s_     #JJ**55!
 	3C "%!5!5c!:JJ{#12	3r   c                 T   t        | j                  j                  |j                        D ]{  \  }}t	        |t
        j                        r|j                  }t	        |t
        j                        r|j                  }|j                  j                  j                  |d |f       } y )Nc                 $    | j                  |      S r   r   r   s     r   r   z8SwapEMAWeights._tf_finalize_ema_values.<locals>.<lambda>e   s    QXXa[ r   r   r"   r-   s       r   _tf_finalize_ema_valuesz&SwapEMAWeights._tf_finalize_ema_valuesZ   s     #JJ**55!
 	C #w//0ii+w'7'78)//,,55<<(V = 	r   c                     t        | j                  j                  |j                        D ]  \  }}|j	                  |        y r   )r#   r$   r%   r&   r   r-   s       r   _backend_finalize_ema_valuesz+SwapEMAWeights._backend_finalize_ema_valuesi   sA     #JJ**55!
 	$C s#		$r   c                 n   t        | j                  j                  d      r!| j                  j                  j                  }n| j                  j                  }t        |d      st	        d|j
                         t        j                         dk(  r| j                  |       y | j                  |       y Ninner_optimizerr&   z[SwapEMAWeights must be used when `use_ema=True` is set on the optimizer. Received: use_ema=
tensorflow)	hasattrr$   r.   r=   
ValueErroruse_emar   r1   r5   r   r.   s     r   _swap_variableszSwapEMAWeights._swap_variablesp   s    4::''):;

,,<<I

,,Iy"CD%%.%6%6$79 
 ??,##I.((3r   c                 n   t        | j                  j                  d      r!| j                  j                  j                  }n| j                  j                  }t        |d      st	        d|j
                         t        j                         dk(  r| j                  |       y | j                  |       y r<   )	r?   r$   r.   r=   r@   rA   r   r8   r:   rB   s     r   _finalize_ema_valuesz#SwapEMAWeights._finalize_ema_values   s    4::''):;

,,<<I

,,Iy"CD%%.%6%6$79 
 ??,((3--i8r   c                 f    | j                   r%| j                  r| j                          d| _        y y y r
   )r   r   rC   r   epochlogss      r   on_epoch_beginzSwapEMAWeights.on_epoch_begin   s/    $"<"<  ").D& #=r   c                     | j                   rK| j                  s>| j                          d| _        || j                  d   dz
  k(  r| j	                          y y y y )NTepochs   )r   r   rC   paramsrE   rG   s      r   on_epoch_endzSwapEMAWeights.on_epoch_end   sY    d&@&@  ")-D&
 H-11))+ 2 'Ar   c                 L    | j                   s| j                          d| _         y y NTr   rC   r   rI   s     r   on_test_beginzSwapEMAWeights.on_test_begin   $    ))  ")-D& *r   c                 L    | j                   r| j                          d| _         y y r
   rR   rS   s     r   on_test_endzSwapEMAWeights.on_test_end   s$    %%  ").D& &r   c                 L    | j                   s| j                          d| _         y y rQ   rR   rS   s     r   on_predict_beginzSwapEMAWeights.on_predict_begin   rU   r   c                 L    | j                   s| j                          d| _         y y r
   rR   rS   s     r   on_predict_endzSwapEMAWeights.on_predict_end   s$    ))  ").D& *r   )Fr   )__name__
__module____qualname____doc__r   r1   r5   r8   r:   rC   rE   rJ   rO   rT   rW   rY   r[   __classcell__)r   s   @r   r   r      sJ    &P+43$4"9"/
	,.
/
.
/r   r   N)	keras.srcr   r   keras.src.api_exportr   keras.src.callbacks.callbackr   r    r   r   <module>re      s5      - 1 ./l/X l/ 0l/r   