o
    ={c\                     @   s"  d 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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Z eddG dd dej!Z"dd Z#dd Z$dd Z%dd Z&dS ) zHome of the `Sequential` model.    N)layers)
base_layer)
functional)input_layer)training)training_utils)
saving_lib)serialization)model_serialization)generic_utils)layer_utils)
tf_inspect)tf_utils)traceback_utils)
tf_logging)keras_exportzuAll layers in a Sequential model should have a single output tensor. For multi-output layers, use the functional API.zkeras.Sequentialzkeras.models.Sequentialc                       s  e Zd ZdZejjjej	d" fdd	Z
e fddZejjjej	dd Zejjjej	d	d
 Zejjj	d#ddZejd# fdd	Zd" fdd	Zdd Zdd Z fddZed#ddZe fddZejdd Zedd Zdd Z fd d!Z  ZS )$
Sequentiala  `Sequential` groups a linear stack of layers into a `tf.keras.Model`.

    `Sequential` provides training and inference features on this model.

    Examples:

    ```python
    # Optionally, the first layer can receive an `input_shape` argument:
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Dense(8, input_shape=(16,)))
    # Afterwards, we do automatic shape inference:
    model.add(tf.keras.layers.Dense(4))

    # This is identical to the following:
    model = tf.keras.Sequential()
    model.add(tf.keras.Input(shape=(16,)))
    model.add(tf.keras.layers.Dense(8))

    # Note that you can also omit the `input_shape` argument.
    # In that case the model doesn't have any weights until the first call
    # to a training/evaluation method (since it isn't yet built):
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Dense(8))
    model.add(tf.keras.layers.Dense(4))
    # model.weights not created yet

    # Whereas if you specify the input shape, the model gets built
    # continuously as you are adding layers:
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Dense(8, input_shape=(16,)))
    model.add(tf.keras.layers.Dense(4))
    len(model.weights)
    # Returns "4"

    # When using the delayed-build pattern (no input shape specified), you can
    # choose to manually build your model by calling
    # `build(batch_input_shape)`:
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Dense(8))
    model.add(tf.keras.layers.Dense(4))
    model.build((None, 16))
    len(model.weights)
    # Returns "4"

    # Note that when using the delayed-build pattern (no input shape specified),
    # the model gets built the first time you call `fit`, `eval`, or `predict`,
    # or the first time you call the model on some input data.
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Dense(8))
    model.add(tf.keras.layers.Dense(1))
    model.compile(optimizer='sgd', loss='mse')
    # This builds the model for the first time:
    model.fit(x, y, batch_size=32, epochs=10)
    ```
    Nc                    s   t tj| j|dd tjdd d| _d| _	d| _
d| _d| _d| _i | _t | _d| _d| _|rIt|ttfs?|g}|D ]	}| | qAdS dS )zCreates a `Sequential` model instance.

        Args:
          layers: Optional list of layers to add to the model.
          name: Optional name for the model.
        F)nameZautocastr   TN)superr   
Functional__init__r   Zkeras_api_gaugeZget_cellsetZsupports_maskingZ _compute_output_and_mask_jointlyZ_auto_track_sub_layers_inferred_input_shape_has_explicit_input_shapeZ_input_dtype_layer_call_argspecs_created_nodes_graph_initialized_use_legacy_deferred_behavior
isinstancelisttupleadd)selfr   r   layer	__class__ 7lib/python3.10/site-packages/keras/engine/sequential.pyr   j   s&   zSequential.__init__c                    s4   t  j}|rt|d tjr|dd  S |d d  S )Nr      )r   r   r   r   
InputLayer)r"   r   r$   r&   r'   r      s   zSequential.layersc           	      C   s  t |dr|jd }t|tjr|}t|tjr$t|tjs#t	
|}ntd| dt| dt|g | |sEtd|j dd| _d}| d	g  | jst|tjr\d
}nt|\}}|rvtj|||jd d}|| d
}|rtj|jd j}t|dkrtt|| _t| jd | _ d
| _d
| _!n| jr|| jd }ttj|dkrtt|g| _d
| _|s| j"r| #| j | j d
| _"n| j$| | %|g t&'|j(| j)|< dS )a  Adds a layer instance on top of the layer stack.

        Args:
            layer: layer instance.

        Raises:
            TypeError: If `layer` is not a layer instance.
            ValueError: In case the `layer` argument does not
                know its input shape.
            ValueError: In case the `layer` argument has
                multiple output tensors, or is already connected
                somewhere else (forbidden in `Sequential` models).
        _keras_historyr   zDThe added layer must be an instance of class Layer. Received: layer=z	 of type .zGAll layers added to a Sequential model should have unique names. Name "za" is already the name of a layer in this model. Update the `name` argument to pass a unique name.F_self_tracked_trackablesT_inputbatch_shapedtyper   r(   N)*hasattrr*   r   r   r)   tfZModuler   ZLayerr   ZModuleWrapper	TypeErrortyper   Zassert_no_legacy_layers_is_layer_name_unique
