
    BVh0                         d Z ddlZddlZddl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 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 ZddZd ZddZddZd ZddZd Zd Z d Z!d Z"d Z#d Z$y)z$Utils related to keras model saving.    N)def_function)backend)losses)optimizer_v1)
optimizers)base_layer_utils)generic_utils)version_utils)ask_to_proceed_with_overwrite)
tf_logging)nestc                 r    t        | dd      r%| j                  D ci c]  }|j                  | c}S yc c}w )a3  Convert metrics from a Keras model `compile` API to dictionary.

  This is used for converting Keras models to SavedModels.

  Args:
    model: A `tf.keras.Model` object.

  Returns:
    Dictionary mapping metric names to metric instances. May return `None` if
    the model does not contain any metrics.
  _compile_metricsN)getattr_compile_metric_functionsname)modelms     [/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/keras/saving/saving_utils.pyextract_model_metricsr   "   s;     U&-  %>>?!AFFAI??	 @s   4c                     | j                  |       }|yt        |      }t        |t        j                  j
                        rt        |      dk(  r|S |gS )aM  Inspect model to get its input signature.

  The model's input signature is a list with a single (possibly-nested) object.
  This is due to the Keras-enforced restriction that tensor inputs must be
  passed in as the first argument.

  For example, a model with input {'feature1': <Tensor>, 'feature2': <Tensor>}
  will have input signature: [{'feature1': TensorSpec, 'feature2': TensorSpec}]

  Args:
    model: Keras Model object.
    keep_original_batch_size: A boolean indicating whether we want to keep using
      the original batch size or set it to None. Default is `False`, which means
      that the batch dim of the returned input signature will always be set to
      `None`.

  Returns:
    A list containing either a single TensorSpec or an object with nested
    TensorSpecs. This list does not contain the `training` argument.
  )dynamic_batchN   )_get_save_spec_enforce_names_consistency
isinstancecollectionsabcSequencelen)r   keep_original_batch_sizeinput_specss      r   model_input_signaturer#   5   sb    * $$7O3O$P+*;7+((*.1+.>!.C =    c                 6    t        dj                  |             )NzModel {} cannot be saved because the input shapes have not been set. Usually, input shapes are automatically determined from calling `.fit()` or `.predict()`. To manually set the shapes, call `model.build(input_shape)`.)
ValueErrorformatr   s    r   raise_model_input_errorr)   X   s    $ %+F5M		3 3r$   c                      :t         j                  t        j                        r j                  j                  t               t                t        j                         fd       }|S )a  Trace the model call to create a tf.function for exporting a Keras model.

  Args:
    model: A Keras model.
    input_signature: optional, a list of tf.TensorSpec objects specifying the
      inputs to the model.

  Returns:
    A tf.function wrapping the model's call function with input signatures set.

  Raises:
    ValueError: if input signature cannot be inferred from the model.
  )input_signaturec                     t              dk(  r| d   n
t        |       }t        j                         j	                  |ddd      5   |d      }ddd       j
                  }|ddlm} |j                        }t        j                        }t        ||      D ci c]  \  }}||
 c}}S # 1 sw Y   cxY wc c}}w )	z<A concrete tf.function that wraps the model's call function.r   r   FT)inputsbuild_graphtrainingsaving)r/   N)compile_utils)r    listr   call_contextenteroutput_namestensorflow.python.keras.enginer1   create_pseudo_output_namesr   flattenzip)	argsr-   outputsr5   r1   r   outputr+   r   s	          r   _wrapped_modelz(trace_model_call.<locals>._wrapped_modelx   s    
 O,1T!WtDzF		&	&	(	.	.f%% 
/ 
N .fu-g.
 %%L>"==gFlll7#G-0w-GH\T6D&LHH. . Is   B5$C5B>)r   callr   Functionr+   r#   r)   function)r   r+   r=   s   `` r   trace_model_callrA   `   ss     %**l334

22o+E2OE"9I :I$ 
r$   c                    ddl m} ddlm} d| j                  j
                  i}	 | j                         |d<   t        t        |      t        j                         |      }| j                  r|rt        | j                  t        j                        rt!        j"                  d       |S | j$                  r| j'                  d	
      }|j)                  dd       t+        |      |d<   t        | j                  |j,                        rt        d      t/        j0                  | j                  j                        | j                  j                         d}	|	|d   d<   |S # t        $ r}|r|Y d}~<d}~ww xY w)z3Returns a dictionary containing the model metadata.r   )__version__)optimizer_v2
class_nameconfigN)keras_versionr   model_configa<  TensorFlow optimizers do not make it possible to access optimizer attributes or optimizer state after instantiation. As a result, we cannot save the optimizer as part of the model save file. You will have to compile your model again after loading it. Prefer using a Keras optimizer instead (see keras.io/optimizers).F)user_metrics	optimizertraining_configzAs of now, Optimizers loaded from SavedModel cannot be saved. If you're calling `model.save` or `tf.keras.models.save_model`, please set the `include_optimizer` option to `False`. For `tf.saved_model.save`, delete the optimizer from the model.)rE   rF   optimizer_config)tensorflow.python.kerasrC   $tensorflow.python.keras.optimizer_v2rD   	__class____name__
get_configNotImplementedErrordictstrKr   rJ   r   r   TFOptimizerloggingwarning_compile_was_called_get_compile_argspop_serialize_nested_configRestoredOptimizerr	   get_registered_name)
r   include_optimizerrequire_configrG   rD   rH   emetadatarK   rL   s
             r   model_metadatarc      s^   B? 8 89,"--/L
 &iik!( __*%//<#;#;<oo'	(8 
/% 
	"	"//U/Co+t,$<_$Mh !	EOO\%C%C	D!JK 	K 11%//2K2KL**,	
 9Ih !"45	/M 
 g s   E" "	E:+E55E:c                 \    |s*t         j                  j                  |       rt        |       S y)z3Returns whether the filepath should be overwritten.T)ospathisfiler   )filepath	overwrites     r   should_overwriterj      s$     
