a
    Sic                     @   sL  d Z ddl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 zddlZdZW n ey   dZY n0 ede  dZ!d-ddZ"d.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"d# Z+d0d%d&Z,d'd( Z-d)d* Z.d+d, Z/dS )1z@Functions for saving and loading a Keras Model from HDF5 format.    N)backend)optimizer_v1)	optimizer)model_config)saving_utils)
json_utils)
LazyLoader)ask_to_proceed_with_overwrite)
tf_loggingi   sequential_libzkeras.engine.sequentialTc                 C   s|  t du rtdt| jt| jkr.td t|t js|sZt	j
|rZt|}|sZdS t	j
|}t	j
|stjj| t j|dd}d}n|}d}zt| |}| D ]@\}	}
t|
tttfrtj|
tjdd	|j|	< q|
|j|	< q|d
}t ||  t| j!t"j#r$td n*|rN| j!rNt| j!t$j%sNt&|| j! |'  W |rx|(  n|rv|(  0 dS )a@  Saves a model to a HDF5 file.

    The saved model contains:
        - the model's configuration (topology)
        - the model's weights
        - the model's optimizer's state (if any)

    Thus the saved model can be reinstantiated in
    the exact same state, without any of the code
    used for model definition or training.

    Args:
        model: Keras model instance to be saved.
        filepath: One of the following:
            - String, path where to save the model
            - `h5py.File` object where to save the model
        overwrite: Whether we should overwrite any existing
            model at the target location, or instead
            ask the user with a manual prompt.
        include_optimizer: If True, save optimizer's state together.

    Raises:
        ImportError: if h5py is not available.
    NzD`save_model()` using h5 format requires h5py. Could not import h5py.a  Found duplicated `Variable`s in Model's `weights`. This is usually caused by `Variable`s being shared by Layers in the Model. These `Variable`s will be treated as separate `Variable`s when the Model is restored. To avoid this, please save with `save_format="tf"`.wmodeTF)defaultutf8model_weightsz{HDF5 format does not save weights of `optimizer_experimental.Optimizer`, your optimizer will be recompiled at loading time.))h5pyImportErrorlenweights_undeduplicated_weightsloggingwarning
