o
    ?e+                     @   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
 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)	tf_exportzlayers.InputSpec)v1c                   @   sF   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 ur
t |jnd | _t|}|jd u rd }nt| }|d ur-t	|| _
|| _n|| _
d | _|| _|| _|| _|| _z pCi   fdd D | _W n ttfy\   tdw | jr| j
d usj| jd ur| j
rp| j
n| jd }	t| j}
|
|	krtd|
|	d S d S d S )Nc                    s   i | ]	}t | | qS  )int).0kaxesr
   j/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/keras/engine/input_spec.py
<dictcomp>`   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__E   s:   	



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r+dt| j nd| jr6dt| j nd| jrAd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>r   s    z%InputSpec.__repr__.<locals>.<genexpr>)r   strr   r   r   r   r   join)r#   specr
   r
   r   __repr__k   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   
get_configt   s   zInputSpec.get_configc                 C   s   | di |S )Nr
   r
   )clsconfigr
   r
   r   from_config}   s   zInputSpec.from_config)NNNNNNFN)	__name__
__module____qualname____doc__r$   r,   r.   classmethodr1   r
   r
   r
   r   r	      s    )
&		r	   c                 C   sd   | j du r| jdu rtdS | jdurt| jS dg| j  }| jD ]	}| j| ||< q#t|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   



r8   c                 C   s  | sdS t | } t|tr:dd | D }t|r:g }|D ]}||vr0td|t| |f |||  q|}t |}|D ]}t	|dsOt
d|f qAt|t| krttd| d tt|  d	 tt| d
 t| tt|| D ]\}\}}|du rq{t|j}	|	jdu r dS |jdur|js|	j}
|
|jkrtdt| d | d t|j d t|
 d tt|	 |jdur|jj}
|
dur|
|jkrtdt| d | d t|j d t|
 |jdur'|jj}
|
dur'|
|jk r'tdt| d | d t|j d t|
 d tt|	 |jdurO|jj|jkrOtdt| d | d t|j d t|j |	 }|jr|j D ]=\}}t	|dri|j}|dur|t| |dhvrtdt| d | d t| d t| d t|j q\|jdur|	jdur|j}|jr|r|d dkr|dd }|r|d dkr|dd }t||D ].\}}|dur|dur||krtdt| d | d t|j d t|j qq{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   itemsr:   r   display_shape)
input_specZinputsZ
layer_namenamesZlist_inputsr   r'   Zinput_indexr+   r   r   Zshape_as_listZaxisr:   Z
spec_shapeZspec_dimdimr
   r
   r   assert_input_compatibility   s"  










 
rK   c                 C   s   t t|  S r&   )r)   r   r   )r   r
   r
   r   rG     s   rG   Nc                 C   s<   |pt  }t| tr| jp|}tt| |S td|S )z2Converts a Keras InputSpec object to a TensorSpec.N)r   Zfloatxr=   r	   r   r   Z
TensorSpecr8   )rH   Zdefault_dtyper   r
   r
   r   to_tensor_spec  s
   

rL   r&   )r5   Ztensorflow.python.frameworkr   r   r   Ztensorflow.python.kerasr   Ztensorflow.python.utilr   Z tensorflow.python.util.tf_exportr   objectr	   r8   rK   rG   rL   r
   r
   r
   r   <module>   s   
fv