o
    i ek5                     @   s  d Z ddlZddlZddlm  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d Zd(ddZdd Zd)ddZd*ddZdd Zd)ddZ dd Z!dd Z"d d! Z#d"d# Z$d$d% Z%d&d' Z&dS )+z$Utils related to keras model saving.    N)backend)losses)
optimizers)base_layer_utils)optimizer_v1)serialization)version_utils)ask_to_proceed_with_overwrite)
tf_loggingc                 C   s    t | ddrdd | jD S dS )aP  Convert metrics from a Keras model `compile` API to dictionary.

    This is used for converting Keras models to Estimators and 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_metricsNc                 S   s   i | ]}|j |qS  )name).0mr   r   S/var/www/myenv/lib/python3.10/site-packages/keras/src/saving/legacy/saving_utils.py
<dictcomp>4   s    z)extract_model_metrics.<locals>.<dictcomp>)getattr_compile_metric_functionsmodelr   r   r   extract_model_metrics$   s   r   Fc                 C   s&   | j | d}|du rdS t|}|S )at  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 tuple containing `(args, kwargs)` TensorSpecs of the model call function
      inputs.
      `kwargs` does not contain the `training` argument.
    )dynamic_batchN)NN)	save_spec_enforce_names_consistency)r   keep_original_batch_sizeinput_specsr   r   r   model_call_inputs8   s
   r   c                 C   s.   t | tjjrtd|  dtd|  d)NzModel z cannot be saved because the input shape is not available. Please specify an input shape either by calling `build(input_shape)` directly, or by calling the model on actual data using `Model()`, `Model.fit()`, or `Model.predict()`.a   cannot be saved either because the input shape is not available or because the forward pass of the model is not defined.To define a forward pass, please override `Model.call()`. To specify an input shape, either call `build(input_shape)` directly, or call the model on actual data using `Model()`, `Model.fit()`, or `Model.predict()`. If you have a custom training step, please make sure to invoke the forward pass in train step through `Model.__call__`, i.e. `model(inputs)`, as opposed to `model.call()`.)
isinstancekerasmodels
Sequential
ValueErrorr   r   r   r   raise_model_input_errorV   s   
	
r"   c                    sn   |du rt  jtjjjr jj}|r|}i }nt \}}|du r&t  tj fdd}|j	|i |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.
    Nc                     s    j jdd| |dd\} }t j ddddd  | i |}W d   n1 s+w   Y   j}|du rBddlm} ||}t	j
|}d	d
 t||D S )z<A concrete tf.function that wraps the model's call function.trainingFT)inputs_in_argsN)inputsbuild_graphr#   savingr   )compile_utilsc                 S   s   i | ]\}}||qS r   r   )r   r   outputr   r   r   r      s    z<trace_model_call.<locals>._wrapped_model.<locals>.<dictcomp>)
_call_specset_arg_valuer   call_contextenteroutput_nameskeras.src.enginer(   create_pseudo_output_namestfnestflattenzip)argskwargsoutputsr.   r(   r   r   r   _wrapped_model   s   



z(trace_model_call.<locals>._wrapped_model)
r   callr1   __internal__functionFunctioninput_signaturer   r"   get_concrete_function)r   r=   
model_argsmodel_kwargsr8   r   r   r   trace_model_callm   s   rA   Tc           
   
   C   s
  ddl m} ddlm} d| jji}z|  |d< W n ty0 } z
