a
    Sic6                     @   s   d 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Zdd	iZG d
d dZG dd dedg dZdd ZdS )zContains the `Node` class.    N)backend)base_layer_utils)
json_utils)tf_utils_CONSTANT_VALUEZ_TYPEZ	COMPOSITEc                   @   s   e Zd ZdZdddZedd Zedd Zd	d
 Zdd Z	dd Z
edd Zedd Zedd Zedd Zedd Zedd ZdS )Nodea  A `Node` describes a layer `__call__()` event.

    A Functional model is a DAG with `Node` instances as nodes, and
    `KerasTensor` instances as edges. Nodes aren't `Layer` instances, because a
    single layer could be called multiple times, which would result in graph
    cycles.

    A `__call__()` event involves input tensors (and other input arguments),
    the layer that was called, and the resulting output tensors.
    A `Node` will include all this information.

    Since a single `Layer` could be called multiple times, the `Node` instances
    are stored on layers as a list. Each time a layer is called a node is added
    to `layer._inbound_nodes`. Each time the output of a layer is used by
    another layer, a node is added to `layer._outbound_nodes`.

    Every `KerasTensor` instance has a `KerasHistory` object attached,
    which tracks the `Node` that records the `__call__()` event that created
    the tensor. By recursively walking through `Node` instances
    via the `KerasHistory` metadata of `KerasTensor` instances, once can
    retrieve the entire DAG of a Functional model.

    Args:
        layer: The layer that was called in the `Layer.__call__()`
          event that this node represents.
        call_args: The positional arguments the layer was called with.
        call_kwargs: The keyword arguments the layer was called with.
        outputs: The output tensors of the `Layer.__call__()`
    Nc                 C   s  |d u rg n|}|d u ri n|}|d u r,g n|}|| _ | o@| | _tjdd |}tjdd |}tjdd || _|| _|| _tj| j| jf| _	| j ot
| jdkot| jd | _tjj s| j	D ](}t|tjrtj|ddrt| qg | _g | _t| j	D ]@\}}t|r| j| tt|}|}	| j||	f q| j j|  | jD ]$}
|
jj }|d urp|j|  qpt
| j jd }ttj|D ]\}}t |||d	|_qd
d | jD | _!dd tj| jD | _"d S )Nc                 S   s   | S N tr	   r	   M/var/www/html/django/DPS/env/lib/python3.9/site-packages/keras/engine/node.py<lambda>Q       zNode.__init__.<locals>.<lambda>c                 S   s   | S r   r	   r
   r	   r	   r   r   R   r   c                 S   s   | S r   r	   r
   r	   r	   r   r   S   r      r   T)ignore_call_contextlayer
node_indextensor_indexc                 S   s   g | ]}t t|qS r	   strid.0r   r	   r	   r   
<listcomp>   r   z!Node.__init__.<locals>.<listcomp>c                 S   s   g | ]}t t|qS r	   r   r   r	   r	   r   r      s   )#r   is_inputtfnestmap_structureoutputs	call_argscall_kwargsflatten_flat_argumentslen	is_tensor _single_positional_tensor_passedcompatv1#executing_eagerly_outside_functions
isinstanceTensorr   needs_keras_historycreate_keras_history_keras_inputs_keras_inputs_ids_and_indices	enumerateis_keras_tensorappendr   r   _inbound_nodeskeras_inputs_keras_history_outbound_nodesKerasHistoryflat_input_idsflat_output_ids)selfr   r    r!   r   objielekt_idkt_indexktinbound_layerr   tensorr	   r	   r   __init__C   sd    




zNode.__init__c                 C   s   | j S )zNTensors input to this node that can be traced back to a
        `keras.Input`.)r.   r:   r	   r	   r   r4      s    zNode.keras_inputsc                 C   s<   g }| j D ],}|jj}|jj}|dur
||j|  q
|S )zNReturns all the `Node`s whose output this node immediately depends
        on.N)r4   r5   r   r   r2   r3   )r:   	node_depsr@   r   r   r	   r	   r   parent_nodes   s    
zNode.parent_nodesc                 c   s6   | j D ]*}|j}|j}|j}|j}||||fV  qdS )zYields tuples representing the data inbound from other nodes.

        Yields:
          tuples like: (inbound_layer, node_index, tensor_index, tensor).
        N)r4   r5   r   r   r   )r:   r@   keras_historyr   r   r   r	   r	   r   iterate_inbound   s    
zNode.iterate_inboundc                 C   sx   | j r&| jd \}}||  fi fS t| j}| jD ]\}}||  ||< q8tj| j| j	f|\}}||fS dS )z;Maps Keras Tensors to computed Tensors using `tensor_dict`.r   N)
r&   r/   popcopyr#   r   r   pack_sequence_asr    r!   )r:   tensor_dictr>   _flat_argumentsr?   argskwargsr	   r	   r   map_arguments   s    zNode.map_argumentsc           	         s  | j | j }| jj|\}}tt| jjjdd |}| |fdd t	j
 ztjtjd W nD ty   t	j
