
    2Vh`                     f   d dl Z d dlZd dl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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#  G d dee      Z$d"dZ%d Z&d Z'd Z(d#dZ)d Z*d Z+d Z,d Z-d  Z.d! Z/y)$    N)backend)ops)tree)global_state)Input)
InputLayer)	InputSpec)Layer)saving_utils)serialization)Model)Function
_build_map)make_node_key)KerasHistory)Node)	Operation)serialization_lib)trackingc                   P    e Zd ZdZ fdZej                  dd       Zd Zd Z	e
d        Zej                  d        ZddZd fd		Z fd
Zd Ze
d        Ze
d        Z fdZddZd Zd Zd Ze
d        Ze
d        Zd Ze
d        Zej                  d        Zd Z xZS )
Functionala?
  A `Functional` model is a `Model` defined as a directed graph of layers.

    Three types of `Model` exist: subclassed `Model`, `Functional` model,
    and `Sequential` (a special case of `Functional`).

    A `Functional` model can be instantiated by passing two arguments to
    `__init__()`. The first argument is the `keras.Input` objects
    that represent the inputs to the model.
    The second argument specifies the output tensors that represent
    the outputs of this model. Both arguments can be a nested structure
    of tensors.

    Example:

    ```
    inputs = {'x1': keras.Input(shape=(10,), name='x1'),
              'x2': keras.Input(shape=(1,), name='x2')}
    t = keras.layers.Dense(1, activation='relu')(inputs['x1'])
    outputs = keras.layers.Add()([t, inputs['x2']])
    model = keras.Model(inputs, outputs)
    ```

    A `Functional` model constructed using the Functional API can also
    include raw Keras 3 ops.

    Example:

    ```python
    inputs = keras.Input(shape=(10,))
    x = keras.layers.Dense(1)(inputs)
    outputs = ops.nn.relu(x)
    model = keras.Model(inputs, outputs)
    ```

    A new `Functional` model can also be created by using the
    intermediate tensors. This enables you to quickly extract sub-components
    of the model.

    Example:

    ```python
    inputs = keras.Input(shape=(None, None, 3))
    processed = keras.layers.RandomCrop(width=32, height=32)(inputs)
    conv = keras.layers.Conv2D(filters=2, kernel_size=3)(processed)
    pooling = keras.layers.GlobalAveragePooling2D()(conv)
    feature = keras.layers.Dense(10)(pooling)

    full_model = keras.Model(inputs, feature)
    backbone = keras.Model(processed, conv)
    activations = keras.Model(conv, feature)
    ```

    Note that the `backbone` and `activations` models are not
    created with `keras.Input` objects, but with the tensors
    that are originated from `keras.Input` objects.
    Under the hood, the layers and weights will
    be shared across these models, so that user can train the `full_model`, and
    use `backbone` or `activations` to do feature extraction.
    The inputs and outputs of the model can be nested structures of tensors as
    well, and the created models are standard `Functional` model that support
    all the existing API.

    Args:
        inputs: List of input tensors (must be created via `keras.Input()`
            or originated from `keras.Input()`).
        outputs: List of output tensors.
        name: String, optional. Name of the model.
        trainable: Boolean, optional. If the model's variables should be
            trainable.
    c                 J    t        j                  | t        |   |             S N)typingcastsuper__new__)clsargskwargs	__class__s      K/home/dcms/DCMS/lib/python3.12/site-packages/keras/src/models/functional.pyr   zFunctional.__new__c   s    {{3 455    c                    t        |t              rr|j                         D ]_  \  }}t        |t        j                        s!||j
                  k7  s1t        j                  d| d| d|j
                   d| d| d       a |j                  dd       }t        j                  |      }t        j                  |      }	|D ]9  }
t        |
t        j                        rt        d| d	|
 d
t        |
              |	D ]9  }
t        |
t        j                        rt        d| d	|
 d
t        |
              t        d |D              st        ||      \  }}t        j                   | |||       ||| _        | j$                  | _        | j)                  d        d| _        d| _        | j.                  D 
cg c]  }
|
j0                  d    }}
|D 
cg c]  }
|
j
                   c}
| _        y c c}
w c c}
w )NzyWhen providing `inputs` as a dict, all keys in the dict must match the names of the corresponding tensors. Received key 'z' mapping to value z which has name 'z'. Change the tensor name to 'z' (via `Input(..., name='z')`)	trainablez;All `inputs` values must be KerasTensors. Received: inputs=z including invalid value z	 of type z=All `outputs` values must be KerasTensors. Received: outputs=c              3   2   K   | ]  }t        |        y wr   )is_input_keras_tensor).0ts     r#   	<genexpr>z&Functional.__init__.<locals>.<genexpr>   s     A(+As   nameFTr   )
isinstancedictitemsr   KerasTensorr-   warningswarnpopr   flatten
ValueErrortypeallclone_graph_nodesr   __init__r&   layers_layersbuild_convert_input_args!_allow_non_tensor_positional_argsoutputs_keras_historyoutput_names)selfinputsr@   r-   r!   kvr&   flat_inputsflat_outputsxoutput_layerss               r#   r:   zFunctional.__init__f   s    fd# 1a!4!45!qvv+MM2234Gs K++,66( 337s$	@ JJ{D1	ll6*||G, 	Aa!4!45 $X%>qc B G9& 	  	Aa!4!45 &i'@ D G9& 	 A[AA/@OFG$d; &DN{{

4#( 15.6:llC))!,CC-:;QVV; D;s   <G4G9c                      y r    rC   s    r#   _lock_statezFunctional._lock_state   s     	r$   c                      y)Nr   rL   rM   s    r#   	_obj_typezFunctional._obj_type   s    r$   c                 p    g }| j                   D ]$  }t        |t              s|j                  |       & |S r   )_operationsr.   r
   append)rC   r;   	operations      r#   r;   zFunctional.layers   s9    )) 	)I)U+i(	) r$   c                     t        d      )NzU`Model.layers` attribute is reserved and should not be used. Please use another name.)AttributeError)rC   _s     r#   r;   zFunctional.layers   s    '
 	
r$   c                    | j                  |      }|d gt        |      z  }nBt        j                  |      }t	        ||      D ]  \  }}|	t        j                  ||         | j                  |fd      }t        |      S )Nc                      t        | fdiS )Ntrainingoperation_fn)opr!   rZ   s    r#   <lambda>z!Functional.call.<locals>.<lambda>   s    L%%%)/% r$   r[   )	_standardize_inputslenr   r5   zipr   set_keras_mask_run_through_graphunpack_singleton)rC   rD   rZ   maskr!   masksrI   r@   s     ` `   r#   callzFunctional.call   s    ))&1<FS[(ELL&Evu- 44#**1d34 )) * 
  ((r$   c                 "    t         |   |      S r   )r   compute_output_spec)rC   rD   rZ   re   r"   s       r#   ri   zFunctional.compute_output_spec   s    w*622r$   c                 "    t         |   |      S r   )r   compute_output_shape)rC   input_shaper"   s     r#   rk   zFunctional.compute_output_shape   s    w+K88r$   c                     d| _         y )NT)built)rC   rl   s     r#   r=   zFunctional.build   s	    
r$   c                     t        j                  d | j                        }t        |t              rt        |      dk(  r|d   S |S )Nc                     | j                   S r   shaperI   s    r#   r^   z(Functional.input_shape.<locals>.<lambda>   s
    AGG r$      r   )r   map_structurerD   r.   listr`   )rC   input_shapess     r#   rl   zFunctional.input_shape   s?    ))*;T[[IlD)c,.?1.D?"r$   c                     t        j                  d | j                        }t        |t              rt        |      dk(  r|d   S |S )Nc                     | j                   S r   rq   rs   s    r#   r^   z)Functional.output_shape.<locals>.<lambda>   s
    QWW r$   rt   r   )r   ru   r@   r.   rv   r`   )rC   output_shapess     r#   output_shapezFunctional.output_shape   s@    **+<dllKmT*s=/AQ/F ##r$   c                 $    t        t        | 
  | S r   )r   r   _assert_input_compatibility)rC   r    r"   s     r#   r}   z&Functional._assert_input_compatibility   s    UD=tDDr$   c                 d   	 t        j                  t        j                  |      t        j                  | j                               y #  t        j                  d | j                        }t        j                  d |      }d| d| }|rt        |      t        j                  |       Y y xY w)Nc                     | j                   S r   r,   rs   s    r#   r^   z?Functional._maybe_warn_inputs_struct_mismatch.<locals>.<lambda>   s
    !&& r$   c                 "    d| j                    dS )NzTensor(shape=)rq   rs   s    r#   r^   z?Functional._maybe_warn_inputs_struct_mismatch.<locals>.<lambda>   s    M!''!4 r$   zJThe structure of `inputs` doesn't match the expected structure.
Expected: z
Received: inputs=)r   assert_same_structurelists_to_tuples_inputs_structru   r6   r2   r3   )rC   rD   raise_exceptionmodel_inputs_structinputs_structmsgs         r#   "_maybe_warn_inputs_struct_mismatchz-Functional._maybe_warn_inputs_struct_mismatch   s    	 &&$$V,$$T%8%89	"&"4"4 $"5"5# !..4fM))<(= >$$1?4 
  o%MM#s   AA	 	A$B/c                     g }t        || j                        D ]T  \  }}||j                  |       |j                  t        j                  ||j
                  |j                               V |S )N)dtypesparse)ra   _inputsrS   r   convert_to_tensorr   r   )rC   rG   	convertedrI   inputs        r#   _convert_inputs_to_tensorsz%Functional._convert_inputs_to_tensors   sk    	K6 	HAuy  #  ))U\\		 r$   c           	      (   | j                   D cg c]  }|j                   }}g }t        ||      D ]  \  }}||j                  |       t	        |j                        }t	        |      }||k(  r|j                  |       Q||dz   k(  r9|j                  d   dk(  r'|j                  t        j                  |d             ||dz
  k(  r/|d   dk(  r'|j                  t        j                  |d             t        d| d| d|j                          t        t	        |            D ]\  }t        ||   d      r||   j                  ||   _        t        j                  ||         }	|	Dt        j                  ||   |	       ^ |S c c}w )Nrt   )axiszInvalid input shape for input z. Expected shape z#, but input has incompatible shape rA   )r   rr   ra   rS   r`   r   squeezeexpand_dimsr6   rangehasattrrA   r   get_keras_maskrb   )
