aiops/Pathformer_ICLR2024/models/PathFormer.py (52 lines of code) (raw):
import math
import torch
import torch
import torch.nn as nn
from torch.distributions.normal import Normal
import numpy as np
from layers.AMS import AMS
from layers.Layer import WeightGenerator, CustomLinear
from layers.RevIN import RevIN
from functools import reduce
from operator import mul
class Model(nn.Module):
def __init__(self, configs):
super(Model, self).__init__()
self.layer_nums = configs.layer_nums # 设置pathway的层数
self.num_nodes = configs.num_nodes
self.pre_len = configs.pred_len
self.seq_len = configs.seq_len
self.k = configs.k
self.num_experts_list = configs.num_experts_list
self.patch_size_list = configs.patch_size_list
self.d_model = configs.d_model
self.d_ff = configs.d_ff
self.residual_connection = configs.residual_connection
self.revin = configs.revin
if self.revin:
self.revin_layer = RevIN(num_features=configs.num_nodes, affine=False, subtract_last=False)
self.start_fc = nn.Linear(in_features=1, out_features=self.d_model)
self.AMS_lists = nn.ModuleList()
self.device = torch.device('cuda:{}'.format(configs.gpu))
for num in range(self.layer_nums):
self.AMS_lists.append(
AMS(self.seq_len, self.seq_len, self.num_experts_list[num], self.device, k=self.k,
num_nodes=self.num_nodes, patch_size=self.patch_size_list[num], noisy_gating=True,
d_model=self.d_model, d_ff=self.d_ff, layer_number=num + 1, residual_connection=self.residual_connection))
self.projections = nn.Sequential(
nn.Linear(self.seq_len * self.d_model, self.pre_len)
)
def forward(self, x):
balance_loss = 0
# norm
if self.revin:
x = self.revin_layer(x, 'norm')
out = self.start_fc(x.unsqueeze(-1))
batch_size = x.shape[0]
for layer in self.AMS_lists:
out, aux_loss = layer(out)
balance_loss += aux_loss
out = out.permute(0,2,1,3).reshape(batch_size, self.num_nodes, -1)
out = self.projections(out).transpose(2, 1)
# denorm
if self.revin:
out = self.revin_layer(out, 'denorm')
return out, balance_loss