t}td| jj d d t| d	 Y n0  fd
d}t	j
||}t	j
|s| jjs|g}t|}|S )z4Serializes `Node` for Functional API's `get_config`.r   Nc                    s   t | dr@| j}|j} |jj|}|d}|jj||jgS t| tj	rT| 
 S t| tjrnt| 
 S t| tjjrtt | fS | S )z,Serializes a single Tensor passed to `call`.r5   r   )hasattrr5   r   r   namegetr   r*   npndarraytolistr   r+   r   	get_value__internal__CompositeTensor_COMPOSITE_TYPEr   Encoderencode)r   khr   node_keynew_node_index)make_node_keynode_conversion_mapr	   r   _serialize_keras_tensor   s    
z/Node.serialize.<locals>._serialize_keras_tensor)defaultzLayer z- was passed non-JSON-serializable arguments. zArguments had types: z6. They cannot be serialized out when saving the model.c                    s\   t | rB| j}|j}|jj|}|d}|jj||jg}ntd | g}t	|S )Nr   )
r1   r5   r   r   rS   rT   r   r   r   ListWrapper)r   r^   r   r_   r`   datarc   rP   ra   rb   r	   r   serialize_first_arg_tensor   s    z2Node.serialize.<locals>.serialize_first_arg_tensor)r    r!   r   
_call_specsplit_out_first_argdictzip	arg_namesupdater   r   r   jsondumpsr   get_json_type	TypeErrortyperS   r   	is_nested#_preserve_input_structure_in_configr   convert_inner_node_data)	r:   ra   rb   rO   inputs	argumentskwarg_typesri   rg   r	   rh   r   	serialize   sF    




zNode.serializec                 C   s   | j r| jgS | jd S )Nr   )r   r   r    rD   r	   r	   r   input_tensors  s    zNode.input_tensorsc                 C   s   | j r| jgS | jS r   )r   r   rD   r	   r	   r   output_tensors  s    zNode.output_tensorsc                 C   s0   t jtj| j}t|dkr,| js,|d S |S )Nr   r   )r   r   r   r   	int_shaper|   r$   r   )r:   input_shapesr	   r	   r   r     s    zNode.input_shapesc                 C   s   t jtj| jS r   )r   r   r   r   r~   r}   rD   r	   r	   r   output_shapes   s    zNode.output_shapesc                 C   s   | j S r   )r   rD   r	   r	   r   outbound_layer$  s    zNode.outbound_layerc                 C   sD   | j r
g S dd | jD }tjdd |}t|dkr@|d S |S )z2Return all layers that feed into the current node.c                 S   s$   g | ]}t |rt|d r|qS )r5   )r   r%   rR   )r   xr	   r	   r   r   -  s   z'Node.inbound_layers.<locals>.<listcomp>c                 S   s   | j jS r   )r5   r   r
   r	   r	   r   r   3  r   z%Node.inbound_layers.<locals>.<lambda>r   r   )r   r#   r   r   r   r$   )r:   Ztensor_call_argsinbound_layersr	   r	   r   r   (  s    zNode.inbound_layers)NNN)__name__
__module____qualname____doc__rC   propertyr4   rF   rH   rQ   r{   r|   r}   r   r   r   r   r	   r	   r	   r   r   $   s*   
F

S




r   c                   @   s   e Zd ZdZdZdS )r7   a,  Tracks the Layer call that created a Tensor, for Keras Graph Networks.

    During construction of Keras Graph Networks, this metadata is added to
    each Tensor produced as the output of a Layer, starting with an
    `InputLayer`. This allows Keras to track how each Tensor was produced, and
    this information is later retraced by the `keras.engine.Network` class to
    reconstruct the Keras Graph Network.

    Attributes:
      layer: The Layer that produced the Tensor.
      node_index: The specific call to the Layer that produced this Tensor.
        Layers can be called multiple times in order to share weights. A new
        node is created every time a Layer is called. The corresponding node
        that represents the call event that produced the Tensor can be found at
        `layer._inbound_nodes[node_index]`.
      tensor_index: The output index for this Tensor. Always zero if the Layer
        that produced this Tensor only has one output. Nested structures of
        Tensors are deterministically assigned an index via `nest.flatten`.
    r	   N)r   r   r   r   	__slots__r	   r	   r	   r   r7   :  s   r7   r   c                 C   s
   t | dS )Nr5   )rR   )r;   r	   r	   r   r1   X  s    r1   )r   collectionsrJ   rp   numpyrU   tensorflow.compat.v2r'   v2r   kerasr   keras.enginer   keras.saving.saved_modelr   keras.utilsr   r   r[   r   
namedtupler7   r1   r	   r	   r	   r   <module>   s(     
