code: def __init__(self, heads_count, model_dim, dropout_prob):
      super(MultiHeadAttention, self).__init__()
      assert (
          model_dim % heads_count == 0
      ), f"model dim {model_dim} not divisible by {heads_count} heads"
      self.d_head = model_dim // heads_count
      self.heads_count = heads_count
      self.query_projection = nn.Linear(
          model_dim, heads_count * self.d_head
      )
      self.key_projection = nn.Linear(
          model_dim, heads_count * self.d_head
      )
      self.value_projection = nn.Linear(
          model_dim, heads_count * self.d_head
      )
      self.final_projection = nn.Linear(
          model_dim, heads_count * self.d_head
      )
      self.dropout = nn.Dropout(dropout_prob)
      self.softmax = nn.Softmax(dim=3)
      self.attention = None
  
imports: from collections import OrderedDict
  import os
  import numpy
  import torch
  from torch import nn
  from gluoncv.torch.utils.coot_utils import truncated_normal_fill
label_desc: Use image node_id 1 to create a new MultiHeadAttention object from inherited base classes: nn with example: obj = MultiHeadAttention(heads_count, model_dim, dropout_prob)