isinstanceFileospathisfiler	   dirnameexiststfiogfilemakedirsr   model_metadataitemsdictlisttuplejsondumpsr   get_json_typeencodeattrscreate_groupsave_weights_to_hdf5_groupr   optimizer_experimental	Optimizerr   TFOptimizer$save_optimizer_weights_to_hdf5_groupflushclose)modelfilepath	overwriteinclude_optimizerproceeddirpathfopened_new_filer$   kvmodel_weights_group rA   T/var/www/html/django/DPS/env/lib/python3.9/site-packages/keras/saving/hdf5_format.pysave_model_to_hdf55   s`    



rC   c           	   	   C   s  t du rtd|si }t| t j }|r:t j| dd}n| }d}z|jd}|du rjtd|  dt|dr~|d	}t	|}t
j||d
}t|d | |r|jd}t|dr|d	}|du rtd |W |r|  S t	|}|jf i t||ddi t| t|jtjr>td nxd|v rz|j|j W n" ttfy|   td Y n0 t|}z|j| W n ty   td Y n0 W |r|  n|r|  0 |S )av  Loads a model saved via `save_model_to_hdf5`.

    Args:
        filepath: One of the following:
            - String, path to the saved model
            - `h5py.File` object from which to load the model
        custom_objects: Optional dictionary mapping names
            (strings) to custom classes or functions to be
            considered during deserialization.
        compile: Boolean, whether to compile the model
            after loading.

    Returns:
        A Keras model instance. If an optimizer was found
        as part of the saved model, the model is already
        compiled. Otherwise, the model is uncompiled and
        a warning will be displayed. When `compile` is set
        to False, the compilation is omitted without any
        warning.

    Raises:
        ImportError: if h5py is not available.
        ValueError: In case of an invalid savefile.
    NzD`load_model()` using h5 format requires h5py. Could not import h5py.rr   r   z%No model config found in the file at .decodezutf-8)custom_objectsr   training_configzgNo training configuration found in the save file, so the model was *not* compiled. Compile it manually.from_serializedTzLoading model from HDF5 will not restore the optimizer's weights, since the optimizer is an instance of `optimizer_experimental.Optimizer`optimizer_weightszError when creating the weights of optimizer {}, making it impossible to restore the saved optimizer state. As a result, your model is starting with a freshly initialized optimizer.zuError in loading the saved optimizer state. As a result, your model is starting with a freshly initialized optimizer.)r   r   r   r   r-   get
ValueErrorhasattrrF   r   model_config_libmodel_from_configload_weights_from_hdf5_groupr   r   r5   compiler   !compile_args_from_training_configtry_build_compiled_argumentsr   r0   r1   _create_all_weightstrainable_variablesNotImplementedErrorAttributeError&load_optimizer_weights_from_hdf5_groupset_weights)	r7   rG   rQ   r=   r<   r6   r   rH   optimizer_weight_valuesrA   rA   rB   load_model_from_hdf5   s    





-





r[   c                    s4   fdd} fdd} fdd} j jdkrD||} j jdkrZ||}n j jd	v rn||}d
kr j jdkrt j|} j jdkr>|d j}|dd  jd dfks|d  jkr|d  jkr|dd  jd dfksJ t|d d|d< |d dddddddf |d<  j jdkrl j	dkrlt|d d|d<  j jdkr j	dkrt|d d|d<  j	dkrt|d d|d<  j jdkr j	dkrt|d d|d<  j jdkrnt
|dkrntj|d |d |d gdd}tj|d |d |d  gdd}	tj|d |d! |d" gdd}
||	|
g} j jd#krt
|d$krtj|d |d |d |d gdd}tj|d |d  |d |d% gdd}	tj|d |d" |d! |d& gdd}
||	|
g} j jd'krt
|d$krtj|d |d |d |d gdd}tj|d |d  |d |d% gdd}	tj|d |d" |d! |d& gdd}
 j	dkrt|d}t|	d}	||	|
g}g d(} j j|v r*t jd |d jkr*t|d d)|d<  j jd'kr*t|d d)|d< t |S )*a  Preprocess layer weights between different Keras formats.

    Converts layers weights from Keras 1 format to Keras 2 and also weights of
    cuDNN layers in Keras 2.

    Args:
        layer: Layer instance.
        weights: List of weights values (Numpy arrays).
        original_keras_version: Keras version for the weights, as a string.
        original_backend: Keras backend the weights were trained with,
            as a string.

    Returns:
        A list of weights values (Numpy arrays).
    c                    sD   t | d }t j| d| }t j| |d }|| S )a+  Converts layers nested in `Bidirectional` wrapper.

        This function uses `preprocess_weights_for_loading()` for converting
        layers.

        Args:
            weights: List of weights values (Numpy arrays).

        Returns:
            A list of weights values (Numpy arrays).
           N)r   preprocess_weights_for_loadingforward_layerbackward_layer)r   num_weights_per_layerforward_weightsbackward_weightslayeroriginal_backendoriginal_keras_versionrA   rB   convert_nested_bidirectional  s    

zDpreprocess_weights_for_loading.<locals>.convert_nested_bidirectionalc                    s   t  j| S )a4  Converts layers nested in `TimeDistributed` wrapper.

        This function uses `preprocess_weights_for_loading()` for converting
        nested layers.

        Args:
            weights: List of weights values (Numpy arrays).

        Returns:
            A list of weights values (Numpy arrays).
        )r]   rd   )r   rc   rA   rB   convert_nested_time_distributed9  s    
zGpreprocess_weights_for_loading.<locals>.convert_nested_time_distributedc           	         s   | dt  j }| t  jd }g }g } jD ]~}t |j}t |j}|jr2t||d| |d|  d}||d|  |||d  ||d }||d }q2| j7 }| j7 }|| S )a2  Converts layers nested in `Model` or `Sequential`.

        This function uses `preprocess_weights_for_loading()` for converting
        nested layers.

        Args:
            weights: List of weights values (Numpy arrays).

        Returns:
            A list of weights values (Numpy arrays).
        N)rd   r   rf   re   )	r   trainable_weightslayersnon_trainable_weightsr   r]   extend_trainable_weights_non_trainable_weights)	r   ri   rk   new_trainable_weightsnew_non_trainable_weightssublayernum_trainable_weightsnum_non_trainable_weightspreprocessedrc   rA   rB   convert_nested_modelI  s:    




	



z<preprocess_weights_for_loading.<locals>.convert_nested_modelBidirectionalTimeDistributed)Model
Sequential
Functional1Conv1Dr   Nr\         )r\   r~   r}   r   Conv2Dchannels_firstConv2DTransposechannels_last)r   r}   r~   r\   )r\   r~   r   r}   Conv3D)r\   r~      r}   r   GRU	      axisr            LSTM   
      
ConvLSTM2D)r|   r   r   r   r   )r~   r\   r   r}   )	__class____name__r]   rd   shapekernel_sizefiltersnp	transposedata_formatr   concatenater   	int_shaper   _convert_rnn_weights)rd   r   rf   re   rg   rh   ru   r   kernelrecurrent_kernelbiasconv_layersrA   rc   rB   r]     s    1



$


r]   c           
         s  dd dd | j j}|dv rt|dkr|d jd }|d	 j}d
 |d	|   fkr`d}n$||  fkrtd}ntdt| d fdd	}||kr|||dkd}|dv rt|dkr|d jd }|d	 j}d d fdd	}|d	|   fkrd}n>|d	|  fkr&d}n&||  fkr<d}ntdt| |dkr\d}n| jrjd}nd}||kr||f}	d|	v rtd|	 |dkr||dd}n|dkr||dd}|S )al  Converts weights for RNN layers between native and cuDNN format.

    Input kernels for each gate are transposed and converted between Fortran
    and C layout, recurrent kernels are transposed. For LSTM biases are summed/
    split in half, for GRU biases are reshaped.

    Weights can be converted in both directions between `LSTM` and`CuDNNSLTM`
    and between `CuDNNGRU` and `GRU(reset_after=True)`. Default `GRU` is not
    compatible with `CuDNNGRU`.

    For missing biases in `LSTM`/`GRU` (`use_bias=False`) no conversion is made.

    Args:
        layer: Target layer instance.
        weights: List of source weights values (input kernels, recurrent
          kernels, [biases]) (Numpy arrays).

    Returns:
        A list of converted weights values (Numpy arrays).

    Raises:
        ValueError: for incompatible GRU layer/weights or incompatible biases
    c                    s    t  fddt | |D S )aY  Transforms kernel for each gate separately using given function.

        Args:
            kernels: Stacked array of kernels for individual gates.
            func: Function applied to kernel of each gate.
            n_gates: Number of gates (4 for LSTM, 3 for GRU).

        Returns:
            Stacked array of transformed kernels.
        c                    s   g | ]} |qS rA   rA   ).0r>   funcrA   rB   
