o
    biy                     @   sf   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dG dd	 d	ejZd
S )    )backend)layers)keras_export)_list_variables_used_by_fns)serialization_lib)
tensorflowzkeras.layers.TFSMLayerc                       sX   e Zd ZdZ					d fdd	Zdd Zdd
dZ fddZedddZ	  Z
S )	TFSMLayerag  Reload a Keras model/layer that was saved via SavedModel / ExportArchive.

    Arguments:
        filepath: `str` or `pathlib.Path` object. The path to the SavedModel.
        call_endpoint: Name of the endpoint to use as the `call()` method
            of the reloaded layer. If the SavedModel was created
            via `model.export()`,
            then the default endpoint name is `'serve'`. In other cases
            it may be named `'serving_default'`.

    Example:

    ```python
    model.export("path/to/artifact")
    reloaded_layer = TFSMLayer("path/to/artifact")
    outputs = reloaded_layer(inputs)
    ```

    The reloaded object can be used like a regular Keras layer, and supports
    training/fine-tuning of its trainable weights. Note that the reloaded
    object retains none of the internal structure or custom methods of the
    original object -- it's a brand new layer created around the saved
    function.

    **Limitations:**

    * Only call endpoints with a single `inputs` tensor argument
    (which may optionally be a dict/tuple/list of tensors) are supported.
    For endpoints with multiple separate input tensor arguments, consider
    subclassing `TFSMLayer` and implementing a `call()` method with a
    custom signature.
    * If you need training-time behavior to differ from inference-time behavior
    (i.e. if you need the reloaded object to support a `training=True` argument
    in `__call__()`), make sure that the training-time call function is
    saved as a standalone endpoint in the artifact, and provide its name
    to the `TFSMLayer` via the `call_training_endpoint` argument.
    serveNTc                    sR  t   dkr
tdt j|||d tj|| _|| _|| _	|| _
t| j|r1t| j|| _n|| jjv r?| jj| | _ntd| dt| jj  |r}t| j|r_t| j|| _n|| jjv rm| jj| | _ntd| dt| jj  | jg}|r|| j t|\}}	|D ]}
| |
 q|	D ]}
| |
 q|   d S )Nr   zFThe TFSMLayer is only currently supported with the TensorFlow backend.)	trainablenamedtypezThe endpoint 'z' is neither an attribute of the reloaded SavedModel, nor an entry in the `signatures` field of the reloaded SavedModel. Select another endpoint via the `call_endpoint` argument. Available endpoints for this SavedModel: z' is neither an attribute of the reloaded SavedModel, nor an entry in the `signatures` field of the reloaded SavedModel. Available endpoints for this SavedModel: )r   NotImplementedErrorsuper__init__tfsaved_modelload_reloaded_objfilepathcall_endpointcall_training_endpointhasattrgetattrcall_endpoint_fn
signatures
ValueErrorlistkeyscall_training_endpoint_fnappendr   _add_existing_weight_build_at_init)selfr   r   r   r
   r   r   all_fnstvsntvsv	__class__ O/home/ubuntu/.local/lib/python3.10/site-packages/keras/src/export/tfsm_layer.pyr   1   sR   	
zTFSMLayer.__init__c              	   C   s2   t j||j|j|j|jddd}| | dS )zTracks an existing weight./_)initializerr
   r   shaper   N)r   Variabler
   r   r.   r   replace_track_variable)r"   weightvariabler)   r)   r*   r    {   s   zTFSMLayer._add_existing_weightFc                 K   s.   |r| j r| j|fi |S | j|fi |S )N)r   r   r   )r"   inputstrainingkwargsr)   r)   r*   call   s   zTFSMLayer.callc                    s(   t   }| j| j| jd}i ||S )N)r   r   r   )r   
get_configr   r   r   )r"   base_configconfigr'   r)   r*   r8      s   
zTFSMLayer.get_configc                 C   s2   |dur|nt  }|durtd| di |S )a/  Creates a TFSMLayer from its config.
        Args:
            config: A Python dictionary, typically the output of `get_config`.
            custom_objects: Optional dictionary mapping names to custom objects.
            safe_mode: Boolean, whether to disallow loading TFSMLayer.
                When `safe_mode=True`, loading is disallowed because TFSMLayer
                loads external SavedModels that may contain attacker-controlled
                executable graph code. Defaults to `True`.
        Returns:
            A TFSMLayer instance.
        NFah  Requested the deserialization of a `TFSMLayer`, which loads an external SavedModel. This carries a potential risk of arbitrary code execution and thus it is disallowed by default. If you trust the source of the artifact, you can override this error by passing `safe_mode=False` to the loading function, or calling `keras.config.enable_unsafe_deserialization().r)   )r   in_safe_moder   )clsr:   custom_objects	safe_modeeffective_safe_moder)   r)   r*   from_config   s   
zTFSMLayer.from_config)r	   NTNN)F)NN)__name__
__module____qualname____doc__r   r    r7   r8   classmethodr@   __classcell__r)   r)   r'   r*   r   	   s    )J

r   N)	keras.srcr   r   keras.src.api_exportr   keras.src.export.saved_modelr   keras.src.savingr   keras.src.utils.module_utilsr   r   Layerr   r)   r)   r)   r*   <module>   s    