class_docstr: A generalized version of all possible networks implemented using mxnet.
class_docstr_tok: ["A","generalized","version","of","all","possible","networks","implemented","using","mxnet","."]
code: def construct_model(self):
      # validate the configuration
      if len(self.network_parameters.input_embedders_parameters) == 0:
          raise ValueError("At least one input type should be defined")
  
      if len(self.network_parameters.heads_parameters) == 0:
          raise ValueError("At least one output type should be defined")
  
      if self.network_parameters.middleware_parameters is None:
          raise ValueError(
              "Exactly one middleware type should be defined"
          )
  
      self.model = GeneralModel(
          num_networks=self.num_networks,
          num_heads_per_network=self.num_heads_per_network,
          network_is_local=self.network_is_local,
          network_name=self.network_wrapper_name,
          agent_parameters=self.ap,
          network_parameters=self.network_parameters,
          spaces=self.spaces,
      )
  
      self.losses = self.model.losses()
  
      # Learning rate
      lr_scheduler = None
      if self.network_parameters.learning_rate_decay_rate != 0:
          lr_scheduler = mx.lr_scheduler.FactorScheduler(
              step=self.network_parameters.learning_rate_decay_steps,
              factor=self.network_parameters.learning_rate_decay_rate,
          )
  
      # Optimizer
      # FIXME Does this code for distributed training make sense?
      if (
          self.distributed_training
          and self.network_is_local
          and self.network_parameters.shared_optimizer
      ):
          # distributed training + is a local network + optimizer shared -> take the global optimizer
          self.optimizer = self.global_network.optimizer
      elif (
          (
              self.distributed_training
              and self.network_is_local
              and not self.network_parameters.shared_optimizer
          )
          or self.network_parameters.shared_optimizer
          or not self.distributed_training
      ):
          if self.network_parameters.optimizer_type == "Adam":
              self.optimizer = mx.optimizer.Adam(
                  learning_rate=self.network_parameters.learning_rate,
                  beta1=self.network_parameters.adam_optimizer_beta1,
                  beta2=self.network_parameters.adam_optimizer_beta2,
                  epsilon=self.network_parameters.optimizer_epsilon,
                  lr_scheduler=lr_scheduler,
              )
          elif self.network_parameters.optimizer_type == "RMSProp":
              self.optimizer = mx.optimizer.RMSProp(
                  learning_rate=self.network_parameters.learning_rate,
                  gamma1=self.network_parameters.rms_prop_optimizer_decay,
                  epsilon=self.network_parameters.optimizer_epsilon,
                  lr_scheduler=lr_scheduler,
              )
          elif self.network_parameters.optimizer_type == "LBFGS":
              raise NotImplementedError(
                  "LBFGS optimizer not implemented"
              )
          else:
              raise Exception(
                  "{} is not a valid optimizer type".format(
                      self.network_parameters.optimizer_type
                  )
              )
  
imports: import copy
  from itertools import chain
  from typing import List, Tuple, Union
  from types import ModuleType
  import numpy
  import mxnet
  from mxnet import nd, sym
  from mxnet.gluon import HybridBlock
  from mxnet.ndarray import NDArray
  from mxnet.symbol import Symbol
  from rl_coach.base_parameters import NetworkParameters
  from rl_coach.architectures.embedder_parameters import InputEmbedderParameters
  from rl_coach.architectures.head_parameters import HeadParameters, PPOHeadParameters
  from rl_coach.architectures.head_parameters import PPOVHeadParameters, VHeadParameters, QHeadParameters
  from rl_coach.architectures.middleware_parameters import MiddlewareParameters
  from rl_coach.architectures.middleware_parameters import FCMiddlewareParameters, LSTMMiddlewareParameters
  from rl_coach.architectures.mxnet_components.architecture import MxnetArchitecture
  from rl_coach.architectures.mxnet_components.embedders import ImageEmbedder, TensorEmbedder, VectorEmbedder
  from rl_coach.architectures.mxnet_components.heads import Head, HeadLoss, PPOHead, PPOVHead, VHead, QHead
  from rl_coach.architectures.mxnet_components.middlewares import FCMiddleware, LSTMMiddleware
  from rl_coach.architectures.mxnet_components import utils
  from rl_coach.base_parameters import AgentParameters, Device, DeviceType, EmbeddingMergerType
  from rl_coach.spaces import SpacesDefinition, PlanarMapsObservationSpace, TensorObservationSpace
label_desc: Use image node_id 4 for calling the GeneralMxnetNetwork obj's underlying member method code with example usage: obj.construct_model() without return types