|r&|W Y d}~nd}~ww tt	|t

 |d}| jr|rt| jtjrOtd |S | jr| jd	d
}|dd t||d< t| j|jrotdtj| jj| j d}	|	|d d< |S )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_configzOptimizers loaded from a SavedModel cannot be saved. If you are 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.)rD   rE   optimizer_config)	keras.srcrB   keras.src.optimizers.legacyrC   	__class____name__
get_configNotImplementedErrordictstrr   rI   r   r   TFOptimizerloggingwarning_compile_was_called_get_compile_argspop_serialize_nested_configRestoredOptimizerr   utilsget_registered_name)
r   include_optimizerrequire_configrF   rC   rG   emetadatarJ   rK   r   r   r   model_metadata   sN   
"
rb   c                 C   s   |st j| rt| S dS )z3Returns whether the filepath should be overwritten.T)ospathisfiler	   )filepath	overwriter   r   r   should_overwrite   s   rh   c                 C   s   |du ri }t j|T | d }t|}d}| dd}|dur(ttj|}d}| dd}|dur9tt|}d}| dd}	|	durJtt|	}t	| drS| d nd}
| d }W d   n1 scw   Y  t
||||||
dS )	z4Return model.compile arguments from training config.NrK   lossmetricsweighted_metricssample_weight_modeloss_weights)rI   ri   rj   rk   rm   rl   )r   r\   CustomObjectScoper   deserializeget_deserialize_nested_configr   _deserialize_metrichasattrrR   )rJ   custom_objectsrK   rI   ri   loss_configrj   metrics_configrk   weighted_metrics_configrl   rm   r   r   r   !compile_args_from_training_config   sF   


!rx   c                    st   dd }|du r
dS ||r |S t |tr" fdd| D S t |ttfr2 fdd|D S td| d	)
z=Deserializes arbitrary Keras `config` using `deserialize_fn`.c                 S   s(   t | trd| v rdS t | trdS dS )NrD   TF)r   rR   rS   objr   r   r   _is_single_object  s
   
z5_deserialize_nested_config.<locals>._is_single_objectNc                    s   i | ]
\}}|t  |qS r   rq   )r   kvdeserialize_fnr   r   r      s    
z._deserialize_nested_config.<locals>.<dictcomp>c                    s   g | ]}t  |qS r   r|   )r   rz   r   r   r   
<listcomp>%  s    
z._deserialize_nested_config.<locals>.<listcomp>zrSaved configuration not understood. Configuration should be a dictionary, string, tuple or list. Received: config=.)r   rR   itemstuplelistr!   )r   rE   r{   r   r   r   rq     s$   


rq   c                 C   s   dd }t j|| S )z/Serialized a nested structure of Keras objects.c                 S   s   t | r	t| S | S N)callabler   serialize_keras_objectry   r   r   r   _serialize_fn2  s   
z/_serialize_nested_config.<locals>._serialize_fn)r1   r2   map_structure)rE   r   r   r   r   rZ   /  s   rZ   c                 C   s"   ddl m} | dv r| S || S )z7Deserialize metrics, leaving special strings untouched.r   )rj   )accuracyacccrossentropyce)rL   rj   ro   )metric_configmetrics_moduler   r   r   rr   :  s   
rr   c                    s`   dd  dd }t j| }t fdd|D o$t fdd|D  }|r.t j|| } | S )z5Enforces that either all specs have names or none do.c                 S   s   | d u pt | do| jd uS Nr   )rs   r   specr   r   r   	_has_nameI  s   z-_enforce_names_consistency.<locals>._has_namec                 S   s   t | } t| drd | _| S r   )copydeepcopyrs   _namer   r   r   r   _clear_nameL  s   

z/_enforce_names_consistency.<locals>._clear_namec                 3   s    | ]} |V  qd S r   r   )r   sr   r   r   	<genexpr>S  s    z-_enforce_names_consistency.<locals>.<genexpr>)r1   r2   r3   anyallr   )specsr   
flat_specsname_inconsistencyr   r   r   r   F  s   "
r   c                 C   sp   t | s4| jd ur6z| jjs| j| j | jjs&| j| j| j W d S W d S    td Y d S d S d S )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_modelr7   compiled_lossbuiltbuildcompiled_metricsrU   rV   r   r   r   r   try_build_compiled_arguments\  s   

r   c                 C   s   |  dp|  dp|  dS )Nz.h5z.kerasz.hdf5)endswith)rf   r   r   r   is_hdf5_filepathn  s
   
r   )Fr   )TT)'__doc__r   rc   tensorflow.compat.v2compatv2r1   rL   srcr   r   r   r   r/   r   keras.src.optimizersr   keras.src.saving.legacyr   keras.src.utilsr   keras.src.utils.io_utilsr	   tensorflow.python.platformr
   rU   r   r   r"   rA   rb   rh   rx   rq   rZ   rr   r   r   r   r   r   r   r   <module>   s6   


48
0