<listcomp>      zC_convert_rnn_weights.<locals>.transform_kernels.<locals>.<listcomp>)r   hstackhsplit)kernelsr   n_gatesrA   r   rB   transform_kernels  s    z/_convert_rnn_weights.<locals>.transform_kernelsc                    s   | rdnd  fdd}|S )a@  Makes a function that transforms input kernels from/to cuDNN format.

        It keeps the shape, but changes between the layout (Fortran/C). Eg.:

        ```
        Keras                 cuDNN
        [[0, 1, 2],  <--->  [[0, 2, 4],
         [3, 4, 5]]          [1, 3, 5]]
        ```

        It can be passed to `transform_kernels()`.

        Args:
            from_cudnn: `True` if source weights are in cuDNN format, `False` if
              they're in plain Keras format.

        Returns:
            Function that converts input kernel to the other format.
        FCc                    s   | j j| j dS )Norder)Treshaper   )r   r   rA   rB   	transform*  s    z@_convert_rnn_weights.<locals>.transpose_input.<locals>.transformrA   )
from_cudnnr   rA   r   rB   transpose_input  s    z-_convert_rnn_weights.<locals>.transpose_input)r   	CuDNNLSTMr~   r}   r   r\   r   r   r   zInvalid bias shape: Tc                    sj   | d | }| d dd  }|rLt jt j| d ddddd}nt d| d  d}|||gS )a&  Converts the weights between CuDNNLSTM and LSTM.

            Args:
              weights: Original weights.
              from_cudnn: Indicates whether original weights are from cuDNN
                layer.

            Returns:
              Updated weights compatible with LSTM.
            r   r}   c                 S   s   | j S Nr   r>   rA   rA   rB   <lambda>S  r   zD_convert_rnn_weights.<locals>.convert_lstm_weights.<locals>.<lambda>r\   r   g      ?)r   sumsplittiler   r   r   recurrent_kernelsbiasesr   r   r   rA   rB   convert_lstm_weightsB  s     z2_convert_rnn_weights.<locals>.convert_lstm_weights)r   )r   CuDNNGRUc                    sN   | d | }| d dd  }t | d |r>dnd}|||gS )a#  Converts the weights between CuDNNGRU and GRU.

            Args:
              weights: Original weights.
              from_cudnn: Indicates whether original weights are from cuDNN
                layer.

            Returns:
              Updated weights compatible with GRU.
            r   r}   c                 S   s   | j S r   r   r   rA   rA   rB   r   }  r   zC_convert_rnn_weights.<locals>.convert_gru_weights.<locals>.<lambda>r\   )r\   r   r   )r   arrayr   r   r   rA   rB   convert_gru_weightsm  s    z1_convert_rnn_weights.<locals>.convert_gru_weightsr   zGRU(reset_after=True)zGRU(reset_after=False)z%s is not compatible with %sF)T)T)r   r   r   r   rL   strreset_after)
