def __init__(self, obs_shape: int, action_shape: int) -> None:
        """
        **Overview**:
            The definition of basic actor-critic network in policy gradient algorithms (e.g. PG/A2C/PPO),
            which is mainly composed of three parts: encoder, policy head and value head.
        """
        # PyTorch necessary requirements for extending ``nn.Module`` . Our network should also subclass this class.
        super(ActorCriticNetwork, self).__init__()
        # Define encoder module, which maps raw local state of each agent into embedding vector.
        # It could be different for various state, such as Convolution Neural Network (CNN) for image state and Multilayer perceptron (MLP) for vector state, respectively.
        # Here we use two-layer MLP for vector state, i.e.
        # $$y = max(W_2 max(W_1 x+b_1, 0) + b_2, 0)$$
        self.encoder = nn.Sequential(
            nn.Linear(obs_shape, 32),
            nn.ReLU(),
            nn.Linear(32, 64),
            nn.ReLU(),
        )
        # Define discrete action logit output network, just one-layer FC.
        self.policy_head = nn.Linear(64, action_shape)
        # Define scalar value output network.
        self.value_head = nn.Linear(64, 1)

        **Overview**:
            The definition of basic actor-critic network in policy gradient algorithms (e.g. PG/A2C/PPO),
            which is mainly composed of three parts: encoder, policy head and value head.
        
chapter6_marl/marl_network.py