B
    d.                 @   s   d Z ddlm  mZ ddlmZ ddlmZ ddlm	Z	 edddgde	d	gdG d
d dZ
dd Zdd Zdd ZdddZdS )zContains the InputSpec class.    N)backend)keras_export)	tf_exportzkeras.layers.InputSpecz*keras.__internal__.legacy.layers.InputSpec)Zv1zlayers.InputSpecc               @   s6   e Zd ZdZdddZdd Zdd	 Zed
d ZdS )	InputSpeca\  Specifies the rank, dtype and shape of every input to a layer.

    Layers can expose (if appropriate) an `input_spec` attribute:
    an instance of `InputSpec`, or a nested structure of `InputSpec` instances
    (one per input tensor). These objects enable the layer to run input
    compatibility checks for input structure, input rank, input shape, and
    input dtype.

    A None entry in a shape is compatible with any dimension,
    a None shape is compatible with any shape.

    Args:
      dtype: Expected DataType of the input.
      shape: Shape tuple, expected shape of the input
        (may include None for unchecked axes). Includes the batch size.
      ndim: Integer, expected rank of the input.
      max_ndim: Integer, maximum rank of the input.
      min_ndim: Integer, minimum rank of the input.
      axes: Dictionary mapping integer axes to
        a specific dimension value.
      allow_last_axis_squeeze: If True, then allow inputs of rank N+1 as long
        as the last axis of the input is 1, as well as inputs of rank N-1
        as long as the last axis of the spec is 1.
      name: Expected key corresponding to this input when passing data as
        a dictionary.

    Example:

    ```python
    class MyLayer(Layer):
        def __init__(self):
            super(MyLayer, self).__init__()
            # The layer will accept inputs with
            # shape (?, 28, 28) & (?, 28, 28, 1)
            # and raise an appropriate error message otherwise.
            self.input_spec = InputSpec(
                shape=(None, 28, 28, 1),
                allow_last_axis_squeeze=True)
    ```
    NFc	          	      s"  |d k	rt |jnd | _t |}|jd kr4d }nt| }|d k	rZt|| _	|| _
n|| _	d | _
|| _|| _|| _|| _y  pi   fdd D | _W n& ttfk
r   td  Y nX | jr| j	d k	s| jd k	r| j	r| j	n| jd }	t| j}
|
|	krtd|
|	d S )Nc                s   i | ]} | t |qS  )int).0k)axesr   I/var/www/html/venv/lib/python3.7/site-packages/keras/engine/input_spec.py
<dictcomp>h   s    z&InputSpec.__init__.<locals>.<dictcomp>zAArgument `axes` must be a dict with integer keys. Received: axes=   z5Axis {} is greater than the maximum allowed value: {})tfZas_dtypenamedtypeTensorShaperanktupleas_listlenndimshapemax_ndimmin_ndimallow_last_axis_squeezer
   
ValueError	TypeErrormaxformat)selfr   r   r   r   r   r
   r   r   Zmax_dimZmax_axisr   )r
   r   __init__K   s6    




zInputSpec.__init__c             C   s   | j rdt| j  nd| jr*dt| j nd| jr@dt| j nd| jrVdt| j nd| jrldt| j nd| jrdt| j ndg}dd	d
d |D  dS )Nzdtype= zshape=zndim=z	max_ndim=z	min_ndim=zaxes=z
InputSpec(z, c             s   s   | ]}|r|V  qd S )Nr   )r   xr   r   r   	<genexpr>   s    z%InputSpec.__repr__.<locals>.<genexpr>))r   strr   r   r   r   r
   join)r   specr   r   r   __repr__x   s    zInputSpec.__repr__c             C   s   | j | j| j| j| j| jdS )N)r   r   r   r   r   r
   )r   r   r   r   r   r
   )r   r   r   r   
get_config   s    zInputSpec.get_configc             C   s
   | f |S )Nr   )clsconfigr   r   r   from_config   s    zInputSpec.from_config)NNNNNNFN)	__name__
