docstr: QMIX algorithm
  
  Args:
      agent_model (parl.Model): agents' local q network for decision making.
      qmixer_model (parl.Model): A mixing network which takes local q values as input to construct a global Q network.
      double_q (bool): Double-DQN.
      gamma (float): discounted factor for reward computation.
      lr (float): learning rate.
      clip_grad_norm (None, or float): clipped value of gradients' global norm.
docstr_tok: ["QMIX","algorithm","Args",":","agent_model","(","parl.Model",")",":","agents","'","local","q","network","for","decision","making",".","qmixer_model","(","parl.Model",")",":","A","mixing","network","which","takes","local","q","values","as","input","to","construct","a","global","Q","network",".","double_q","(","bool",")",":","Double-DQN",".","gamma","(","float",")",":","discounted","factor","for","reward","computation",".","lr","(","float",")",":","learning","rate",".","clip_grad_norm","(","None",",","or","float",")",":","clipped","value","of","gradients","'","global","norm","."]
code: def __init__(
      self,
      agent_model,
      qmixer_model,
      double_q=True,
      gamma=0.99,
      lr=0.0005,
      clip_grad_norm=None,
  ):
      """QMIX algorithm
  
      Args:
          agent_model (parl.Model): agents' local q network for decision making.
          qmixer_model (parl.Model): A mixing network which takes local q values as input to construct a global Q network.
          double_q (bool): Double-DQN.
          gamma (float): discounted factor for reward computation.
          lr (float): learning rate.
          clip_grad_norm (None, or float): clipped value of gradients' global norm.
      """
      # checks
      check_model_method(
          agent_model, "init_hidden", self.__class__.__name__
      )
      check_model_method(
          agent_model, "forward", self.__class__.__name__
      )
      check_model_method(
          qmixer_model, "forward", self.__class__.__name__
      )
      assert hasattr(qmixer_model, "n_agents") and not callable(
          getattr(qmixer_model, "n_agents", None)
      ), "qmixer_model needs to have attribute n_agents"
      assert isinstance(gamma, float)
      assert isinstance(lr, float)
  
      self.agent_model = agent_model
      self.qmixer_model = qmixer_model
      self.target_agent_model = deepcopy(self.agent_model)
      self.target_qmixer_model = deepcopy(self.qmixer_model)
  
      self.n_agents = self.qmixer_model.n_agents
      self.double_q = double_q
      self.gamma = gamma
      self.lr = lr
      self.clip_grad_norm = clip_grad_norm
  
      self.params = list(self.agent_model.parameters())
      self.params += self.qmixer_model.parameters()
      if self.clip_grad_norm:
          clip = nn.ClipGradByGlobalNorm(clip_norm=self.clip_grad_norm)
          self.optimizer = paddle.optimizer.RMSProp(
              parameters=self.params,
              learning_rate=self.lr,
              rho=0.99,
              epsilon=1e-5,
              grad_clip=clip,
          )
      else:
          self.optimizer = paddle.optimizer.RMSProp(
              parameters=self.params,
              learning_rate=self.lr,
              rho=0.99,
              epsilon=1e-5,
          )
  
file_path: PARL/parl/algorithms/paddle/qmix.py
imports: import paddle
  import paddle.nn
  import parl
  from copy import deepcopy
  import paddle.nn.functional
  from parl.utils.utils import check_model_method
label_desc: Use image node_id 1 to create a new QMIX object from inherited base classes: parl with example: obj = QMIX(agent_model, qmixer_model, double_q, gamma, lr, clip_grad_norm)