ValueErrorr   builtZ_maybe_create_attributer,   r   Zget_input_shape_and_dtypeInputnestflatten_inbound_nodesoutputslenSINGLE_LAYER_OUTPUT_ERROR_MSGr   Zget_source_inputsinputsr   r   _init_graph_networkappendZ#_handle_deferred_layer_dependenciesr   Zgetfullargspeccallr   )	r"   r#   Zorigin_layerZ
set_inputsr/   r0   xr=   Zoutput_tensorr&   r&   r'   r!      sx   




zSequential.addc                 C   s   | j std| j }| j| | j s)d| _d| _d| _d| _d| _	d| _
dS | j
rGg | j d _| j d jg| _| | j| j d| _dS dS )zzRemoves the last layer in the model.

        Raises:
            TypeError: if there are no layers in the model.
        z!There are no layers in the model.NFr1   T)r   r4   r,   popr   r=   r@   r8   r   r   r   _outbound_nodesoutputrA   )r"   r#   r&   r&   r'   rE      s"   


zSequential.popc           
      C   sx  |d u s| j s	d S tjj rtjj sd S | js| j	st
|}| jd u r)|}nt| j|}|d ur|| jkrt k tj||| j d jd d}|}t }| j D ]6}t|| j z||}W n   d| _	Y  W d    d S ttj|dkrttt|| |}|}	qS|| _z| ||	 d| _W n   d| _	Y W d    n1 sw   Y  || _d S d S d S d S d S )Nr   r-   r.   Tr(   )r   r3   __internal__tf2enabledcompatZv1Z#executing_eagerly_outside_functionsr   r   r    r   relax_input_shapeZ
init_scoper   r9   r   r   clear_previously_created_nodesr   r>   r:   r;   r7   r?    track_nodes_created_by_last_callrA   r   )
r"   input_shapeZinput_dtypeZ	new_shaper@   Zlayer_inputcreated_nodesr#   Zlayer_outputr=   r&   r&   r'   '_build_graph_network_for_inferred_shape  sl   






)
	

=z2Sequential._build_graph_network_for_inferred_shapec                    s\   | j r| | j| j n|d u rtd| | | js)t|}|| _t	 
| d| _d S )Nz+You must provide an `input_shape` argument.T)r   rA   r@   r=   r7   rQ   r8   r    _build_input_shaper   build)r"   rO   r$   r&   r'   rS   u  s   

zSequential.buildc           	         s   | j s1t|s)t|tjs)d| _tjt|| _	tj
j r(td| d n| |j|j | jrH| js?| | j| j t j|||dS |}| jD ]/}i }| j| j}d|v r_||d< d|v rg||d< ||fi |}|}dd }tj||}qM|S )	NTzVLayers in a Sequential model should only have a single input tensor. Received: inputs=z8. Consider rewriting this model with the Functional API.)r   maskrT   r   c                 S   s   t | dd S )N_keras_mask)getattr)Zktr&   r&   r'   _get_mask_from_keras_tensor  s   z4Sequential.call.<locals>._get_mask_from_keras_tensor)r   r3   Z	is_tensorr   ZTensorr   r:   Zmap_structure_get_shape_tuplerR   rH   rI   rJ   loggingZwarningrQ   shaper0   r   r8   rA   r@   r=   r   rC   r   r   args)	r"   r@   r   rT   r=   r#   kwargsZargspecrW   r$   r&   r'   rC     sB   
zSequential.callc                 C   s   |}| j D ]}||}q|S N)r   compute_output_shape)r"   rO   rZ   r#   r&   r&   r'   r^     s   
zSequential.compute_output_shapec                 C   s   | j ||d}t|dd S )N)rT   rU   )rC   rV   )r"   r@   rT   r=   r&   r&   r'   compute_mask  s   zSequential.compute_maskc                    sd   g }t  jD ]
}|t| qtj| }| j|d< t	
||d< | js0| jd ur0| j|d< |S )Nr   r   build_input_shape)r   r   rB   r	   Zserialize_keras_objectr   ZModel
get_configr   copyZdeepcopyZ_is_graph_networkrR   )r"   layer_configsr#   configr$   r&   r'   ra     s   

