
    6bi"                     j    S r SSKrSSKJs  Jr  SSKJr  SS jr	 SS jr
 " S S5      rS rS	 rS
 rg)zTraining-related utilities.    N)generic_utilsc                    Sn[        U [        5      (       d  SnU /n [        S U  5       5      (       as  U(       dN  U  VVs/ s H  oA Vs/ s H	  oTXUS-    PM     snPM     nnnU Vs/ s H  n[        R                  " USS9PM     nnO4U  Vs/ s H  oDUS   US   S-    PM     nnO[
        R                  " X5      nU(       a  US   nU$ s  snf s  snnf s  snf s  snf )a  Slices batches out of provided arrays (workaround for eager tensors).

Unfortunately eager tensors don't have the same slicing behavior as
Numpy arrays (they follow the same slicing behavior as symbolic TF tensors),
hence we cannot use `generic_utils.slice_arrays` directly
and we have to implement this workaround based on `concat`. This has a
performance cost.

Args:
  arrays: Single array or list of arrays.
  indices: List of indices in the array that should be included in the
    output batch.
  contiguous: Boolean flag indicating whether the indices are contiguous.

Returns:
  Slice of data (either single array or list of arrays).
FTc              3   N   #    U  H  n[         R                  " U5      v   M     g 7fN)tf	is_tensor).0xs     \/home/james-whalen/.local/lib/python3.13/site-packages/tf_keras/src/engine/training_utils.py	<genexpr>slice_arrays.<locals>.<genexpr>-   s     
+Fq2<<??Fs   #%   r   )axis)
isinstancelistanyr   concatr   slice_arrays)arraysindices
contiguousconverted_to_listr
   ientriesslicess           r   r   r      s    $ fd## 

+F
+++@FG1g6g!!eg6GG4;<Gqbii*GF<F?EFv!
WR[1_5vFFF++F<M 7G<Fs$    	C	CC'CCCc                    [        U[        [        45      (       d  USLnU=(       a    USL nO8USL=(       a    [        S U 5       5      nU=(       a    [        S U 5       5      nU(       d  SXE4$ U(       d  XU4$ U(       a  [        R
                  R                  [        U5      [        [        R
                  R                  U5      5      5        [        R
                  R                  [        U 5      [        [        R
                  R                  U 5      5      5        Ub=  [        R
                  R                  U[        R
                  R                  U5      5        / n[        U5       H  u  pxUc  [        X   [        R                  5      n	X   n
U	(       a  U
R                  O[        R                  " U
5      nUSL=(       a    X'   S:H  nU(       a
  US   US   4OUS   4nUR                  U	(       a  [        R                  " U5      O[        R                  " U5      5        M  UR                  U5        M     [        U5      UU4$ )a  Adds 1.0 as sample weights for the outputs for which there is no weight.

Args:
  outputs: List of model outputs.
  sample_weights: List of sample weight inputs.
  sample_weight_modes: List of sample weight modes or None.
  check_all_flat: Ensure that inputs are not nested structures. This is not
    a free check, so we may not want to run it eagerly every iteration.

Returns:
  Tuple of sample weights, one sample weight for every output, and booleans
  describing the raw sample weights.
Nc              3   (   #    U  H  oS Lv   M
     g 7fr    r	   ws     r   r   0handle_partial_sample_weights.<locals>.<genexpr>O   s      ?
#1aTM>   c              3   (   #    U  H  oS L v   M
     g 7fr   r   r    s     r   r   r"   R   s      :
-!I~r#   temporalr   r   )r   r   tupler   r   nestassert_same_structurelist_to_tupleflatten	enumeratenpndarrayshapeappendones)outputssample_weightssample_weight_modescheck_all_flatany_sample_weightpartial_sample_weightnew_sample_weightsr   swas_numpyoutputoutput_shapeis_temporalsw_shapes                 r   handle_partial_sample_weightsr>   ;   s
     ntUm44*$6 1 Ln6L*$6 
3 ?
#1?
 <
 !2 !
c :
-:
 7
 &== 2GGG
%%.)"''//.9:	
 	%%'"M"''//'2J$K	
 *GG))#RWW__5H%I >*:!'*bjj9HZF+36<<&9IL $4/ 9'*j8   a,q/2"1o'  %%%-!27783D
 %%b)+ +. 	()     c                   *    \ rS rSrSrS rS rS rSrg)RespectCompiledTrainableState   a]  Set and restore trainable state if it has changed since compile.

The keras API guarantees that the value of each Layer's `trainable` property
at `Model.compile` time will be used when training that model. In order to
respect this requirement, it may be necessary to set the trainable value of
layers to their compile time values before beginning a training endpoint and
restore the values before returning from said endpoint. This scope checks if
any layer's trainable state has changed since Model compile, and performs
this set and un-set bookkeeping.

However, the trainable state of a layer changes quite infrequently, if ever,
for many kinds of workflows. Moreover, updating every layer in a model is an
expensive operation. As a result, we will only explicitly set and unset the
trainable state of a model if a trainable value has changed since compile.
c                 :    Xl         S U l        S U l        SU l        g NF)_model_current_trainable_state_compiled_trainable_state_should_set_trainable)selfmodels     r   __init__&RespectCompiledTrainableState.__init__   s    (,%)-&%*"r?   c                    U R                   R                  5       U l        U R                   R                  U l        U R                  R	                  5        H1  u  pXR                  ;   d  M  X R                  U   :w  d  M*  SU l          O   U R
                  (       a&  U R                   R                  U R                  5        g g )NT)rE   _get_trainable_staterF   rG   itemsrH   _set_trainable_state)rI   layer	trainables      r   	__enter__'RespectCompiledTrainableState.__enter__   s    (,(H(H(J%)-)N)N& !% > > D D FE666!>!>u!EE-1* !G %%KK,,T-K-KL &r?   c                 p    U R                   (       a%  U R                  R                  U R                  5        grD   )rH   rE   rP   rF   )rI   type_arg	value_argtraceback_args       r   __exit__&RespectCompiledTrainableState.__exit__   s(     %%KK,,T-J-JKr?   )rG   rF   rE   rH   N)	__name__
__module____qualname____firstlineno____doc__rK   rS   rY   __static_attributes__r   r?   r   rA   rA      s     +M$r?   rA   c                     S nU" U 5      (       a:  U R                   (       d  [        S5      eU R                   S   n U" U 5      (       a  M:  [        U SS5      (       a  U R                  U R                  4$ g)a2  Retrieves input shape and input dtype of layer if applicable.

Args:
  layer: Layer (or model) instance.

Returns:
  Tuple (input_shape, input_dtype). Both could be None if the layer
    does not have a defined input shape.

Raises:
  ValueError: in case an empty Sequential or Functional model is passed.
c                     [        U S5      =(       a    U R                  =(       d    U R                  R                  S:H  $ )N_is_graph_network
Sequential)hasattrrc   	__class__r[   )rQ   s    r   _is_graph_model2get_input_shape_and_dtype.<locals>._is_graph_model   s4    E./KE4K4K6__%%5	6r?   z)An empty Model cannot be used as a Layer.r   _batch_input_shapeN)NN)layers
ValueErrorgetattrri   dtype)rQ   rg   s     r   get_input_shape_and_dtypern      sk    6 %
 
 ||HIIQ %
 
 
 u*D11''44r?   c                     [        U 5      u  pUb6  [        R                  R                  R	                  US   5      R
                  $ g)zyGets the static batch size of a Layer.

Args:
  layer: a `Layer` instance.

Returns:
  The static batch size of a Layer.
Nr   )rn   r   compatv1	Dimensionvalue)rQ   batch_input_shape_s      r   get_static_batch_sizerv      s@     5U;$yy||%%&7&:;AAAr?   c                 F    [        U [        5      (       a  [        U 5      $ U $ )zADatasets will stack the list of tensor, so switch them to tuples.)r   r   r&   )
maybe_lists    r   r)   r)      s     *d##Z  r?   )T)F)r_   numpyr,   tensorflow.compat.v2rp   v2r   tf_keras.src.utilsr   r   r>   rA   rn   rv   r)   r   r?   r   <module>r}      sE    "  ! ! ,!J BGIX. .h@r?   