rd   r   target_classunits
bias_shapesourcer   r   targettypesrA   r   rB   r     sV    






r   c           	      C   s   t |d}|r| d}dd |D }t|d| t|}t||D ]8\}}|j||j|jd}|jsr||d< qF||dd< qFdS )	zSaves optimizer weights of a optimizer to a HDF5 group.

    Args:
        hdf5_group: HDF5 group.
        optimizer: optimizer instance.
    r   rJ   c                 S   s   g | ]}t |jd qS r   )r   namer,   r   r   rA   rA   rB   r     r   z8save_optimizer_weights_to_hdf5_group.<locals>.<listcomp>weight_namesdtyperA   N)	getattrr.   save_attributes_to_hdf5_groupr   batch_get_valuezipcreate_datasetr   r   )	
hdf5_groupr   symbolic_weightsweights_groupr   weight_valuesr   val
param_dsetrA   rA   rB   r3     s    




r3   c                    s$   | d  t  d} fdd|D S )zLoad optimizer weights from a HDF5 group.

    Args:
        hdf5_group: A pointer to a HDF5 group.

    Returns:
        data: List of optimizer weight names.
    rJ   r   c                    s   g | ]} | qS rA   rA   r   weight_namer   rA   rB   r     s   z:load_optimizer_weights_from_hdf5_group.<locals>.<listcomp>load_attributes_from_hdf5_group)r   optimizer_weight_namesrA   r   rB   rX     s    	
rX   c                 C   sl   t |}dd |D }t| d| t||D ]8\}}| j||j|jd}|jsZ||d< q.||dd< q.dS )zSave top-level weights of a model to a HDF5 group.

    Args:
        f: HDF5 group.
        weights: List of weight variables.
    c                 S   s   g | ]}|j d qS r   r   r,   r   rA   rA   rB   r     r   z5save_subset_weights_to_hdf5_group.<locals>.<listcomp>r   r   rA   N)r   r   r   r   r   r   r   )r<   r   r   r   r   r   r   rA   rA   rB   !save_subset_weights_to_hdf5_group  s    

r   c                 C   s   ddl m} t| ddd |jD  t d| jd< t|d| jd< t|jd	d
 dD ]"}| 	|j
}t|}t|| q^|j|j }| 	d}t|| dS )z|Saves the weights of a list of layers to a HDF5 group.

    Args:
        f: HDF5 group.
        model: Model instance.
    r   )__version__layer_namesc                 S   s   g | ]}|j d qS r   r   )r   rd   rA   rA   rB   r     r   z.save_weights_to_hdf5_group.<locals>.<listcomp>r   r   keras_versionc                 S   s   | j S r   )r   )xrA   rA   rB   r     r   z,save_weights_to_hdf5_group.<locals>.<lambda>)keytop_level_model_weightsN)kerasr   r   rj   r   r,   r-   r   sortedr.   r   _legacy_weightsr   rm   rn   )r<   r6   r   rd   gr   rA   rA   rB   r/     s    
