def independentac_training_opeator() -> None:
    """
    **Overview**:
        The main function about the training process of independent actor-critic algorithm.
        Define some hyper-parameters, the neural network and optimizer, then generate fake data and calculate the actor-critic loss.
        Finally, update the network parameters with optimizer. In practice, the training data should
        be replaced by the results getting from the interacting with the environment.
        BTW, policy network means actor and value network indicates critic in this file.
    """
    # Set necessary hyper-parameters.
    batch_size, agent_num, local_state_dim, global_state_dim, action_dim = 4, 5, 10, 20, 6
    # Entropy bonus weight, which is beneficial to exploration.
    entropy_weight = 0.001
    # Value loss weight, which aims to balance the loss scale.
    value_weight = 0.5
    # Discount factor for future reward.
    discount_factor = 0.99
    # Set the tensor device to cuda or cpu according to the runtime environment.
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

    # Define the multi-agent neural network and optimizer.
    # Here we use the independent actor-critic network as the example, you can also use the shared-parameter network.
    model = IndependentActorCriticNetwork(agent_num, local_state_dim, action_dim)
    model.to(device)
    # Adam is the most commonly used optimizer in deep reinforcement learning. If you want to add
    # weight decay mechanism, you should use ``torch.optim.AdamW`` .
    optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

    # Define the corresponding fake data following the same data format of the interacting with the environment.
    # Note that the data should keep the same device with the network.
    # For simplicity, we regard the whole batch data as a entire episode.
    # In practice, the training batch is the combination of multiple episodes. We often use
    # ``done`` variable to distinguish the different episodes.
    local_state = torch.randn(batch_size, agent_num, local_state_dim).to(device)
    action = torch.randint(0, action_dim, (batch_size, agent_num)).to(device)
    reward = torch.randn(batch_size, agent_num).to(device)
    # Return_ can be computed with different methods. Here we use the discounted cumulative sum of the reward.
    # You can also use the generalized advantage estimation (GAE) method, n-step return method, etc.
    return_ = torch.zeros_like(reward)
    for i in reversed(range(batch_size)):
        return_[i] = reward[i] + (discount_factor * return_[i + 1] if i + 1 < batch_size else 0)

    # Actor-critic network forward propagation.
    output = model(local_state)
    # ``squeeze`` operation transforms shape from $$(B, A, 1)$$ to $$(B, A)$$.
    value = output.value.squeeze(-1)
    # Prepare the data for policy gradient loss calculation.
    # ``detach`` operation means stop gradient for ``value`` in policy gradient loss calculation.
    data = pg_data(output.logit, action, value.detach())
    # Calculate the policy gradient loss.
    loss = pg_error(data)
    # Calculate the value loss.
    value_loss = torch.nn.functional.mse_loss(value, return_)
    # Weighted sum of policy loss, value loss and entropy loss.
    total_loss = loss.policy_loss + value_weight * value_loss - entropy_weight * loss.entropy_loss

    # PyTorch loss back propagation and optimizer update.
    optimizer.zero_grad()
    total_loss.backward()
    optimizer.step()
    print('independentac_training_opeator is ok')

    **Overview**:
        The main function about the training process of independent actor-critic algorithm.
        Define some hyper-parameters, the neural network and optimizer, then generate fake data and calculate the actor-critic loss.
        Finally, update the network parameters with optimizer. In practice, the training data should
        be replaced by the results getting from the interacting with the environment.
        BTW, policy network means actor and value network indicates critic in this file.
    
chapter6_marl/independentpg.py