Download stress_operator/models/blocks.py from Efradeca/transolver-linearno-elasticity: direct link, hf CLI and curl.
- Browser
- Download file 2.51 kB
-
https://huggingface.co/Efradeca/transolver-linearno-elasticity/resolve/main/stress_operator/models/blocks.py
- Command line
-
hf download hf://Efradeca/transolver-linearno-elasticity/stress_operator/models/blocks.py
-
curl -L -o blocks.py https://huggingface.co/Efradeca/transolver-linearno-elasticity/resolve/main/stress_operator/models/blocks.py
2.51 kB
| """Building blocks: MLP and the pre-norm Transolver block. | |
| Faithful to Transolver ``model/Transolver_Irregular_Mesh.py`` (MIT). The only structural | |
| change is that the attention module is injected (so Stage 2 can swap Physics-Attention for | |
| LinearNO without touching anything else). | |
| """ | |
| import torch.nn as nn | |
| ACTIVATION = { | |
| "gelu": nn.GELU, | |
| "tanh": nn.Tanh, | |
| "sigmoid": nn.Sigmoid, | |
| "relu": nn.ReLU, | |
| "leaky_relu": lambda: nn.LeakyReLU(0.1), | |
| "softplus": nn.Softplus, | |
| "ELU": nn.ELU, | |
| "silu": nn.SiLU, | |
| } | |
| class MLP(nn.Module): | |
| """Transolver MLP: Linear->act (->[Linear->act]^n_layers) ->Linear, optional residual.""" | |
| def __init__(self, n_input, n_hidden, n_output, n_layers=1, act="gelu", res=True): | |
| super().__init__() | |
| if act not in ACTIVATION: | |
| raise NotImplementedError(act) | |
| act_cls = ACTIVATION[act] | |
| self.n_layers = n_layers | |
| self.res = res | |
| self.linear_pre = nn.Sequential(nn.Linear(n_input, n_hidden), act_cls()) | |
| self.linear_post = nn.Linear(n_hidden, n_output) | |
| self.linears = nn.ModuleList( | |
| [nn.Sequential(nn.Linear(n_hidden, n_hidden), act_cls()) for _ in range(n_layers)] | |
| ) | |
| def forward(self, x): | |
| x = self.linear_pre(x) | |
| for layer in self.linears: | |
| x = layer(x) + x if self.res else layer(x) | |
| return self.linear_post(x) | |
| class TransolverBlock(nn.Module): | |
| """Pre-norm transformer block; the last block also carries the decoder head. | |
| fx = fx + Attn(LayerNorm(fx)) | |
| fx = fx + MLP(LayerNorm(fx)) | |
| (last block) return Linear(LayerNorm(fx)) -> out_dim | |
| """ | |
| def __init__( | |
| self, | |
| attention: nn.Module, | |
| hidden_dim: int, | |
| dropout: float = 0.0, | |
| act: str = "gelu", | |
| mlp_ratio: int = 1, | |
| last_layer: bool = False, | |
| out_dim: int = 1, | |
| ): | |
| super().__init__() | |
| self.last_layer = last_layer | |
| self.ln_1 = nn.LayerNorm(hidden_dim) | |
| self.Attn = attention | |
| self.ln_2 = nn.LayerNorm(hidden_dim) | |
| self.mlp = MLP(hidden_dim, hidden_dim * mlp_ratio, hidden_dim, n_layers=0, res=False, act=act) | |
| if last_layer: | |
| self.ln_3 = nn.LayerNorm(hidden_dim) | |
| self.mlp2 = nn.Linear(hidden_dim, out_dim) | |
| def forward(self, fx): | |
| fx = self.Attn(self.ln_1(fx)) + fx | |
| fx = self.mlp(self.ln_2(fx)) + fx | |
| if self.last_layer: | |
| return self.mlp2(self.ln_3(fx)) | |
| return fx | |