From 209f9b6a3da2dbc8f5f1caafa8e292a248168eba Mon Sep 17 00:00:00 2001 From: cedric Date: Tue, 31 Mar 2026 22:09:37 +0000 Subject: [PATCH] feat: MLP related design decisions doc --- docs/design_decisions/mlp_architecture.md | 24 ++++++++++++++++++++++ docs/img/mlp_pipe.png | Bin 0 -> 39662 bytes 2 files changed, 24 insertions(+) create mode 100644 docs/design_decisions/mlp_architecture.md create mode 100644 docs/img/mlp_pipe.png diff --git a/docs/design_decisions/mlp_architecture.md b/docs/design_decisions/mlp_architecture.md new file mode 100644 index 0000000..0cdb381 --- /dev/null +++ b/docs/design_decisions/mlp_architecture.md @@ -0,0 +1,24 @@ +# Network Architecture (MLP Pipeline per Module) + +In the decentralized architectures (arm-level and segment-level), each controller/module follows the same **shared MLP-based pipeline** inspired by NerveNet-style message passing. The pipeline consists of 5 MLPs (4 in the case of centralized, with no messager): + +- **INPUT_ACTOR**: Processes local observations for the actor branch. +- **INPUT_CRITIC**: Processes local observations for the critic branch. +- **MESSAGER**: Processes incoming hidden states from neighboring modules (via the chosen communication scheme) and produces an aggregated hidden state. +- **ACTOR**: Takes the aggregated hidden state and outputs the action distribution (mean and log_std). +- **CRITIC**: Takes the aggregated hidden state and outputs a scalar value estimate. + +## MLP Pipeline + +![MLP Pipeline - Actor-Critic with Message Passing](../img/mlp_pipe.png "MLP neural network pipeline per module") + + +## Implementation Details Related To PPO + +Inspired by: https://iclr-blog-track.github.io/2022/03/25/ppo-implementation-details/ + +For starters we will execute our tests with simple models. Each MLP will have only 1 hidden layer. This will be expanded as needed. The exceptions are the input networks / feature extractors — they will be given 2 hidden layers and 64 nodes per layer as advised in the blog. This might change as we make progress in our experiments. + +Our policy and value networks use separate networks as advised by the paper and the blog. For continuous actions this should allow better learning at a small cost. + +We use mean and log_std to represent the action distribution, because it is advised by previous research for learning stability and other reasons. \ No newline at end of file diff --git a/docs/img/mlp_pipe.png b/docs/img/mlp_pipe.png new file mode 100644 index 0000000000000000000000000000000000000000..174d521c01243ba8e11f204d095a78213f9ba1ab GIT binary patch literal 39662 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