rC   rG   rI   flat_ref_shapesadjusted	ref_shapex_rankref_rankire   s
             r#   _adjust_input_rankzFunctional._adjust_input_rank   s   ,0LL9q17799_= 	LAyy"\F9~H!"A%772;!#OOCKK$;<A%R=A%OOCOOAB$?@03D+@	K #	, s;'( 	:A{1~'78-8^-J-J*))+a.9D&&x{D9	: = :s   Fc                 t   d}t        | j                  t              r2t        | j                        dk(  rt	        j
                  |      r|g}n)t        |t              rt        | j                  t              st        | j                  d      rt        d | j                  D              rpt        d | j                  D              }t        |j                               }|j                  |      r'| j                  D cg c]  }||j                      }}n_d}n\t        | j                  t        j                        r6| j                  j                  |v r|| j                  j                     g}nd}nd}t        | j                  t              rYt        |t              sIt        | j                  j                               t        | j                  j                               k7  rd}| j!                  ||       t#        j$                  |      }| j'                  |      }| j)                  |      S c c}w )NFrt   __len__c              3   P   K   | ]  }t        |t        j                           y wr   r.   r   r1   r)   r   s     r#   r+   z1Functional._standardize_inputs.<locals>.<genexpr>.  s"      ?78
1g112?   $&c              3   4   K   | ]  }|j                     y wr   r,   r   s     r#   r+   z1Functional._standardize_inputs.<locals>.<genexpr>1  s     #HqAFF#Hs   T)r   )r.   r   rv   r`   r   	is_tensorr/   r   r8   setkeysissubsetr-   r   r1   sortedr   r   r5   r   r   )rC   rD   r   expected_keysr   r   rG   s          r#   r_   zFunctional._standardize_inputs!  s   t**D1D''(A-f%XF%j/

 t**I63 ?<@<O<O? < !$#HD4G4G#H H6;;=) ))$/6:6I6IJfQVVnJFJ&*OD//1D1DE&&++v5$T%8%8%=%=>?F&*O"&t**D1vt,T((--/0d))..012 #O//O 	0 	
 ll6*55kB&&{33/ Ks    H5c                     | j                   S r   )r   rM   s    r#   r   zFunctional.inputM  s    
 """r$   c                     | j                   S r   )_outputs_structrM   s    r#   outputzFunctional.outputT  s    ###r$   c                     t         r   )NotImplementedError)rC   losss     r#   add_losszFunctional.add_lossX  s    !!r$   c                    t        | d      r| j                  S d dfd	}t        | j                  t              rst        d | j                  j                         D              rHt        | j                  j                               }|D cg c]  } || j                  |   |       c}S y | j                  D cg c]
  } ||       c}S c c}w c c}w )N_manual_input_specc                 <    t        |       } | rd | d<   t        |       S )Nr   )rv   tuplers   s    r#   shape_with_no_batch_sizez7Functional.input_spec.<locals>.shape_with_no_batch_sizea  s     QA!8Or$   c                     d}t        | j                  d   t              r| j                  d   j                  rd}t	         | j
                        d|| j                  d   j                  |      S ||      S )NFr   T)rr   allow_last_axis_squeezer-   optional)r.   rA   r   r   r	   rr   r-   )rI   r-   r   r   s      r#   make_spec_for_tensorz3Functional.input_spec.<locals>.make_spec_for_tensorg  s    H!**1-z:##A&//#H.qww7(,15Q%%a(--!	  DH!	 r$   c              3   P   K   | ]  }t        |t        j                           y wr   r   )r)   rI   s     r#   r+   z(Functional.input_spec.<locals>.<genexpr>t  s%       1g112r   r,   r   )
r   r   r.   r   r/   r8   valuesr   r   rD   )rC   r   namesr-   rI   r   s        @r#   
input_speczFunctional.input_spec\  s    4-.***	
	 d))40 ,,335 
 t22779: !& ))<)<T)BN  15=A$Q'==
 >s   C>Cc                     || _         y r   )r   )rC   values     r#   r   zFunctional.input_spec  s
    "'r$   c                     t         j                        st        j                         S  j                   j
                  d}i  j                  D ]c  }t        |j                  t              rd}nd}t        |j                        D ]*  \  }}t        ||      }| j                  v s!||<   |dz  }, e g } j                  D ]  }g }t        |j                        D ]K  \  }}t        ||      }| j                  v s!t        | j                        }	|	;|j                  |	       M t        j                   }
t#        j$                  dd      rt&        j                   }
 |
|      }|j                  |d<   ||d<   |j                  |        ||d	<    fd
fd} | j(                        |d<    | j*                        |d<   t-        j.                  |      S )Nr-   r&   rt   r   )	own_nodesuse_legacy_configFr-   inbound_nodesr;   c                     | j                   d   }| j                   d   }| j                   d   }t        ||      }|j                  v sJ |   }|j                  ||gS )Nr   rt      )rA   r   _nodesr-   )tensorrT   
node_indextensor_indexnode_keynew_node_indexnode_reindexing_maprC   s         r#   get_tensor_configz0Functional.get_config.<locals>.get_tensor_config  sl    --a0I..q1J!003L$Y
;Ht{{***0:NNNNLAAr$   c                 v    t        | t        j                        r	 |       gS t        j                  |       S r   )r.   r   r1   r   ru   )tensorsr   s    r#   map_tensorsz*Functional.get_config.<locals>.map_tensors  s5    '7#6#67)'233%%&7AAr$   input_layersrJ   )functional_like_constructorr"   r   
get_configr-   r&   
operations
issubclassr   	enumerate_inbound_nodesr   r   serialize_noderS   r   serialize_keras_objectr   get_global_attributelegacy_serializationr   r   copydeepcopy)rC   configrT   
kept_nodesoriginal_node_indexnoder   layer_configsfiltered_inbound_nodes	node_dataserialize_obj_fnlayer_configr   r   r   s   `            @@r#   r   zFunctional.get_config  s   *4>>: ##D)) II
 ! 	$I)--z: 

-6((. $)#T )4GHt{{*4>'1!OJ$	$"  	/I%'"-6((. 	A)#T )4GHt{{* !/tt{{ KI ,.55i@	A  1GG001DeL#7#N#N +I6L#,>>L ,BL)  .)	/* )x	B	B
 "-T-@-@!A~"-d.B.B"C}}V$$r$   r   )NN)F)__name__
__module____qualname____doc__r   r    no_automatic_dependency_trackingr:   rN   rP   propertyr;   setterrg   ri   rk   r=   rl   r{   r}   r   r   r   r_   r   r   r   r   r   __classcell__)r"   s   @r#   r   r      s   EN6 ..,< /,<\   ]]
 
)$39    E0B*4X # # $ $" "> ">H ( (I%r$   r   c                    i i fdfd}fd}i }dD ]  }|j                  |      ||<    dD ]   }||v r|j                  |      ||<   d||<   " |d   D ]
  } ||        rl|d   D ]a  }|d      }|v s|   }	d	}
|
t        |	      k  r#|	|
   }	  |||       |
d
z  }
|
t        |	      k  r#|
t        |	      k  r	|	|
d |<   _|= c rl|d   }|d   }fdfd |d         } |d         }t        |t              rt        |      d
k(  r|d	   } | d||||d|S # t        $ r Y w xY w)aI  Instantiates a Functional model from its config (from `get_config()`).

    Args:
        cls: Class of the model, e.g. a custom subclass of `Model`.
        config: Output of `get_config()` for the original model instance.
        custom_objects: Optional dict of custom objects.

    Returns:
        An instance of `cls`.
    c                 D    | vr|g| <   y|    j                  |       y)zAdd node to layer list

        Arg:
            layer: layer object
            node_data: Node data specifying layer call
        N)rS   )layerr   unprocessed_nodess     r#   add_unprocessed_nodez4functional_from_config.<locals>.add_unprocessed_node  s.     ))(1{e$e$++I6r$   c                 4    t        |      \  }} | |i | y)zReconstruct node by linking to inbound layers

        Args:
            layer: Layer to process
            node_data: List of layer configs
        N)deserialize_node)r   r   r    r!   created_layerss       r#   process_nodez,functional_from_config.<locals>.process_node  s$     (	>Bf 	tvr$   c                     | d   }d| vrt        j                  |       }nt        j                  |       }t	        |t
              st        dt        |             ||<   | d   }|D ]  } ||        y)ztDeserializes a layer and index its inbound nodes.

        Args:
            layer_data: layer config dict.
        r-   module)custom_objectszMUnexpected object from deserialization, expected a layer or operation, got a r   N)r   model_from_configr   deserialize_keras_objectr.   r   r6   r7   )
layer_data
layer_namer   inbound_nodes_datar   r   r   r   s        r#   process_layerz-functional_from_config.<locals>.process_layer  s      '
 :% !22>E &>>>E %+$$(K=2  &+z" (8+ 	3I
 !	2	3r$   )r;   r   rJ   r   Nr;   r-   r   rt   r&   c                     | v sJ |    }t        |t              r|dz  }|j                  |   j                  }||   S )Nrt   )r.   r   r   output_tensors)r  r   r   r   layer_output_tensorsr   s        r#   
get_tensorz*functional_from_config.<locals>.get_tensorW  sP    ^+++z*eZ(!OJ$33J?NN#L11r$   c                    t        | t              r&t        |       dk(  rt        | d   t              r |  S t        | t              r*| j                         D ci c]  \  }}| |       c}}S t        | t              rt        | D cg c]
  } |       c}      S | D cg c]
  } |       c}S c c}}w c c}w c c}w )N   r   )r.   rv   r`   strr/   r0   r   )r   rE   rF   r
  r   s      r#   r   z+functional_from_config.<locals>.map_tensors`  s    w%G!71:s+ w''gt$29--/B$!QA{1~%BBgu%':Q+a.:;;(/01A00 C:0s   B7B=%Cr   rJ   )rD   r@   r-   r&   rL   )r4   r`   
IndexErrorr.   rv   )r   r   r   r   r  functional_configkeyr  r   node_data_listr   r   r-   r&   input_tensorsr  r   r   r
  r   r   s     `             @@@@@r#   functional_from_configr    s    N 
7
!3L : 1!'C#1$ *&=%+ZZ_c"%)c"	* (1 "
j!" +H5 	1J":f#56E ))!25!9 
 3~#66 .z :I$UI6 !OJ !3~#66 N 33/=jk/J%e, *%05	1 < V$D!+.I21   1. ABM !2?!CDN.$'C,?1,D'* 	
  Y & s   "	D99	EEc                       fd}|S )z.Wraps each op to inject the call-context args.c                  t    j                         D ]  \  }}|t        di       v s||||<     | i |S )N_call_context_args)r0   getattr)r    r!   r-   r   call_context_argsrT   s       r#   rg   zoperation_fn.<locals>.call  sR    ,224 	%KD%	+?DD%$t	% $)&))r$   rL   )rT   r  rg   s   `` r#   r\   r\   |  s    	* Kr$   c                     t        j                  | j                        j                  dd  }t        j                  t        j                        j                  dd  }||k(  ryy)Nrt   TF)inspectgetfullargspecr:   r    r   )r   	init_argsfunctional_init_argss      r#   r   r     sV    &&s||499!"=I"11*2E2EFKKABO((r$   c                 X    t        | t        t        f      rt        |       dk(  r| d   S | S )Nrt   r   )r.   rv   r   r`   rs   s    r#   rd   rd     s(    !dE]#A!tHr$   c                 .   | j                   sy fd}| j                  j                  }| j                  j                  }t	        j
                  ||      }t	        j
                  ||      }t        j                  |      t        j                  |      dS )Nc                 H   t        | t        j                        r| j                  \  }}}d}t	        |j
                  d |       D ]  \  }}t        ||      }|	vs|dz  } t        |||z
  |      | _        t        j                  |       }t        |||      | _        |S | S )Nr   rt   )
r.   r   r1   rA   r   r   r   r   r   r   )
rI   rT   r   r   irrelevant_node_countr   r   r   
serializedr   s
            r#   serialize_keras_tensorz.serialize_node.<locals>.serialize_keras_tensor  s     a,,-232B2B/Iz<$%!$Y%=%=kz%JK /4(A69,)Q.)/  ,:(==| A +AA!DJ+Iz<PAr$   )r    r!   )r  	argumentsr    r!   r   ru   r   r   )r   r   r#  r    r!   s    `   r#   r   r     s    $ >>D^^""F4d;D 6?F!88>#::6B r$   c           	      v   | sg i fS t        | t              rg }| D ]  }|d   }|d   }|d   }t        |      dk(  ri }nt        |      dk(  r|d   }nt        d      |   }t        |j                        |k  rt        d| d|j                   d	|       |j                  |   }	|j                  |	j                  |           t        |      gfS t        j                  | d
         }
t        j                  | d         }fd}t        j                  ||
      }
t        j                  ||      }|
|fS )z1Return (args, kwargs) for calling the node layer.r   rt   r   r     z3Cannot deserialize the model (invalid config data?)0Layer node index out of bounds.
inbound_layer =  
inbound_layer._inbound_nodes = 
inbound_node_index = r    r!   c                 h   t        | t        j                        r| j                  }|| S j	                  |d   d       }|t        d|d          |d   }|d   }t        |j                        |k  rt        d| d|j                   d|       |j                  |   }|j                  |   S | S )Nr   zUnknown layer: rt   r   r'  r(  r)  )
r.   r   r1    _pre_serialization_keras_historygetr6   r`   r   r  r  )rI   historyr   inbound_node_indexinbound_tensor_indexinbound_noder   s         r#   convert_revived_tensorz0deserialize_node.<locals>.convert_revived_tensor  s    a,,-88G"&&wqz48E} ?71:,!?@@!(#*1: 5''(,>> '',g .66;6J6J5K L,,>+?A  !//0BCL../CDDr$   )r.   rv   r`   r6   r   r  rS   r  rd   r   r  r   ru   )r   r   r  
input_datainbound_layer_namer.  r/  r!   inbound_layerr0  r    r1  s    `          r#   r   r     s   2v)T"# 	J!+A!+A#-a= :!#ZA%#A I  ++=>M =//04FF ''4o 66$334 5,,>+?	A  )778JKL  ++,@A3	8 !/0&8855i6GHD77	(8KLF* 4d;D 6?F<r$   c                 X    | j                   \  }}}|j                  |   }|j                  S r   )rA   r   is_input)rI   rT   r   rW   r   s        r#   r(   r(      s5    
 	
		##J/D==r$   c                     t        j                  | j                  | j                  | j                  | j
                  dz         S )N_clone)rr   r   r   r-   )r   r1   rr   r   r   r-   rs   s    r#   clone_single_keras_tensorr9  
  s3    ggQWWQXXAFFX<M r$   c                 :    fd}t        j                  ||       S )Nc                     t        | t        j                        s| S t        |       v rt        |          S t	        |       }|t        |       <   |S r   )r.   r   r1   idr9  )rI   new_xkt_id_mappings     r#   swapz!clone_keras_tensors.<locals>.swap  sP    !W001Ha5M! A'')!,$ber$   )r   ru   )r   r>  r?  s    ` r#   clone_keras_tensorsr@    s     dG,,r$   c                 $    t        | |      \  }}|S r   r   )rD   r@   nodesrW   s       r#    find_nodes_by_inputs_and_outputsrC    s    &'*HE1Lr$   c                 :   t        | |      }g }g }i }i }t        j                  |       D ]  }t        |      r |j	                  |       ||t        |      <   .t        |j                  |j                  |j                  |j                  dz         }|j	                  |       ||t        |      <   |j                  d   |t        |j                  d         <    t        j                  | |      }t        j                  |      D ]=  }	t        |	      }
|	j                  |
_        |j	                  |
       |
|t        |	      <   ? t        j                  ||      }|D ]  }t        |j                        |v r|t        |j                           }n|j                  }t        |j                   |      }t#        |t$              sAt        |j&                  j(                  |      }t        |j&                  j*                  |      }nd}i }t-        ||||        ||fS )a  Clone the `Node` between the inputs and output tensors.

    This function is used to create a new functional model from any intermediate
    Keras tensors. The clone of the nodes mimic the behavior of reconstructing
    the functional graph network by re-executing all the `__call__()` methods.
    The cloned nodes will be appended to the layers.

    Note that a new `keras.Input` will be created for any items in the
    `inputs`

    Args:
    inputs: A nested structure of `KerasTensor` instances.
    outputs: A nested structure of `KerasTensor` instances.

    Returns:
        A pair of inputs and outputs, with cloned `KerasTensor` instances.
        They can be used to create a new functional model.
    CLONE)batch_shaper   r   r-   r   rL   )	call_argscall_kwargsr@   )rC  r   r5   r(   rS   r<  r   rr   r   r   r-   rA   pack_sequence_asr9  rT   r@  r  r.   r   r$  r    r!   r   )rD   r@   nodes_to_clonecloned_inputscloned_outputsr>  op_id_mappingkt_inputcloned_input	kt_outputcpyr   rT   output_copycall_args_copycall_kwargs_copys                   r#   r9   r9   "  s   & 6fgFNMN MMLL(  *  **2M"X,' !$NNnn]]W,	L   .*6M"X,'++A. "X44Q789$ ))&-@M\\'* +	'	2&55c"'*bm$+ **7NCN 
dnn.%b&89II *$*=*=}M)Z00##]N  3%%}   N! 	$(		
/
: .((r$   r   )rL   )0r   r  r   r2   	keras.srcr   r   r   keras.src.backend.commonr   !keras.src.layers.core.input_layerr   r   keras.src.layers.input_specr	   keras.src.layers.layerr
   keras.src.legacy.savingr   r   r   keras.src.models.modelr   keras.src.ops.functionr   r   r   keras.src.ops.noder   r   keras.src.ops.operationr   keras.src.savingr   keras.src.utilsr   r   r  r\   r   rd   r   r   r(   r9  r@  rC  r9   rL   r$   r#   <module>ra     s           1 3 8 1 ( 0 I ( + - 0 + # - . $s%5 s%lhV"D@F
-
W)r$   