class_docstr: Distributional dueling fully-connected Q-function with discrete actions.
class_docstr_tok: ["Distributional","dueling","fully-connected","Q-function","with","discrete","actions","."]
code: def forward(self, x):
      h = x
      for layer in self.conv_layers:
          h = self.activation(layer(h))
  
      # Advantage
      batch_size = x.shape[0]
  
      h = self.activation(self.main_stream(h.view(batch_size, -1)))
      h_a, h_v = torch.chunk(h, 2, dim=1)
      ya = self.a_stream(h_a).reshape(
          (batch_size, self.n_actions, self.n_atoms)
      )
  
      mean = ya.sum(dim=1, keepdim=True) / self.n_actions
  
      ya, mean = torch.broadcast_tensors(ya, mean)
      ya -= mean
  
      # State value
      ys = self.v_stream(h_v).reshape((batch_size, 1, self.n_atoms))
      ya, ys = torch.broadcast_tensors(ya, ys)
      q = F.softmax(ya + ys, dim=2)
  
      self.z_values = self.z_values.to(x.device)
      return action_value.DistributionalDiscreteActionValue(
          q, self.z_values
      )
  
file_path: pfrl/pfrl/q_functions/dueling_dqn.py
imports: import torch
  import torch.nn
  import torch.nn.functional
  from pfrl import action_value
  from pfrl.initializers import init_chainer_default
  from pfrl.nn.mlp import MLP
  from pfrl.q_function import StateQFunction
label_desc: Use image node_id 2 for calling the DistributionalDuelingDQN obj's underlying member method code with example usage: obj.forward(x) and returns: action_value