__module____qualname____doc__r    r(   r)   classmethodr,   r   r   r   r   r      s   -       
$
r   c             C   sl   | j dkr| jdkrtdS | jdk	r4t| jS dg| j  }x| jD ]}| j| ||< qHW t|S dS )a@  Returns a tf.TensorShape object that matches the shape specifications.

    If the InputSpec's shape or ndim is defined, this method will return a fully
    or partially-known shape. Otherwise, the returned TensorShape is None.

    Args:
      spec: an InputSpec object.

    Returns:
      a tf.TensorShape object
    N)r   r   r   r   r
   )r'   r   ar   r   r   to_tensor_shape   s    

r3   c             C   s  | sdS t j| } t|trdd | D }t|rg }xD|D ]<}||krltd| dt|  d| |	||  q>W |}t j|}x$|D ]}t
|dstd| qW t|t| krtd	| d
t|  dt| d| xtt|| D ]\}\}}|dkrqt |j}	|	jdkr4dS |jdk	r|js|	j}
|
|jkrtd| d| d|j d|
 dt|	 
|jdk	r|jj}
|
dk	r|
|jkrtd| d| d|j d|
 |jdk	r(|jj}
|
dk	r(|
|jk r(td| d| d|j d|
 dt|	 
|jdk	rh|jj|jkrhtd| d| d|j d|j |	 }|jrxv|j D ]h\}}t
|dr|j}|dk	r|t| |dhkrtd| d| d| d| dt|j 
qW |jdk	r|	jdk	r|j}|jrR|r2|d dkr2|dd }|rR|d dkrR|dd }x^t||D ]P\}}|dk	r^|dk	r^||kr^td| d| d|j dt|j q^W qW dS )a  Checks compatibility between the layer and provided inputs.

    This checks that the tensor(s) `inputs` verify the input assumptions
    of a layer (if any). If not, a clear and actional exception gets raised.

    Args:
        input_spec: An InputSpec instance, list of InputSpec instances, a nested
            structure of InputSpec instances, or None.
        inputs: Input tensor, list of input tensors, or a nested structure of
            input tensors.
        layer_name: String, name of the layer (for error message formatting).

    Raises:
        ValueError: in case of mismatch between
            the provided inputs and the expectations of the layer.
    Nc             S   s   g | ]
}|j qS r   )r   )r   r'   r   r   r   
<listcomp>   s    z.assert_input_compatibility.<locals>.<listcomp>zMissing data for input "z*". You passed a data dictionary with keys z. Expected the following keys: r   z*Inputs to a layer should be tensors. Got: zLayer "z
" expects z input(s), but it received z! input tensors. Inputs received: zInput z of layer "z0" is incompatible with the layer: expected ndim=z, found ndim=z. Full shape received: z4" is incompatible with the layer: expected max_ndim=z4" is incompatible with the layer: expected min_ndim=z1" is incompatible with the layer: expected dtype=z, found dtype=valuez0" is incompatible with the layer: expected axis z of input shape to have value z , but received input with shape r   z1" is incompatible with the layer: expected shape=z, found shape=)r   nestflatten
isinstancedictallr   listkeysappendhasattrr   r   	enumeratezipr   r   r   r   r   r   r   r   r   r   r   r
   itemsr5   r   display_shape)
input_specinputsZ
layer_namenamesZlist_inputsr   r"   Zinput_indexr'   r   r   Zshape_as_listZaxisr5   Z
spec_shapeZspec_dimdimr   r   r   assert_input_compatibility   s    

 

& 
* *"
0
rH   c             C   s   t t|  S )N)r%   r   r   )r   r   r   r   rC   /  s    rC   c             C   s<   |p
t  }t| tr0| jp|}tt| |S td|S )z2Converts a Keras InputSpec object to a TensorSpec.N)r   Zfloatxr9   r   r   r   Z
TensorSpecr3   )rD   Zdefault_dtyper   r   r   r   to_tensor_spec3  s
    

rI   )N)r0   Ztensorflow.compat.v2compatZv2r   Zkerasr   Z tensorflow.python.util.tf_exportr   r   r   r3   rH   rC   rI   r   r   r   r   <module>   s   
r 