r/   c                    s   t  d} fdd|D S )a	  Load layer weights of a model from hdf5.

    Args:
        f: A pointer to a HDF5 group.

    Returns:
        List of NumPy arrays of the weight values.

    Raises:
        ValueError: in case of mismatch between provided model
            and weights file.
    r   c                    s   g | ]}t  | qS rA   )r   asarrayr   r<   rA   rB   r     r   z7load_subset_weights_from_hdf5_group.<locals>.<listcomp>r   )r<   r   rA   r   rB   #load_subset_weights_from_hdf5_group  s    
r   c                 C   s  d| j v r*| j d }t|dr.|d}nd}d| j v rX| j d }t|dr\|d}nd}g }|jD ]}t|}|rf|| qft| d}g }|D ]$}	| |	 }
t|
d}|r||	 q|}t|t|krtd	t| d
t| dg }t	|D ]\}}	| |	 }
|| }t|}t
|
}t||||}t|t|krrtd| d|j d|	 dt| dt| d|t||7 }qd| v r|j|j }t
| d }t|t|krtdt| dt| d|t||7 }t| | D ]}|  qdS )zImplements topological (order-based) weight loading.

    Args:
        f: A pointer to a HDF5 group.
        model: Model instance.

    Raises:
        ValueError: in case of mismatch between provided layers
            and weights file.
    r   rF   r   r{   r   Nr   r   zDLayer count mismatch when loading weights from file. Model expected z layers, found z saved layers.!Weight count mismatch for layer # (named z in the current model, z" in the save file). Layer expects  weight(s). Received  saved weight(s)r   zZWeight count mismatch for top-level weights when loading weights from file. Model expects  top-level weight(s). Received  saved top-level weight(s))r-   rM   rF   rj   r   appendr   r   rL   	enumerater   r]   r   r   rm   rn   r   batch_set_value_flatten_layersfinalize_state)r<   r6   rf   re   filtered_layersrd   r   r   filtered_layer_namesr   r   r   weight_value_tuplesr>   r   r   rA   rA   rB   rP   
  s    











rP   Fc                 C   sF  d| j v r*| j d }t|dr.|d}nd}d| j v rX| j d }t|dr\|d}nd}t| d}i }|jD ]}|jrp||jg | qpg }t|D ]l\}	}
| |
 }t	|}|
|
g D ]D}t|}t||||}t|t|krR|r&td|	 d	|j d
t| dt| d	 qtd|	 d	|j dt| dt| d	tt|D ]}t|| }|| j}||kr|rtd|	 d	|j d|| j d| d| 
 q^td|	 d	|j d|| j d| d| 
