o
    Me.                     @   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)v1zlayers.InputSpecc                   @   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sm| jd ur| j	rs| 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   GD:\Projects\ConvertPro\env\Lib\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   sD   



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  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   
get_config   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-   classmethodr0   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 )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   



r7   c                 C   s  | sdS t j| } t|tr?dd | D }t|r?g }|D ]}||vr5td| dt|  d| |	||  q|}t j|}|D ]}t
|dsUtd| qGt|t| krrtd	| d
t|  dt| d| tt|| D ]P\}\}}|du rqyt |j}	|	jdu r dS |jdur|js|	j}
|
|jkrtd| d| d|j d|
 dt|	 
|jdur|jj}
|
dur|
|jkrtd| d| d|j d|
 |jdur|jj}
|
dur|
|jk rtd| d| d|j d|
 dt|	 
|jdur'|jj|jkr'td| d| d|j d|j |	 }|jri|j D ]4\}}t
|drA|j}|durg|t| |dhvrgtd| d| d| d| dt|j 
q4|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| d| d|j dt|j qqyd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   itemsr9   r   display_shape)
input_specZinputsZ
layer_namenamesZlist_inputsr   r%   Zinput_indexr*   r   r   Zshape_as_listZaxisr9   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   c                 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
TensorSpecr7   )rH   Zdefault_dtyper   r   r   r   to_tensor_spec3  s
   

rL   r$   )r4   Ztensorflow.compat.v2compatv2r   Zkerasr   Z tensorflow.python.util.tf_exportr   r   r   r7   rK   rG   rL   r   r   r   r   <module>   s    
q 