code: def forward(self, query, key, value, mask=None):
      batch_size = query.size(0)
  
      # project and reshaping
      k_project = self.k_proj(key)
      q_project = self.q_proj(query)
      v_project = self.v_proj(value)
      k_reshape = k_project.view(
          batch_size, -1, self.n_heads, self.head_dim
      ).transpose(1, 2)
      q_reshape = q_project.view(
          batch_size, -1, self.n_heads, self.head_dim
      ).transpose(1, 2)
      v_reshape = v_project.view(
          batch_size, -1, self.n_heads, self.head_dim
      ).transpose(1, 2)
  
      # merge heads and output
      scores = attention(
          q_reshape, k_reshape, v_reshape, mask, self.dropout
      )
      scores = scores.transpose(1, 2).contiguous()
      scores = scores.view(batch_size, -1, self.hidden_dim)
  
      return self.output_proj(scores)
  
imports: import torch
  import torch.nn
  import torch.nn.functional
  import math
  import copy
label_desc: Use image node_id 2 for calling the MultiHeadAttention obj's underlying member method code with example usage: obj.forward(query, key, value, mask) and returns: self