(self, x)
return x.view(shape[0], shape[1], self.num_heads, shape[2]//self.num_heads).permute(0, 2, 1, 3)
Split x such to add an extra num_heads dimension
        Input:
            x: a Tensor with shape [batch_size, seq_length, depth]
        Returns:
            A Tensor with shape [batch_size, num_heads, seq_length, depth/num_heads]
Split x such to add an extra num_heads dimension
        Input:
            x: a Tensor with shape [batch_size, seq_length, depth]
        Returns:
            A Tensor with shape [batch_size, num_heads, seq_length, depth/num_heads]
Split x such to add an extra num_heads dimension Input : x : a Tensor with shape [ batch_size seq_length depth ] Returns : A Tensor with shape [ batch_size num_heads seq_length depth / num_heads ]
def _split_heads(self, x):
        """
        Split x such to add an extra num_heads dimension
        Input:
            x: a Tensor with shape [batch_size, seq_length, depth]
        Returns:
            A Tensor with shape [batch_size, num_heads, seq_length, depth/num_heads]
        """
        if len(x.shape) != 3:
            raise ValueError("x must have rank 3")
        shape = x.shape
        return x.view(shape[0], shape[1], self.num_heads, shape[2]//self.num_heads).permute(0, 2, 1, 3)
def _split_heads ( self , x ) : if len ( x . shape ) != 3 : raise ValueError ( "x must have rank 3" ) shape = x . shape return x . view ( shape [ 0 ] , shape [ 1 ] , self . num_heads , shape [ 2 ] // self . num_heads ) . permute ( 0 , 2 , 1 , 3 )