B
    ӻd+                 @   s   d 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 e
d	ed
gdG dd deZdd Zdd Zdd ZdddZdS )zContains the InputSpec class.    )dtypes)tensor_shape)tensor_spec)backend)nest)keras_export)	tf_exportzkeras.layers.InputSpeczlayers.InputSpec)Zv1c               @   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
   [/var/www/html/venv/lib/python3.7/site-packages/tensorflow/python/keras/engine/input_spec.py
<dictcomp>b   s    z&InputSpec.__init__.<locals>.<dictcomp>z"The keys in axes must be integers.   z5Axis {} is greater than the maximum allowed value: {})r   Zas_dtypenamedtyper   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__G   s2    	




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  S )Nzdtype= zshape=zndim=z	max_ndim=z	min_ndim=zaxes=zInputSpec(%s)z, c             s   s   | ]}|r|V  qd S )Nr
   )r   xr
   r
   r   	<genexpr>t   s    z%InputSpec.__repr__.<locals>.<genexpr>)r   strr   r   r   r   r   join)r"   specr
   r
   r   __repr__m   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_configv   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 )a2  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    

r5   c             C   s0  | sdS t | } t|trxdd | D }t|rxg }x<|D ]4}||krbtd|t| |f |||  q<W |}t |}x$|D ]}t	|dst
d|f qW t|t| krtd| d tt|  d	 tt| d
 t| x8tt|| D ]$\}\}}|dkrqt|j}	|	jdkr:dS |jdk	r|js|	j}
|
|jkrtdt| d | d t|j d t|
 d tt|	 |jdk	r|jj}
|
dk	r|
|jkrtdt| d | d t|j d t|
 |jdk	rj|jj}
|
dk	rj|
|jk rjtdt| d | d t|j d t|
 d tt|	 |jdk	r|jj|jkrtdt| d | d t|j d t|j |	 }|jrTx|j D ]z\}}t	|dr|j}|dk	r|t| |dhkrtdt| d | d t| d t| d t|j qW |jdk	r|	jdk	r|j}|jr|r|d dkr|dd }|r|d dkr|dd }xjt||D ]\\}}|dk	r|dk	r||krtdt| d | d t|j d t|j qW qW 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>zgMissing data for input "%s". You passed a data dictionary with keys %s. Expected the following keys: %sr   z,Inputs to a layer should be tensors. Got: %szLayer z	 expects z input(s), but it received z! input tensors. Inputs received: zInput z
 of layer z/ is incompatible with the layer: expected ndim=z, found ndim=z. Full shape received: z3 is incompatible with the layer: expected max_ndim=z5 is incompatible with the layer: : expected min_ndim=z0 is incompatible with the layer: expected dtype=z, found dtype=valuez/ is incompatible with the layer: expected axis z of input shape to have value z but received input with shape r   z is incompatible with layer z: expected shape=z, found shape=) r   flatten
isinstancedictallr   listkeysappendhasattrr   r   r'   	enumeratezipr   r   r   r   r   r   r   r   r   r   r   r   r   itemsr7   r   display_shape)
input_specinputsZ
layer_namenamesZlist_inputsr   r%   Zinput_indexr)   r   r   Zshape_as_listZaxisr7   Z
spec_shapeZspec_dimdimr
   r
   r   assert_input_compatibility   s    





6 
0002 B
rI   c             C   s   t t|  S )N)r'   r   r   )r   r
   r
   r   rD     s    rD   Nc             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floatxr:   r	   r   r   Z
TensorSpecr5   )rE   Zdefault_dtyper   r
   r
   r   to_tensor_spec  s
    

rJ   )N)r2   Ztensorflow.python.frameworkr   r   r   Ztensorflow.python.kerasr   Ztensorflow.python.utilr   Z tensorflow.python.util.tf_exportr   r   objectr	   r5   rI   rD   rJ   r
   r
   r
   r   <module>   s   
fv