o
    7?e!                     @   st   d Z ddlm  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d	 d	eZed
dddZdS )z'Layer that concatenates several inputs.    N)backend)_Merge)tf_utils)keras_exportzkeras.layers.Concatenatec                       s\   e Zd ZdZd fdd	Zejdd Zdd Zejd	d
 Z	dddZ
 fddZ  ZS )Concatenatea  Layer that concatenates a list of inputs.

    It takes as input a list of tensors, all of the same shape except
    for the concatenation axis, and returns a single tensor that is the
    concatenation of all inputs.

    >>> x = np.arange(20).reshape(2, 2, 5)
    >>> print(x)
    [[[ 0  1  2  3  4]
      [ 5  6  7  8  9]]
     [[10 11 12 13 14]
      [15 16 17 18 19]]]
    >>> y = np.arange(20, 30).reshape(2, 1, 5)
    >>> print(y)
    [[[20 21 22 23 24]]
     [[25 26 27 28 29]]]
    >>> tf.keras.layers.Concatenate(axis=1)([x, y])
    <tf.Tensor: shape=(2, 3, 5), dtype=int64, numpy=
    array([[[ 0,  1,  2,  3,  4],
            [ 5,  6,  7,  8,  9],
            [20, 21, 22, 23, 24]],
           [[10, 11, 12, 13, 14],
            [15, 16, 17, 18, 19],
            [25, 26, 27, 28, 29]]])>

    >>> x1 = tf.keras.layers.Dense(8)(np.arange(10).reshape(5, 2))
    >>> x2 = tf.keras.layers.Dense(8)(np.arange(10, 20).reshape(5, 2))
    >>> concatted = tf.keras.layers.Concatenate()([x1, x2])
    >>> concatted.shape
    TensorShape([5, 16])

    c                    s(   t  jdi | || _d| _d| _dS )a.  Instantiates a Concatenate layer.

        >>> x = np.arange(20).reshape(2, 2, 5)
        >>> print(x)
        [[[ 0  1  2  3  4]
          [ 5  6  7  8  9]]
         [[10 11 12 13 14]
          [15 16 17 18 19]]]
        >>> y = np.arange(20, 30).reshape(2, 1, 5)
        >>> print(y)
        [[[20 21 22 23 24]]
         [[25 26 27 28 29]]]
        >>> tf.keras.layers.Concatenate(axis=1)([x, y])
        <tf.Tensor: shape=(2, 3, 5), dtype=int64, numpy=
        array([[[ 0,  1,  2,  3,  4],
                [ 5,  6,  7,  8,  9],
                [20, 21, 22, 23, 24]],
               [[10, 11, 12, 13, 14],
                [15, 16, 17, 18, 19],
                [25, 26, 27, 28, 29]]])>

        Args:
          axis: Axis along which to concatenate.
          **kwargs: standard layer keyword arguments.
        TFN )super__init__axisZsupports_maskingZ_reshape_required)selfr   kwargs	__class__r   e/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/keras/src/layers/merging/concatenate.pyr
   ?   s   
zConcatenate.__init__c           	         s  t |dk st|d tstd| tdd |D rd S dd |D }t }tt |D ]}|| | j= |t||  q/t |dkr~d| }td	d |D }t |dkr_t||\}t|D ] t fd
d|D }t |dkr}t|qfd S d S )N   r   z\A `Concatenate` layer should be called on a list of at least 1 input. Received: input_shape=c                 s       | ]}|d u V  qd S Nr   .0shaper   r   r   	<genexpr>f       z$Concatenate.build.<locals>.<genexpr>c                 S   s   g | ]}t |qS r   )listr   r   r   r   
<listcomp>h   s    z%Concatenate.build.<locals>.<listcomp>ztA `Concatenate` layer requires inputs with matching shapes except for the concatenation axis. Received: input_shape=c                 s   s    | ]}t |V  qd S r   )lenr   r   r   r   r   u   r   c                 3   s$    | ]}|  d ur|  V  qd S r   r   r   r   r   r   r   }   s    

)	r   
isinstancetuple
ValueErrorallsetranger   add)	r   input_shapeZreduced_inputs_shapesZ	shape_setierr_msgZranksZrankZunique_dimsr   r   r   build^   s>   zConcatenate.buildc                 C   s   t j|| jdS )Nr   )r   concatenater   )r   inputsr   r   r   _merge_function   s   zConcatenate._merge_functionc                 C   s   t |ttfrt |d ttfstd| |}t|d }|dd  D ]&}|| j d u s5|| j d u r?d || j<  t|S || j  || j 7  < q%t|S )Nr   zRA `Concatenate` layer should be called on a list of inputs. Received: input_shape=r   )r   r   r   r   r   )r   r$   Zinput_shapesZoutput_shaper   r   r   r   compute_output_shape   s"   
z Concatenate.compute_output_shapeNc              
   C   s  |d u rd S t |ttfstd| t |ttfs"td| t|t|kr>td| dt| d| dt| tdd |D rId S g }t||D ]-\}}|d u rc|tj	|dd	 qPt
|t
|k rx|tj|d
d qP|| qPt
j|| jd}t
j|d
ddS )Nz'`mask` should be a list. Received mask=z,`inputs` should be a list. Received: inputs=zLThe lists `inputs` and `mask` should have the same length. Received: inputs=z of length z, and mask=c                 s   r   r   r   )r   mr   r   r   r      r   z+Concatenate.compute_mask.<locals>.<genexpr>bool)Zdtyper   r   F)r   Zkeepdims)r   r   r   r   r   r    zipappendtfZ	ones_liker   ndimZexpand_dimsr(   r   )r   r)   maskmasksZinput_iZmask_iZconcatenatedr   r   r   compute_mask   s>   zConcatenate.compute_maskc                    s0   d| j i}t  }tt| t|  S )Nr   )r   r	   
get_configdictr   items)r   configZbase_configr   r   r   r5      s   
zConcatenate.get_configr   r   )__name__
__module____qualname____doc__r
   r   Zshape_type_conversionr'   r*   r+   r4   r5   __classcell__r   r   r   r   r      s    !
&

!r   zkeras.layers.concatenater   c                 K   s   t dd|i|| S )av  Functional interface to the `Concatenate` layer.

    >>> x = np.arange(20).reshape(2, 2, 5)
    >>> print(x)
    [[[ 0  1  2  3  4]
      [ 5  6  7  8  9]]
     [[10 11 12 13 14]
      [15 16 17 18 19]]]
    >>> y = np.arange(20, 30).reshape(2, 1, 5)
    >>> print(y)
    [[[20 21 22 23 24]]
     [[25 26 27 28 29]]]
    >>> tf.keras.layers.concatenate([x, y],
    ...                             axis=1)
    <tf.Tensor: shape=(2, 3, 5), dtype=int64, numpy=
    array([[[ 0,  1,  2,  3,  4],
          [ 5,  6,  7,  8,  9],
          [20, 21, 22, 23, 24]],
         [[10, 11, 12, 13, 14],
          [15, 16, 17, 18, 19],
          [25, 26, 27, 28, 29]]])>

    Args:
        inputs: A list of input tensors.
        axis: Concatenation axis.
        **kwargs: Standard layer keyword arguments.

    Returns:
        A tensor, the concatenation of the inputs alongside axis `axis`.
    r   Nr   )r   )r)   r   r   r   r   r   r(      s    r(   r9   )r=   Ztensorflow.compat.v2compatv2r0   Z	keras.srcr   Z#keras.src.layers.merging.base_merger   Zkeras.src.utilsr   Z tensorflow.python.util.tf_exportr   r   r(   r   r   r   r   <module>   s    +