o
    i eu                     @   sp  d Z ddlZddlZddl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 eeeefZe Ze Z d	Z!d
Z"G dd dZ#G dd dZ$eddd Z%dd Z&G dd dZ'dd Z(dd Z)dd Z*edddd Z+d d! Z,d1d"d#Z-d1d$d%Z.d&d' Z/d(d) Z0ed*d+	,d2d-d.Z1	d1d/d0Z2dS )3z6Object config serialization and deserialization logic.    N)object_registration)serialization)in_tf_saved_model_scope)generic_utils)	tf_export)keras_export)z%tensorflow.python.ops.custom_gradient)activationsconstraintsinitializerslossesmetrics
optimizersregularizersc                   @   s   e Zd Zdd Zdd ZdS )Configc                 K   
   || _ d S Nconfig)selfr    r   Q/var/www/myenv/lib/python3.10/site-packages/keras/src/saving/serialization_lib.py__init__7      
zConfig.__init__c                 C   s
   t | jS r   )serialize_keras_objectr   r   r   r   r   	serialize:   r   zConfig.serializeN)__name__
__module____qualname__r   r   r   r   r   r   r   6   s    r   c                   @   s*   e Zd ZdZd
ddZdd Zdd Zd	S )SafeModeScopezBScope to propagate safe mode flag to nested deserialization calls.Tc                 C   r   r   )	safe_mode)r   r    r   r   r   r   A   r   zSafeModeScope.__init__c                 C   s   t  | _| jt_d S r   )in_safe_modeoriginal_valuer    	SAFE_MODEr   r   r   r   	__enter__D   s   zSafeModeScope.__enter__c                 O   s   | j t_d S r   )r"   r#   r    r   argskwargsr   r   r   __exit__H      zSafeModeScope.__exit__N)T)r   r   r   __doc__r   r$   r(   r   r   r   r   r   >   s
    
r   z0keras.__internal__.enable_unsafe_deserializationc                   C   s
   dt _dS )zADisables safe mode globally, allowing deserialization of lambdas.FN)r#   r    r   r   r   r   enable_unsafe_deserializationL   s   
r+   c                   C   s   t tdd S )Nr    )getattrr#   r   r   r   r   r!   R   r)   r!   c                   @   s    e Zd ZdZdd Zdd ZdS )ObjectSharingScopez?Scope to enable detection and reuse of previously seen objects.c                 C      dt _i t _i t _d S NTSHARED_OBJECTSenabledid_to_obj_mapid_to_config_mapr   r   r   r   r$   Y      
zObjectSharingScope.__enter__c                 O   r.   )NFr0   r%   r   r   r   r(   ^   r5   zObjectSharingScope.__exit__N)r   r   r   r*   r$   r(   r   r   r   r   r-   V   s    r-   c                 C   s   t tddrtj| dS dS )z:Retrieve an object previously seen during deserialization.r2   FN)r,   r1   r3   get)obj_idr   r   r   get_shared_objectd   s   r8   c                 C   sf   |d dkr
d|d< t tddsdS tt| }|tjvr$|tj|< dS ||d< tj| }||d< dS )z>Call after serializing an object, to keep track of its config.module__main__Nr2   Fshared_object_id)r,   r1   intidr4   )objr   r7   prev_configr   r   r   !record_object_after_serializationj   s   

r@   c                 C   s   t tddsdS | tj|< dS )zFCall after deserializing an object, to keep track of it in the future.r2   FN)r,   r1   r3   )r>   r7   r   r   r   #record_object_after_deserializationy   s   rA   z#keras.saving.serialize_keras_objectz"keras.utils.serialize_keras_objectc           	         s  t jj r	t rt| S | du r| S t| tr| S t| t	t
fr4dd | D }t| t
r2t
|S |S t| tr=t| S t| trLdd| didS t| t jr]| jdur[|  S dS t| t jrqd|   | jjd	dS t| jtjkrt| tjr| jd
krd|  | jjd	dS |  S t| t jr| jS t| t jj j!r| j"S t| t#j$r| jdkrt%j&dt'(|  dd ddt)*| idS t| t j+r| , }t	t-dd |}| j.j}d}t/| drt j0j12| }t|}t34| j.}d|| j.j||dS t5| }t6| j.| t|t7r|dkr| S  dur:t8 fddt9D r.| S t:|   t;|    S t| t#j$rE| j}n| j.j}| j.j}|dkrUd}nt| t#j$rbt34| }nt34| j.}||||d}t:| | t;| | |S )a  Retrieve the config dict by serializing the Keras object.

    `serialize_keras_object()` serializes a Keras object to a python dictionary
    that represents the object, and is a reciprocal function of
    `deserialize_keras_object()`. See `deserialize_keras_object()` for more
    information about the config format.

    Args:
      obj: the Keras object to serialize.

    Returns:
      A python dict that represents the object. The python dict can be
      deserialized via `deserialize_keras_object()`.
    Nc                 S   s   g | ]}t |qS r   r   .0xr   r   r   
