class_docstr: input: n_agents' agent_qs (a scalar for each agent)
  output: a scalar (Q)
docstr: Args:
      agent_qs (torch.Tensor): (batch_size, T, n_agents)
      states (torch.Tensor):   (batch_size, T, state_shape)
  Returns:
      q_total (torch.Tensor):  (batch_size, T, 1)
code: def forward(self, agent_qs, states):
      """
      Args:
          agent_qs (torch.Tensor): (batch_size, T, n_agents)
          states (torch.Tensor):   (batch_size, T, state_shape)
      Returns:
          q_total (torch.Tensor):  (batch_size, T, 1)
      """
      batch_size = agent_qs.size(0)
      states = states.reshape(-1, self.state_shape)
      agent_qs = agent_qs.view(-1, 1, self.n_agents)
  
      w1 = torch.abs(self.hyper_w_1(states))
      w1 = w1.view(-1, self.n_agents, self.embed_dim)
      b1 = self.hyper_b_1(states)
      b1 = b1.view(-1, 1, self.embed_dim)
  
      w2 = torch.abs(self.hyper_w_2(states))
      w2 = w2.view(-1, self.embed_dim, 1)
      b2 = self.hyper_b_2(states).view(-1, 1, 1)
  
      hidden = F.elu(torch.bmm(agent_qs, w1) + b1)
      y = torch.bmm(hidden, w2) + b2
      q_total = y.view(batch_size, -1, 1)
      return q_total
  
file_path: PARL/benchmark/torch/qmix/qmixer_model.py
imports: import torch
  import torch.nn
  import torch.nn.functional
  import parl
label_desc: Use image node_id 2 for calling the QMixerModel obj's underlying member method code with example usage: obj.forward(agent_qs, states) and returns: q_total