zSequential.get_configc           
      C   s   d|v r|d }| d}|d }nd }d }|}| |d}|D ]}tj||d}|| qttjddrF| dd }	|	d urF|j|	td	 |j	sW|rWt
|ttfrW|| |S )
Nr   r`   r   )r   )custom_objectsvalueFcompile_config)Z
base_class)getlayer_moduleZdeserializer!   rV   r   Z_SAVING_V3_ENABLEDZ_compile_from_configr   r@   r   r    r   rS   )
clsrd   re   r   r`   rc   ZmodelZlayer_configr#   rg   r&   r&   r'   from_config  s6   



zSequential.from_configc                    s"   t | dr| jS | jrt jS d S )N_manual_input_spec)r2   rl   r   r   
input_specr"   r$   r&   r'   rm     s
   
zSequential.input_specc                 C   s
   || _ d S r]   )rl   )r"   rf   r&   r&   r'   rm        
c                 C   s
   t | S r]   )r
   ZSequentialSavedModelSaverrn   r&   r&   r'   _trackable_saved_model_saver  ro   z'Sequential._trackable_saved_model_saverc                 C   s*   | j D ]}|j|jkr||ur dS qdS )NFT)r   r   )r"   r#   Z	ref_layerr&   r&   r'   r6     s
   
z Sequential._is_layer_name_uniquec                    s   | j rd S ttj|   d S r]   )r   r   r   r   _assert_weights_createdrn   r$   r&   r'   rq   	  s   z"Sequential._assert_weights_created)NNr]   )__name__
__module____qualname____doc__r3   rH   ZtrackingZ no_automatic_dependency_trackingr   Zfilter_tracebackr   propertyr   r!   rE   rQ   r   defaultrS   rC   r^   r_   ra   classmethodrk   rm   setterrp   r6   rq   __classcell__r&   r&   r$   r'   r   0   s@    8%]^3 

r   c                 C   s<   t | dr| j}t|tr|S |jd urt| S d S d S )NrZ   )r2   rZ   r   r    ZrankZas_list)trZ   r&   r&   r'   rX     s   


rX   c                 C   s@   | d u s|d u r
d S t | t |krd S tdd t| |D S )Nc                 s   s$    | ]\}}||krd n|V  qd S r]   r&   ).0Zd1Zd2r&   r&   r'   	<genexpr>!  s   " z$relax_input_shape.<locals>.<genexpr>)r>   r    zip)Zshape_1Zshape_2r&   r&   r'   rL     s
   rL   c                    sT   | j D ]}|j}tj|D ]} fdd|jD |_qq fdd| j D | _ dS )zARemove nodes from `created_nodes` from the layer's inbound_nodes.c                       g | ]}| vr|qS r&   r&   r|   nrP   r&   r'   
<listcomp>)      z2clear_previously_created_nodes.<locals>.<listcomp>c                    r   r&   r&   r   r   r&   r'   r   ,  r   N)r<   inbound_layersr3   r:   r;   rF   )r#   rP   Znodeprev_layers
prev_layerr&   r   r'   rM   $  s   



rM   c                 C   sR   | j sdS || j d  | j d j}tj|D ]}|jr&||jd  qdS )zFAdds to `created_nodes` the nodes created by the last call to `layer`.Nr1   )r<   r!   r   r3   r:   r;   rF   )r#   rP   r   r   r&   r&   r'   rN   1  s   rN   )'ru   rb   Ztensorflow.compat.v2rK   Zv2r3   Zkerasr   ri   Zkeras.enginer   r   r   r   r   Zkeras.saving.experimentalr   Zkeras.saving.legacyr	   Zkeras.saving.legacy.saved_modelr
   Zkeras.utilsr   r   r   r   r   Ztensorflow.python.platformr   rY   Z tensorflow.python.util.tf_exportr   r?   r   r   rX   rL   rM   rN   r&   r&   r&   r'   <module>   s<      c