class_docstr: Multi-Head Attention module
class_docstr_tok: ["Multi-Head","Attention","module"]
code: def forward(self, q, k, v, mask=None):
      d_k, d_v, n_head = self.d_k, self.d_v, self.n_head
      sz_b, len_q, _ = q.shape
      sz_b, len_k, _ = k.shape
      sz_b, len_v, _ = v.shape
      residual = q
  
      q = self.w_qs(q)
      q = paddle.reshape(
          q, shape=[-1, len_q, n_head, d_k]
      )  # 4*21*512 ---- 4*21*8*64
      k = self.w_ks(k)
      k = paddle.reshape(k, shape=[-1, len_k, n_head, d_k])
      v = self.w_vs(v)
      v = paddle.reshape(v, shape=[-1, len_v, n_head, d_v])
  
      q = paddle.transpose(q, perm=[2, 0, 1, 3])
      q = paddle.reshape(q, shape=[-1, len_q, d_k])  # (n*b) x lq x dk
      k = paddle.transpose(k, perm=[2, 0, 1, 3])
      k = paddle.reshape(k, shape=[-1, len_k, d_k])  # (n*b) x lk x dk
      v = paddle.transpose(v, perm=[2, 0, 1, 3])
      v = paddle.reshape(v, shape=[-1, len_v, d_v])  # (n*b) x lv x dv
  
      mask = (
          paddle.tile(mask, [n_head, 1, 1])
          if mask is not None
          else None
      )  # (n*b) x .. x ..
      output = self.attention(q, k, v, mask=mask)
      output = paddle.reshape(output, shape=[n_head, -1, len_q, d_v])
      output = paddle.transpose(output, perm=[1, 2, 0, 3])
      output = paddle.reshape(
          output, shape=[-1, len_q, n_head * d_v]
      )  # b x lq x (n*dv)
      output = self.dropout(self.fc(output))
      output = self.layer_norm(output + residual)
      return output
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import paddle
  from paddle import ParamAttr
  import paddle.nn
  import paddle.nn.functional
  from paddle.nn.initializer import Normal, XavierNormal
  import numpy
label_desc: Use image node_id 2 for calling the MultiHeadAttention obj's underlying member method code with example usage: obj.forward(q, k, v, mask) and returns: output