(self, x)
return x.permute(0, 2, 1, 3).contiguous().view(shape[0], shape[2], shape[3]*self.num_heads)
Merge the extra num_heads into the last dimension
        Input:
            x: a Tensor with shape [batch_size, num_heads, seq_length, depth/num_heads]
        Returns:
            A Tensor with shape [batch_size, seq_length, depth]
Merge the extra num_heads into the last dimension
        Input:
            x: a Tensor with shape [batch_size, num_heads, seq_length, depth/num_heads]
        Returns:
            A Tensor with shape [batch_size, seq_length, depth]
Merge the extra num_heads into the last dimension Input : x : a Tensor with shape [ batch_size num_heads seq_length depth / num_heads ] Returns : A Tensor with shape [ batch_size seq_length depth ]
def _merge_heads(self, x):
        """
        Merge the extra num_heads into the last dimension
        Input:
            x: a Tensor with shape [batch_size, num_heads, seq_length, depth/num_heads]
        Returns:
            A Tensor with shape [batch_size, seq_length, depth]
        """
        if len(x.shape) != 4:
            raise ValueError("x must have rank 4")
        shape = x.shape
        return x.permute(0, 2, 1, 3).contiguous().view(shape[0], shape[2], shape[3]*self.num_heads)
def _merge_heads ( self , x ) : if len ( x . shape ) != 4 : raise ValueError ( "x must have rank 4" ) shape = x . shape return x . permute ( 0 , 2 , 1 , 3 ) . contiguous ( ) . view ( shape [ 0 ] , shape [ 2 ] , shape [ 3 ] * self . num_heads )