B
    ӻd+              	   @   s   d Z 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
ZG dd dZG dd deddddgZdd ZdS )zContains the `Node` class.    N)ops)tensor_util)backend)base_layer_utils)
json_utils)tf_utils)nest_CONSTANT_VALUEc               @   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 the connectivity between two layers.

  Each time a layer is connected to some new input,
  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`.

  Args:
      layer: The Layer for the Layer.__call__ 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 outputs of the Layer.__call__
  Nc             C   s   |d krg n|}|d kri n|}|d kr,g n|}|| _ | o@| | _tdd |}tdd |}tdd || _|| _|| _t| j| jf| _| j ot	| jdkot
| jd | _t sx2| jD ](}t|tjrtj|ddrt| qW g | _g | _xNt| jD ]@\}}t|r| j| tt|}|}	| j||	f qW | j j|  x.| jD ]$}
|
jj }|d k	rl|j|  qlW t	| j jd }x,tt|D ]\}}t|||d	|_qW d
d | jD | _ dd t| jD | _!d S )Nc             S   s   | S )N )tr   r   U/var/www/html/venv/lib/python3.7/site-packages/tensorflow/python/keras/engine/node.py<lambda>D       zNode.__init__.<locals>.<lambda>c             S   s   | S )Nr   )r   r   r   r   r   E   r   c             S   s   | S )Nr   )r   r   r   r   r   F   r      r   T)Zignore_call_context)layer
node_indextensor_indexc             S   s   g | ]}t t|qS r   )strid).0r   r   r   r   
<listcomp>o   s    z!Node.__init__.<locals>.<listcomp>c             S   s   g | ]}t t|qS r   )r   r   )r   r   r   r   r   r   p   s    )"r   is_inputr   map_structureoutputs	call_argscall_kwargsflatten_flat_argumentslenr   Z
is_tf_type _single_positional_tensor_passedr   Z#executing_eagerly_outside_functions
isinstanceTensorr   Zneeds_keras_historyZcreate_keras_history_keras_inputs_keras_inputs_ids_and_indices	enumerateis_keras_tensorappendr   r   _inbound_nodeskeras_inputs_keras_historyZ_outbound_nodesKerasHistoryZflat_input_idsZflat_output_ids)selfr   r   r   r   objiZelekt_idkt_indexktZinbound_layerr   Ztensorr   r   r   __init__2   sL    



zNode.__init__c             C   s   | j S )zFTensors input to this node that can be traced back to a `keras.Input`.)r#   )r,   r   r   r   r)   r   s    zNode.keras_inputsc             C   s@   g }x6| j D ],}|jj}|jj}|dk	r||j|  qW |S )zFReturns all the `Node`s whose output this node immediately depends on.N)r)   r*   r   r   r'   r(   )r,   Z	node_depsr1   r   r   r   r   r   parent_nodesw   s    zNode.parent_nodesc             c   s:   x4| j D ]*}|j}|j}|j}|j}||||fV  qW dS )zYields tuples representing the data inbound from other nodes.

    Yields:
      tuples like: (inbound_layer, node_index, tensor_index, tensor).
    N)r)   r*   r   r   r   )r,   r1   Zkeras_historyr   r   r   r   r   r   iterate_inbound   s    zNode.iterate_inboundc             C   sz   | j r&| jd \}}||  fi fS t| j}x"| jD ]\}}||  ||< q:W t| j| jf|\}}||fS dS )z;Maps Keras Tensors to computed Tensors using `tensor_dict`.r   N)	r    r$   popcopyr   r   Zpack_sequence_asr   r   )r,   Ztensor_dictr/   _Zflat_argumentsr0   argskwargsr   r   r   map_arguments   s    
zNode.map_argumentsc       	         s  | j | j }| j|\}}tt| jjdd |}| |fdd t	 yt
jtjd W nD tk
r   t	t}td| jj d d t| d	 Y nX  fd
d}t	||}t|s| jjs|g}t|}|S )z4Serializes `Node` for Functional API's `get_config`.r   Nc                sr   t | dr@| j}|j} |jj|}|d}|jj||jgS t| tj	rT| 
 S t| tjrnt| 
 S | S )z,Serializes a single Tensor passed to `call`.r*   r   )hasattrr*   r   r   namegetr   r!   npZndarraytolistr   r"   r   	get_value)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   )
r&   r*   r   r   r<   r=   r   r	   r   ZListWrapper)r   rA   r   rB   rC   data)rF   r9   rD   rE   r   r   serialize_first_arg_tensor   s    z2Node.serialize.<locals>.serialize_first_arg_tensor)r   r   r   Z_split_out_first_argdictzipZ_call_fn_argsupdater   r   jsondumpsr   Zget_json_type	TypeErrortyper<   r   Z	is_nestedZ#_preserve_input_structure_in_configr   Zconvert_inner_node_data)	r,   rD   rE   r8   inputs	argumentsZkwarg_typesrJ   rI   r   )rF   r9   rD   rE   r   	serialize   s(    
(

zNode.serializec             C   s   | j r| jgS | jd S )Nr   )r   r   r   )r,   r   r   r   input_tensors   s    zNode.input_tensorsc             C   s   | j r| jgS | jS )N)r   r   )r,   r   r   r   output_tensors   s    zNode.output_tensorsc             C   s.   t tj| j}t|dkr*| js*|d S |S )Nr   r   )r   r   r   	int_shaperU   r   r   )r,   input_shapesr   r   r   rX      s    zNode.input_shapesc             C   s   t tj| jS )N)r   r   r   rW   rV   )r,   r   r   r   output_shapes   s    zNode.output_shapesc             C   s   | j S )N)r   )r,   r   r   r   outbound_layer   s    zNode.outbound_layerc             C   s$   | j r
g S tdd | jd }|S )Nc             S   s   | j jS )N)r*   r   )r   r   r   r   r     r   z%Node.inbound_layers.<locals>.<lambda>r   )r   r   r   r   )r,   inbound_layersr   r   r   r[      s
    
zNode.inbound_layers)NNN)__name__
__module____qualname____doc__r2   propertyr)   r3   r4   r:   rT   rU   rV   rX   rY   rZ   r[   r   r   r   r   r
   #   s     
<Er
   c               @   s   e Zd ZdZdZdS )r+   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.
    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   r+     s   r+   r   r   r   c             C   s
   t | dS )Nr*   )r;   )r-   r   r   r   r&      s    r&   )r_   collectionsr6   rN   numpyr>   Ztensorflow.python.frameworkr   r   Ztensorflow.python.kerasr   Ztensorflow.python.keras.enginer   Z*tensorflow.python.keras.saving.saved_modelr   Ztensorflow.python.keras.utilsr   Ztensorflow.python.utilr   r	   r
   
namedtupler+   r&   r   r   r   r   <module>   s$    e
