B
    dh                  @   s   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 ddlmZ edG d	d
 d
e
ZeddddZdS )z7Layer that computes the dot product between two inputs.    N)backend)base_layer_utils)_Merge)tf_utils)keras_exportzkeras.layers.Dotc                   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 )Dota  Layer that computes a dot product between samples in two tensors.

    E.g. if applied to a list of two tensors `a` and `b` of shape
    `(batch_size, n)`, the output will be a tensor of shape `(batch_size, 1)`
    where each entry `i` will be the dot product between
    `a[i]` and `b[i]`.

    >>> x = np.arange(10).reshape(1, 5, 2)
    >>> print(x)
    [[[0 1]
      [2 3]
      [4 5]
      [6 7]
      [8 9]]]
    >>> y = np.arange(10, 20).reshape(1, 2, 5)
    >>> print(y)
    [[[10 11 12 13 14]
      [15 16 17 18 19]]]
    >>> tf.keras.layers.Dot(axes=(1, 2))([x, y])
    <tf.Tensor: shape=(1, 2, 2), dtype=int64, numpy=
    array([[[260, 360],
            [320, 445]]])>

    >>> 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))
    >>> dotted = tf.keras.layers.Dot(axes=1)([x1, x2])
    >>> dotted.shape
    TensorShape([5, 1])


    Fc                s   t  jf | t|tsxt|ttfs4td| t|dkrNtd| t|d trjt|d tsxtd| || _	|| _
d| _d| _d	S )
a  Initializes a layer that computes the element-wise dot product.

          >>> x = np.arange(10).reshape(1, 5, 2)
          >>> print(x)
          [[[0 1]
            [2 3]
            [4 5]
            [6 7]
            [8 9]]]
          >>> y = np.arange(10, 20).reshape(1, 2, 5)
          >>> print(y)
          [[[10 11 12 13 14]
            [15 16 17 18 19]]]
          >>> tf.keras.layers.Dot(axes=(1, 2))([x, y])
          <tf.Tensor: shape=(1, 2, 2), dtype=int64, numpy=
          array([[[260, 360],
                  [320, 445]]])>

        Args:
          axes: Integer or tuple of integers,
            axis or axes along which to take the dot product. If a tuple, should
            be two integers corresponding to the desired axis from the first
            input and the desired axis from the second input, respectively. Note
            that the size of the two selected axes must match.
          normalize: Whether to L2-normalize samples along the
            dot product axis before taking the dot product.
            If set to True, then the output of the dot product
            is the cosine proximity between the two samples.
          **kwargs: Standard layer keyword arguments.
        zPInvalid type for argument `axes`: it should be a list or an int. Received: axes=   zSInvalid format for argument `axes`: it should contain two elements. Received: axes=r      zUInvalid format for argument `axes`: list elements should be integers. Received: axes=TFN)super__init__
isinstanceintlisttuple	TypeErrorlen
ValueErroraxes	normalizeZsupports_maskingZ_reshape_required)selfr   r   kwargs)	__class__ J/var/www/html/venv/lib/python3.7/site-packages/keras/layers/merging/dot.pyr   ?   s    
zDot.__init__c             C   s   t |d trt|dkr(td| |d }|d }|d ksH|d krLd S t | jtr| jdk r| jt| | jt| g}q| jgd }n| j}||d  ||d  krtd||d   d|d  d||d   d|d  d| d	| d S )
Nr   r   zLA `Dot` layer should be called on a list of 2 inputs. Received: input_shape=r	   z'Incompatible input shapes: axis values z
 (at axis z) != z). Full input shapes: z, )r   r   r   r   r   r   )r   input_shapeshape1shape2r   r   r   r   buildt   s    
z	Dot.buildc             C   s  t || j t|dkr(td| |d }|d }t| jtr~| jdk rp| jt	| | jt	| g}q| jgd }nZg }xTt
t| jD ]B}| j| dk r|| j| t	||   q|| j|  qW | jrtjj||d d}tjj||d d}t|||}|S )Nr   zEA `Dot` layer should be called on exactly 2 inputs. Received: inputs=r   r	   )Zaxis)r   Zno_ragged_supportnamer   r   r   r   r   r   ndimrangeappendr   tfZlinalgZl2_normalizeZ	batch_dot)r   inputsx1Zx2r   ioutputr   r   r   _merge_function   s*    
 zDot._merge_functionc             C   s   t |ttfrt|dkr(td| t|d }t|d }t | jtr| jdk rt| jt| | jt| g}q| jgd }n| j}||d  ||d  |d || }t|dkr|dg7 }t|S )Nr   zLA `Dot` layer should be called on a list of 2 inputs. Received: input_shape=r   r	   )r   r   r   r   r   r   r   pop)r   r   r   r   r   Zoutput_shaper   r   r   compute_output_shape   s"    


zDot.compute_output_shapeNc             C   s   d S )Nr   )r   r#   maskr   r   r   compute_mask   s    zDot.compute_maskc                s4   | j | jd}t  }tt| t|  S )N)r   r   )r   r   r
   
get_configdictr   items)r   configZbase_config)r   r   r   r,      s    

zDot.get_config)F)N)__name__
__module____qualname____doc__r   r   Zshape_type_conversionr   r'   r)   r+   r,   __classcell__r   r   )r   r   r      s    5
r   zkeras.layers.dotFc             K   s   t f ||d|| S )aQ  Functional interface to the `Dot` layer.

    Args:
        inputs: A list of input tensors (at least 2).
        axes: Integer or tuple of integers,
            axis or axes along which to take the dot product.
        normalize: Whether to L2-normalize samples along the
            dot product axis before taking the dot product.
            If set to True, then the output of the dot product
            is the cosine proximity between the two samples.
        **kwargs: Standard layer keyword arguments.

    Returns:
        A tensor, the dot product of the samples from the inputs.
    )r   r   )r   )r#   r   r   r   r   r   r   dot   s    r5   )F)r3   Ztensorflow.compat.v2compatZv2r"   Zkerasr   Zkeras.enginer   Zkeras.layers.merging.base_merger   Zkeras.utilsr   Z tensorflow.python.util.tf_exportr   r   r5   r   r   r   r   <module>   s    4