Source code for waxmorph.torch.mlp

"""PyTorch MLP used by the graph network."""

import torch.nn as nn

from waxmorph._validation import _validate_mlp_config

_ACTIVATIONS = {
    "relu": nn.ReLU,
    "silu": nn.SiLU,
    "gelu": nn.GELU,
    "tanh": nn.Tanh,
}


[docs] class MLP(nn.Module): """MLP with one or more linear layers. ``num_layers`` counts all linear layers. Depth one is a single affine map; deeper networks apply the selected activation after each hidden layer. Optional LayerNorm follows the final projection. Activations are ``relu``, ``silu``, ``gelu``, and ``tanh``. Boolean, nonintegral, and nonpositive depths are rejected. Examples: >>> import torch >>> mlp = MLP(3, 2, hidden_dim=4, num_layers=1, layer_norm=False) >>> print(tuple(mlp(torch.ones(5, 3)).shape)) (5, 2) """ def __init__( self, input_dim: int, output_dim: int, hidden_dim: int = 128, num_layers: int = 2, activation: str = "silu", layer_norm: bool = True, ): super().__init__() num_layers = _validate_mlp_config(activation, _ACTIVATIONS, num_layers) self.activation_name = activation act_cls = _ACTIVATIONS[activation] layers: list[nn.Module] = [] if num_layers == 1: layers.append(nn.Linear(input_dim, output_dim)) else: layers.append(nn.Linear(input_dim, hidden_dim)) layers.append(act_cls()) for _ in range(num_layers - 2): layers.append(nn.Linear(hidden_dim, hidden_dim)) layers.append(act_cls()) layers.append(nn.Linear(hidden_dim, output_dim)) if layer_norm: layers.append(nn.LayerNorm(output_dim)) self.net = nn.Sequential(*layers)
[docs] def forward(self, x): return self.net(x)