<listcomp>   s    z*serialize_keras_object.<locals>.<listcomp>	__bytes__valueutf-8)
class_namer   
__tensor__)rH   dtyper   	__numpy__z<lambda>a  The object being serialized includes a `lambda`. This is unsafe. In order to reload the object, you will have to pass `safe_mode=False` to the loading function. Please avoid using `lambda` in the future, and use named Python functions instead. This is the `lambda` being serialized:    )
stacklevel
__lambda__c                 S   s*   t | tjr
|  S t | tjr| jS | S r   )
isinstancetfTensorShapeas_listDTypenamerE   r   r   r   <lambda>   s   

z(serialize_keras_object.<locals>.<lambda>_tf_extension_type_fields__typespec__)rJ   	spec_namer9   r   registered_nameop_dispatch_handlerc                 3   s    | ]	}| d  v V  qdS )r9   Nr   )rD   modconfig_with_public_classr   r   	<genexpr>   s
    

z)serialize_keras_object.<locals>.<genexpr>builtinsr9   rJ   r   r\   )<rR   __internal__tf2r2   r   legacy_serializationr   rQ   PLAIN_TYPESlisttupledictserialize_dictbytesdecoderS   _dimsrT   TensornumpytolistrL   rV   typer   npr   ndarrayndimitemrU   compatv1	DimensionrH   typesFunctionTypewarningswarninspect	getsourcer   	func_dumpTypeSpec
_serializemap	__class__hasattrexperimentalextension_typeas_dictr   get_registered_name_get_class_or_fn_configserialize_with_public_classstranyNON_SERIALIZABLE_CLASS_MODULESget_build_and_compile_configr@   )	r>   
config_arr	ts_configr[   r\   inner_configr9   rJ   r   r   r_   r   r      s   




	









r   c                 C   sP   t | dr|  }|d urt||d< t | dr&|  }|d ur&t||d< d S )Nget_build_configbuild_configget_compile_configcompile_config)r   r   rk   r   )r>   r   r   r   r   r   r   r   $  s   

r   c                 C   sh   t j| dd}|du rt| }|du rdS | j| j||dS |d}d|dd |d |ddS )zSerializes classes from public Keras API or object registration.

    Called to check and retrieve the config of any class that has a public
    Keras API or has been registered as serializable via
    `keras.saving.register_keras_serializable()`.
    kerasapi_nameNrc   .)r   get_canonical_name_for_symbolr   r   r   r   splitjoin)clsr   keras_api_namer\   partsr   r   r   r   0  s$   

r   c                 C   sv   |r	|d||dS t j| dd}|r%|d}d|dd d||dS t| }|s3| jdks3dS | jd||dS )	aO  Serializes functions from public Keras API or object registration.

    Called to check and retrieve the config of any function that has a public
    Keras API or has been registered as serializable via
    `keras.saving.register_keras_serializable()`. If function's module name is
    already known, returns corresponding config.
    functionrc   r   r   r   Nr   rb   )r   r   r   r   r   r   r   )fnr   fn_module_namer   r   r\   r   r   r   serialize_with_public_fnT  s0   

r   c                 C   sx   t | tjr	| jS t| dr%|  }t |ts!td|  d| t|S t| dr/t	
| S td|  dt|  d)z1Return the object's config depending on its type.
get_configzThe `get_config()` method of z$ should return a dict. It returned: r   zCannot serialize object z	 of type zG. To be serializable, a class must implement the `get_config()` method.)rQ   rz   r{   r   r   r   rj   	TypeErrorrk   r   r   rr   )r>   r   r   r   r   r   z  s    



