PDENNEval / model /pinnsformer.py
OneScience's picture
Upload folder using huggingface_hub
ede74c0 verified
Raw
History Blame Contribute Delete
4.29 kB
# implementation of PINNsformer
# paper: PINNsFormer: A Transformer-Based Framework For Physics-Informed Neural Networks
# link: https://arxiv.org/abs/2307.11833
import torch
import torch.nn as nn
from onescience.utils.pinnsformer_util import get_clones
class WaveAct(nn.Module):
def __init__(self):
super(WaveAct, self).__init__()
self.w1 = nn.Parameter(torch.ones(1), requires_grad=True)
self.w2 = nn.Parameter(torch.ones(1), requires_grad=True)
def forward(self, x):
return self.w1 * torch.sin(x)+ self.w2 * torch.cos(x)
class FeedForward(nn.Module):
def __init__(self, d_model, d_ff=256):
super(FeedForward, self).__init__()
self.linear = nn.Sequential(*[
nn.Linear(d_model, d_ff),
WaveAct(),
nn.Linear(d_ff, d_ff),
WaveAct(),
nn.Linear(d_ff, d_model)
])
def forward(self, x):
return self.linear(x)
class EncoderLayer(nn.Module):
def __init__(self, d_model, heads):
super(EncoderLayer, self).__init__()
self.attn = nn.MultiheadAttention(embed_dim=d_model, num_heads=heads, batch_first=True)
self.ff = FeedForward(d_model)
self.act1 = WaveAct()
self.act2 = WaveAct()
def forward(self, x):
x2 = self.act1(x)
# pdb.set_trace()
x = x + self.attn(x2,x2,x2)[0]
x2 = self.act2(x)
x = x + self.ff(x2)
return x
class DecoderLayer(nn.Module):
def __init__(self, d_model, heads):
super(DecoderLayer, self).__init__()
self.attn = nn.MultiheadAttention(embed_dim=d_model, num_heads=heads, batch_first=True)
self.ff = FeedForward(d_model)
self.act1 = WaveAct()
self.act2 = WaveAct()
def forward(self, x, e_outputs):
x2 = self.act1(x)
x = x + self.attn(x2, e_outputs, e_outputs)[0]
x2 = self.act2(x)
x = x + self.ff(x2)
return x
class Encoder(nn.Module):
def __init__(self, d_model, N, heads):
super(Encoder, self).__init__()
self.N = N
self.layers = get_clones(EncoderLayer(d_model, heads), N)
self.act = WaveAct()
def forward(self, x):
for i in range(self.N):
x = self.layers[i](x)
return self.act(x)
class Decoder(nn.Module):
def __init__(self, d_model, N, heads):
super(Decoder, self).__init__()
self.N = N
self.layers = get_clones(DecoderLayer(d_model, heads), N)
self.act = WaveAct()
def forward(self, x, e_outputs):
for i in range(self.N):
x = self.layers[i](x, e_outputs)
return self.act(x)
class PINNsformer1D(nn.Module):
def __init__(self, d_out, d_model, d_hidden, N, heads):
super(PINNsformer1D, self).__init__()
self.linear_emb = nn.Linear(2, d_model)
self.encoder = Encoder(d_model, N, heads)
self.decoder = Decoder(d_model, N, heads)
self.linear_out = nn.Sequential(*[
nn.Linear(d_model, d_hidden),
WaveAct(),
nn.Linear(d_hidden, d_hidden),
WaveAct(),
nn.Linear(d_hidden, d_out)
])
def forward(self, x, t):
src = torch.cat((x,t), dim=-1)
src = self.linear_emb(src)
e_outputs = self.encoder(src)
d_output = self.decoder(src, e_outputs)
output = self.linear_out(d_output)
# pdb.set_trace()
# raise Exception('stop')
return output
class PINNsformer2D(nn.Module):
def __init__(self, d_out, d_model, d_hidden, N, heads):
super(PINNsformer2D, self).__init__()
self.linear_emb = nn.Linear(3, d_model)
self.encoder = Encoder(d_model, N, heads)
self.decoder = Decoder(d_model, N, heads)
self.linear_out = nn.Sequential(*[
nn.Linear(d_model, d_hidden),
WaveAct(),
nn.Linear(d_hidden, d_hidden),
WaveAct(),
nn.Linear(d_hidden, d_out)
])
def forward(self, x, y, t):
src = torch.cat((x,y,t), dim=-1)
src = self.linear_emb(src)
e_outputs = self.encoder(src)
d_output = self.decoder(src, e_outputs)
output = self.linear_out(d_output)
return output