n||| || f q^qqd| v r |j|j }t	| d }t|t|kr|rhtdt| dt| d ntdt| dt| dntt|D ]}t|| }|| j}||kr|rtd|| j d| d|  n td|| j d| d| n||| || f qt| | D ]}|  q2dS )a  Implements name-based weight loading (instead of topological loading).

    Layers that have no matching name are skipped.

    Args:
        f: A pointer to a HDF5 group.
        model: Model instance.
        skip_mismatch: Boolean, whether to skip loading of layers
            where there is a mismatch in the number of weights,
            or a mismatch in the shape of the weights.

    Raises:
        ValueError: in case of mismatch between provided layers
            and weights file and skip_match=False.
    r   rF   r   r{   r   Nr   z'Skipping loading of weights for layer #r   z6) due to mismatch in number of weights. Layer expects r   r   r   z). Layer expects z$Skipping loading weights for layer #z&) due to mismatch in shape for weight z. Weight expects shape z#. Received saved weight with shape zShape mismatch in layer #z) for weight r   zaSkipping loading top-level weights for model due to mismatch in number of weights. Model expects r   r   zDWeight count mismatch for top-level weights of model. Model expects zPSkipping loading top-level weight for model due to mismatch in shape for weight z-Shape mismatch in model for top-level weight )r-   rM   rF   r   rj   r   
setdefaultr   r   r   rK   r   r]   r   r   r   rL   ranger   r   r   rm   rn   r   r   r   )r<   r6   skip_mismatchrf   re   r   indexrd   r   r>   r   r   r   r   iexpected_shapeZreceived_shaperA   rA   rB   $load_weights_from_hdf5_group_by_namea  s    













	
r  c           	      C   s   dd |D }|r&t dt d| t|}d}t||}tdd |D rh|d7 }t||}q@|dkrt|D ]\}}|| jd||f < qxn
|| j|< d	S )
a  Saves attributes (data) of the specified name into the HDF5 group.

    This method deals with an inherent problem of HDF5 file which is not
    able to store data larger than HDF5_OBJECT_HEADER_LIMIT bytes.

    Args:
        group: A pointer to a HDF5 group.
        name: A name of the attributes to save.
        data: Attributes data to store.

    Raises:
      RuntimeError: If any single attribute is too large to be saved.
    c                 S   s   g | ]}t |tkr|qS rA   )r   HDF5_OBJECT_HEADER_LIMITr   r   rA   rA   rB   r     r   z1save_attributes_to_hdf5_group.<locals>.<listcomp>zSThe following attributes cannot be saved to HDF5 file because they are larger than z bytes: r}   c                 s   s   | ]}|j tkV  qd S r   )nbytesr  r	  rA   rA   rB   	<genexpr>  r   z0save_attributes_to_hdf5_group.<locals>.<genexpr>%s%dN)RuntimeErrorr  r   r   array_splitanyr   r-   )	groupr   databad_attributesdata_npy
num_chunkschunked_datachunk_id
chunk_datarA   rA   rB   r     s&    
r   c                 C   sj   || j v r dd | j | D }nFg }d}d||f | j v rf|dd | j d||f  D  |d7 }q(|S )ac  Loads attributes of the specified name from the HDF5 group.

    This method deals with an inherent problem
    of HDF5 file which is not able to store
    data larger than HDF5_OBJECT_HEADER_LIMIT bytes.

    Args:
        group: A pointer to a HDF5 group.
        name: A name of the attributes to load.

    Returns:
        data: Attributes data.
    c                 S   s$   g | ]}t |d r|dn|qS rF   r   rM   rF   r   nrA   rA   rB   r   1  s   z3load_attributes_from_hdf5_group.<locals>.<listcomp>r   r  c                 S   s$   g | ]}t |d r|dn|qS r  r  r  rA   rA   rB   r   :  s   r}   )r-   rl   )r  r   r  r  rA   rA   rB   r   "  s    

r   c                 C   s:   | j | j }tdd |D r6td| jj d| |S )a  DO NOT USE.

    For legacy reason, the layer.weights was in the order of
    [self.trainable_weights + self.non_trainable_weights], and this order was
    used for preserving the weights in h5 format. The new order of layer.weights
    are the same as layer.get_weights() which is more intuitive for user. To
    keep supporting the existing saved h5 file, this method should be used to
    save/load weights. In future version, we will delete this method and
    introduce a breaking change for h5 and stay with the new order for weights.

    Args:
      layer: a `tf.keras.Model` or `tf.keras.layers.Layer` instance.

    Returns:
      A list of variables with the order of trainable_weights, followed by
        non_trainable_weights.
    c                 s   s   | ]}t |tj V  qd S r   )r   r    Variabler   rA   rA   rB   r  V  r   z"_legacy_weights.<locals>.<genexpr>zSave or restore weights that is not an instance of `tf.Variable` is not supported in h5, use `save_format='tf'` instead. Received a model or layer z with weights )ri   rk   r  rV   r   r   )rd   r   rA   rA   rB   r   C  s    r   )TT)NT)NN)F)0__doc__r)   r   numpyr   tensorflow.compat.v2compatv2r    r   r   keras.optimizersr   'keras.optimizers.optimizer_experimentalr   r0   keras.savingr   rN   r   keras.saving.saved_modelr   keras.utils.generic_utilsr   Zkeras.utils.io_utilsr	   tensorflow.python.platformr
   r   r   r  r   globalsr   rC   r[   r]   r   r3   rX   r   r/   r   rP   r  r   r   r   rA   rA   rA   rB   <module>   sN   

`
w 
 d 2W
 ,!