rww~~h/(22	r$   c                    |i }t        j                  |      5  | d   }t        j                  |      }d}| j	                  dd      }|t        t        j                  |      }d}| j	                  dd      }|t        t        |      }d}| j	                  dd      }	|	t        t        |	      }t        | d      r| d   nd}
| d   }ddd       t        
      S # 1 sw Y   xY w)	z4Return model.compile arguments from training config.NrL   lossmetricsweighted_metricssample_weight_modeloss_weights)rJ   rl   rm   rn   rp   ro   )
r	   CustomObjectScoper   deserializeget_deserialize_nested_configr   _deserialize_metrichasattrrS   )rK   custom_objectsrL   rJ   rl   loss_configrm   metrics_configrn   weighted_metrics_configro   rp   s               r   !compile_args_from_training_configr{      s,   N&&~6 3&'9:&&'78I D!%%fd3K'(:(:KHd G$((D9N!*+>Og -112DdK*34G4KM CJ-C/)=>48 ">2L336 
'+
- -73 3s   B/C""C+c           	      6   d }|y ||      r | |      S t        |t              r.|j                         D ci c]  \  }}|t        | |       c}}S t        |t        t
        f      r|D cg c]  }t        | |       c}S t        d      c c}}w c c}w )z=Deserializes arbitrary Keras `config` using `deserialize_fn`.c                 P    t        | t              rd| v ryt        | t              ryy)NrE   TF)r   rS   rT   objs    r   _is_single_objectz5_deserialize_nested_config.<locals>._is_single_object   s&    #t!4#sr$   Nz#Saved configuration not understood.)r   rS   itemsrt   tupler2   r&   )deserialize_fnrF   r   kvr   s         r   rt   rt      s     ^v&!!&$ LLNAq 	
%na88  &5$-(GMN&~s;NN899
 Os   B/Bc                 4    d }t        j                  ||       S )z/Serialized a nested structure of Keras objects.c                 F    t        |       rt        j                  |       S | S N)callabler	   serialize_keras_objectr~   s    r   _serialize_fnz/_serialize_nested_config.<locals>._serialize_fn  s    }11#66Jr$   )r   map_structure)rF   r   s     r   r\   r\   	  s    
 
		M6	22r$   c                 <    ddl m} | dv r| S |j                  |       S )z7Deserialize metrics, leaving special strings untouched.r   )rm   )accuracyacccrossentropyce)rM   rm   rr   )metric_configmetrics_modules     r   ru   ru     s'    ??? 		#	#M	22r$   c                     d d }t        j                  |       }t        fd|D              xr t        fd|D               }|rt        j                  ||       } | S )z5Enforces that either all specs have names or none do.c                 :    t        | d      xr | j                  d uS Nr   )rv   r   specs    r   	_has_namez-_enforce_names_consistency.<locals>._has_name!  s    4 :TYYd%::r$   c                 V    t        j                  |       } t        | d      rd | _        | S r   )copydeepcopyrv   _namer   s    r   _clear_namez/_enforce_names_consistency.<locals>._clear_name$  s&    ==DtVdjKr$   c              3   .   K   | ]  } |        y wr    .0sr   s     r   	<genexpr>z-_enforce_names_consistency.<locals>.<genexpr>,  s     	+1)A,	+   c              3   .   K   | ]  } |        y wr   r   r   s     r   r   z-_enforce_names_consistency.<locals>.<genexpr>-  s     /qil/r   )r   r8   anyallr   )specsr   
flat_specsname_inconsistencyr   s       @r   r   r     sb    ; ||E"*		+
	++ 0
/J/
//  {E2E	,r$   c                    t        j                  |       s| j                  	 | j                  j                  s%| j                  j                  | j                         | j                  j                  s1| j                  j                  | j                  | j                         y y y y #  t        j                  d       Y y xY w)NzCompiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.)	r
   is_v1_layer_or_modelr;   compiled_lossbuiltbuildcompiled_metricsrW   rX   r(   s    r   try_build_compiled_argumentsr   4  s    

,
,U
3mm	$  &&!!%--0##))$$U]]EMMB *	   4$oo#$s   BB( (Cc                 p    | j                  d      xs$ | j                  d      xs | j                  d      S )Nz.h5z.kerasz.hdf5)endswith)rh   s    r   is_hdf5_filepathr   C  s:    


E
" %h&7&7&A %


G
$&r$   )Fr   )TT)%__doc__r   r   re   tensorflow.python.eagerr   rM   r   rU   r   r   r   r6   r   tensorflow.python.keras.utilsr	   r
   &tensorflow.python.keras.utils.io_utilsr   tensorflow.python.platformr   rW   tensorflow.python.utilr   r   r#   r)   rA   rc   rj   r{   rt   r\   ru   r   r   r   r   r$   r   <module>r      sy    +   	 0 0 * 0 . ; 7 7 P < '& F3+\.b&-R:233,$&r$   