a
    Sic/5                     @   s  d Z ddlZddlZddlm  m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 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)generic_utils)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   U/var/www/html/django/DPS/env/lib/python3.9/site-packages/keras/saving/saving_utils.py
<dictcomp>4       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   s2   t | tjjrtd|  dtd|  dd S )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}|r0|}i }nt \}}|du rLt  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 sV0    Y   j}|du rd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      r   z<trace_model_call.<locals>._wrapped_model.<locals>.<dictcomp>)
_call_specset_arg_valuer   call_contextenteroutput_nameskeras.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   callr2   __internal__functionFunctioninput_signaturer   r#   get_concrete_function)r   r>   Z
model_argsmodel_kwargsr9   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y` } z|rL|W Y d}~n
d}~0 0 tt	|t

 |d}| jr
|r
t| jtjrtd nj| jr
| jd	d
}|dd t||d< t| j|jrtdnt| 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)r   rB   keras.optimizers.optimizer_v2rC   	__class____name__
get_configNotImplementedErrordictstrr   rI   r   r   TFOptimizerloggingwarning_compile_was_called_get_compile_argspop_serialize_nested_configRestoredOptimizerr   get_registered_name)
r   include_optimizerrequire_configrF   rC   rG   emetadatarJ   rK   r   r   r   model_metadata   sF    
r`   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    rf   c                 C   s   |du ri }t | | d }t|}d}| dd}|durNttj|}d}| dd}|durptt|}d}| dd}	|	durtt|	}t| dr| d nd}
| d }W d   n1 s0    Y  t	||||||
dS )	z4Return model.compile arguments from training config.NrK   lossmetricsweighted_metricssample_weight_modeloss_weights)rI   rg   rh   ri   rk   rj   )
r   CustomObjectScoper   deserializeget_deserialize_nested_configr   _deserialize_metrichasattrrQ   )rJ   custom_objectsrK   rI   rg   loss_configrh   metrics_configri   weighted_metrics_configrj   rk   r   r   r   !compile_args_from_training_config   sD    

&rv   c                    sx   dd }|du rdS ||r$ |S t |trD fdd| D S t |ttfrd fdd|D S td| d	dS )
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   rQ   rR   objr   r   r   _is_single_object  s
    
z5_deserialize_nested_config.<locals>._is_single_objectNc                    s   i | ]\}}|t  |qS r   ro   )r   kvdeserialize_fnr   r   r      s   z._deserialize_nested_config.<locals>.<dictcomp>c                    s   g | ]}t  |qS r   rz   )r   rx   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   rQ   itemstuplelistr"   )r~   rE   ry   r   r}   r   ro     s$    


ro   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_objectrw   r   r   r   _serialize_fn2  s    
z/_serialize_nested_config.<locals>._serialize_fn)r2   r3   map_structure)rE   r   r   r   r   rY   /  s    rY   c                 C   s"   ddl m} | dv r| S || S )z7Deserialize metrics, leaving special strings untouched.r   )rh   )accuracyacccrossentropyce)r   rh   rm   )metric_configmetrics_moduler   r   r   rp   :  s    rp   c                    s`   dd  dd }t j| }t fdd|D oHt 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   )rq   r   specr   r   r   	_has_nameI  s    z-_enforce_names_consistency.<locals>._has_namec                 S   s   t | } t| drd | _| S r   )copydeepcopyrq   _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  r   z-_enforce_names_consistency.<locals>.<genexpr>)r2   r3   r4   anyallr   )specsr   
flat_specsname_inconsistencyr   r   r   r   F  s    "
r   c                 C   sd   t | s`| jd ur`z4| jjs,| j| j | jjsF| j| j| j W n   td Y n0 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_modelr8   compiled_lossbuiltbuildcompiled_metricsrT   rU   r   r   r   r   try_build_compiled_arguments\  s    r   c                 C   s   |  dp|  dp|  dS )Nz.h5z.kerasz.hdf5)endswith)rd   r   r   r   is_hdf5_filepathn  s
    
r   )F)N)TT)N)$__doc__r   ra   tensorflow.compat.v2compatv2r2   r   r   r   r   r0   r   Zkeras.optimizersr   keras.utilsr   r   Zkeras.utils.io_utilsr	   tensorflow.python.platformr
   rT   r   r   r#   rA   r`   rf   rv   ro   rY   rp   r   r   r   r   r   r   r   <module>   s4   

4
8
0