r   c                 C   s   dd |   D S )Nc                 S   s   i | ]	\}}|t |qS r   rB   rD   keyrH   r   r   r   
<dictcomp>  s    z"serialize_dict.<locals>.<dictcomp>)items)r>   r   r   r   rk     s   rk   z%keras.saving.deserialize_keras_objectz$keras.utils.deserialize_keras_objectTc              	      s  t  }|dur	|n|dd} pi  tjj}tj}i  || |dd}|r7tdt|  t	j
j r@t rHt| | |S | du rNdS t| tr` r` | dur` |  S t| ttfrq fdd| D S |dur
d\}	}
}t| trd	| v r| d	 }	d
| vrtd|   r| d
  v s| d v st|	tr|	 v rd}n3| d
 dkr| d }
|
dkr| d	 } n | d } n| dddu rtd| d
  d| d
  d| d
 } |s
| |vr| S t||  tjrtt||  | |
 dS tt||  |	d dS t| tr| S t| tstd|  d
| vs)d	| vr5 fdd|  D S | d
 }| d	 p?i }	 pDi  |dkrUt	j|	d |	d dS |dkretj|	d |	d dS | d
 dkrs|	d d S | d
 d!krrtd"t !|	d S | d
 d#krt"| d$ | d | d d%|  d&}t#|d'r fd(d|	 D }	|d1i |	S | d dur|$|	S t%d)d* |	}	|&t|	S | dd}| d|}|dkr|	}t"|||d|  d&S d+| v rt'| d+ }|dur|S t"|||d%|  d&}t|tjr|S t#|d,s$td-| d.|  t( }t)}|< |) |$|	}| d/d}|rF|*| | d0d}|rT|+| W d   n	1 s_w   Y  W d   n	1 sow   Y  d+| v rt,|| d+  |S )2a  Retrieve the object by deserializing the config dict.

    The config dict is a Python dictionary that consists of a set of key-value
    pairs, and represents a Keras object, such as an `Optimizer`, `Layer`,
    `Metrics`, etc. The saving and loading library uses the following keys to
    record information of a Keras object:

    - `class_name`: String. This is the name of the class,
      as exactly defined in the source
      code, such as "LossesContainer".
    - `config`: Dict. Library-defined or user-defined key-value pairs that store
      the configuration of the object, as obtained by `object.get_config()`.
    - `module`: String. The path of the python module, such as
      "keras.engine.compile_utils". Built-in Keras classes
      expect to have prefix `keras`.
    - `registered_name`: String. The key the class is registered under via
      `keras.saving.register_keras_serializable(package, name)` API. The key has
      the format of '{package}>{name}', where `package` and `name` are the
      arguments passed to `register_keras_serializable()`. If `name` is not
      provided, it uses the class name. If `registered_name` successfully
      resolves to a class (that was registered), the `class_name` and `config`
      values in the dict will not be used. `registered_name` is only used for
      non-built-in classes.

    For example, the following dictionary represents the built-in Adam optimizer
    with the relevant config:

    ```python
    dict_structure = {
        "class_name": "Adam",
        "config": {
            "amsgrad": false,
            "beta_1": 0.8999999761581421,
            "beta_2": 0.9990000128746033,
            "decay": 0.0,
            "epsilon": 1e-07,
            "learning_rate": 0.0010000000474974513,
            "name": "Adam"
        },
        "module": "keras.optimizers",
        "registered_name": None
    }
    # Returns an `Adam` instance identical to the original one.
    deserialize_keras_object(dict_structure)
    ```

    If the class does not have an exported Keras namespace, the library tracks
    it by its `module` and `class_name`. For example:

    ```python
    dict_structure = {
      "class_name": "LossesContainer",
      "config": {
          "losses": [...],
          "total_loss_mean": {...},
      },
      "module": "keras.engine.compile_utils",
      "registered_name": "LossesContainer"
    }

    # Returns a `LossesContainer` instance identical to the original one.
    deserialize_keras_object(dict_structure)
    ```

    And the following dictionary represents a user-customized `MeanSquaredError`
    loss:

    ```python
    @keras.saving.register_keras_serializable(package='my_package')
    class ModifiedMeanSquaredError(keras.losses.MeanSquaredError):
      ...

    dict_structure = {
        "class_name": "ModifiedMeanSquaredError",
        "config": {
            "fn": "mean_squared_error",
            "name": "mean_squared_error",
            "reduction": "auto"
        },
        "registered_name": "my_package>ModifiedMeanSquaredError"
    }
    # Returns the `ModifiedMeanSquaredError` object
    deserialize_keras_object(dict_structure)
    ```

    Args:
        config: Python dict describing the object.
        custom_objects: Python dict containing a mapping between custom
            object names the corresponding classes or functions.
        safe_mode: Boolean, whether to disallow unsafe `lambda` deserialization.
            When `safe_mode=False`, loading an object has the potential to
            trigger arbitrary code execution. This argument is only
            applicable to the Keras v3 model format. Defaults to `True`.

    Returns:
      The object described by the `config` dictionary.

    Nmodule_objectsprintable_module_nameobjectz-The following argument(s) are not supported: c                    s   g | ]	}t | d qS custom_objectsr    deserialize_keras_objectrC   r   r   r   rF   %  s    z,deserialize_keras_object.<locals>.<listcomp>)NNFr   rJ   z%Unknown `config` as a `dict`, config=r\   Tr   r9   rb   _z#Cannot deserialize object of type `z`. If `zj` is a custom class, please register it using the `@keras.saving.register_keras_serializable()` decorator.r   )r   zCould not parse config: c                        i | ]\}}|t | d qS r   r   r   r   r   r   r   n      z,deserialize_keras_object.<locals>.<dictcomp>rK   rH   rL   )rL   rM   rG   rI   rP   a  Requested the deserialization of a `lambda` object. This carries a potential risk of arbitrary code execution and thus it is disallowed by default. If you trust the source of the saved model, you can pass `safe_mode=False` to the loading function in order to allow `lambda` loading.rZ   r[   class)obj_typefull_configr   rY   c                    r   r   r   r   r   r   r   r     r   c                 S   s2   t | tr
t| S ttjt| rtt| S | S r   )rQ   rh   rR   rS   r   dtypesr   r,   rW   r   r   r   rX     s   z*deserialize_keras_object.<locals>.<lambda>r;   from_configz&Unable to reconstruct an instance of 'zM' because the class is missing a `from_config()` method. Full object config: r   r   r   )-r!   popr   _THREAD_LOCAL_CUSTOM_OBJECTS__dict___GLOBAL_CUSTOM_OBJECTS
ValueErrorrh   keysrR   rd   re   r2   r   rf   r   rQ   r   r6   ri   rj   r   rz   r{   r   r   rg   r   constantrs   arrayencoder   	func_load_retrieve_class_or_fnr   r   r   _deserializer8   custom_object_scoper   build_from_configcompile_from_configrA   )r   r   r    r'   safe_scope_argr   tlcogcor   r   r   has_custom_objectrJ   r   r9   r\   fn_namer>   custom_obj_scopesafe_mode_scopeinstancer   r   r   r   r   r     sV  i














	



 
	r   c                    s  |dkrt j| |d}nt j||d}|d ur|S |r|dks$|dr=|d |  }d|v r2d| }t|}|d ur=|S |dkrr|dkrrtD ]}	td|	 d |  }|d ur\|  S qG fd	d
| D }
|
rrtt|
	 S zt
|}	W n ty   td| d|  d| d  w t|	| d }|d u r|d urt|	|d }| ddkr| d\}}t|	|d }|d urt||d nd }|d ur|S td| d|  d  )Nr   r   r   zkeras.r   z__internal__.legacyz
compat.v1.rb   c                    s$   i | ]\}}|  d  r||qS r   )endswith)rD   kvr   r   r   r     s    z)_retrieve_class_or_fn.<locals>.<dictcomp>zCould not deserialize z 'z' because its parent module z) cannot be imported. Full object config:    zCould not locate zr'. Make sure custom classes are decorated with `@keras.saving.register_keras_serializable()`. Full object config: )r   get_registered_object
startswithr   get_symbol_from_nameBUILTIN_MODULESr   nextitervalues	importlibimport_moduleModuleNotFoundErrorr   varsr6   countr   r,   )rV   r\   r9   r   r   r   
custom_objr   r>   r^   filtered_dict
outer_name
inner_name	outer_objr   r   r   r     sv   

r   r   r/   )3r*   r   r~   	threadingrz   r|   rp   rs   tensorflow.compat.v2rw   v2rR   keras.src.savingr   keras.src.saving.legacyr   rf   )keras.src.saving.legacy.saved_model.utilsr   keras.src.utilsr   tensorflow.python.utilr    tensorflow.python.util.tf_exportr   r   r<   floatboolrg   localr1   r#   r   r   r   r   r+   r!   r-   r8   r@   rA   r   r   r   r   r   rk   r   r   r   r   r   r   <module>   s`   

 "

$&  P