Spaces:
Sleeping
Sleeping
| # core/models.py | |
| import torch | |
| import logging | |
| import torch.nn as nn | |
| import math | |
| # ---------------- Base ---------------- | |
| class BaseTimeSeriesModel(nn.Module): | |
| def __init__(self): | |
| super(BaseTimeSeriesModel, self).__init__() | |
| def reset_weights(self): | |
| for layer in self.children(): | |
| if hasattr(layer, "reset_parameters"): | |
| layer.reset_parameters() | |
| # ---------------- LSTM ---------------- | |
| class LSTMModel(nn.Module): | |
| def __init__(self, input_size, hidden_size, num_layers, output_size, dropout=0.2): | |
| super(LSTMModel, self).__init__() | |
| self.hidden_size = hidden_size | |
| self.num_layers = num_layers | |
| self.lstm = nn.LSTM( | |
| input_size=input_size, | |
| hidden_size=hidden_size, | |
| num_layers=num_layers, | |
| batch_first=True, | |
| dropout=dropout if num_layers > 1 else 0.0, | |
| ) | |
| self.fc = nn.Linear(hidden_size, output_size) | |
| self.dropout = nn.Dropout(dropout) | |
| def forward(self, x): | |
| logging.debug(f"Inside forward: initial x type={type(x)}, x={x}") | |
| if isinstance(x, (tuple, list)): | |
| logging.debug(f"Model forward received tuple/list: type={type(x)}, length={len(x)}") | |
| x = x[0] | |
| if not isinstance(x, torch.Tensor): | |
| x = torch.tensor( | |
| x, dtype=torch.float32, device=next(self.parameters()).device | |
| ) | |
| batch_size = x.size(0) | |
| h0 = torch.zeros(self.num_layers, batch_size, self.hidden_size).to(x.device) | |
| c0 = torch.zeros(self.num_layers, batch_size, self.hidden_size).to(x.device) | |
| out, _ = self.lstm(x, (h0, c0)) | |
| out = self.dropout(out[:, -1, :]) | |
| return self.fc(out) | |
| # ---------------- GRU ---------------- | |
| class GRUModel(nn.Module): | |
| def __init__(self, input_size, hidden_size, num_layers, output_size, dropout=0.2): | |
| super(GRUModel, self).__init__() | |
| self.hidden_size = hidden_size | |
| self.num_layers = num_layers | |
| self.gru = nn.GRU( | |
| input_size=input_size, | |
| hidden_size=hidden_size, | |
| num_layers=num_layers, | |
| batch_first=True, | |
| dropout=dropout if num_layers > 1 else 0.0, | |
| ) | |
| self.fc = nn.Linear(hidden_size, output_size) | |
| self.dropout = nn.Dropout(dropout) | |
| def forward(self, x): | |
| logging.debug(f"Inside forward: initial x type={type(x)}, x={x}") | |
| if isinstance(x, (tuple, list)): | |
| logging.debug(f"Model forward received tuple/list: type={type(x)}, length={len(x)}") | |
| x = x[0] | |
| if not isinstance(x, torch.Tensor): | |
| x = torch.tensor( | |
| x, dtype=torch.float32, device=next(self.parameters()).device | |
| ) | |
| batch_size = x.size(0) | |
| h0 = torch.zeros(self.num_layers, batch_size, self.hidden_size).to(x.device) | |
| out, _ = self.gru(x, h0) | |
| out = self.dropout(out[:, -1, :]) | |
| return self.fc(out) | |
| # ---------------- CNN ---------------- | |
| class CNNModel(nn.Module): | |
| def __init__(self, input_size, hidden_size, num_layers, output_size, dropout=0.2): | |
| super(CNNModel, self).__init__() | |
| self.conv1 = nn.Conv1d(input_size, hidden_size, kernel_size=3, padding=1) | |
| self.relu = nn.ReLU() | |
| self.dropout = nn.Dropout(dropout) | |
| self.fc = nn.Linear(hidden_size, output_size) | |
| def forward(self, x): | |
| logging.debug(f"Inside forward: initial x type={type(x)}, x={x}") | |
| if isinstance(x, (tuple, list)): | |
| logging.debug(f"Model forward received tuple/list: type={type(x)}, length={len(x)}") | |
| x = x[0] | |
| if not isinstance(x, torch.Tensor): | |
| x = torch.tensor( | |
| x, dtype=torch.float32, device=next(self.parameters()).device | |
| ) | |
| x = x.transpose(1, 2) # [batch, features, seq_len] | |
| out = self.conv1(x) | |
| out = self.relu(out) | |
| out = out.mean(dim=2) # global avg pooling | |
| out = self.dropout(out) | |
| return self.fc(out) | |
| # ---------------- MLP ---------------- | |
| class MLPModel(nn.Module): | |
| def __init__(self, input_size, hidden_size, num_layers, output_size, dropout=0.2): | |
| super(MLPModel, self).__init__() | |
| layers = [] | |
| in_features = input_size | |
| for _ in range(num_layers): | |
| layers.append(nn.Linear(in_features, hidden_size)) | |
| layers.append(nn.ReLU()) | |
| layers.append(nn.Dropout(dropout)) | |
| in_features = hidden_size | |
| layers.append(nn.Linear(hidden_size, output_size)) | |
| self.mlp = nn.Sequential(*layers) | |
| def forward(self, x): | |
| logging.debug(f"Inside forward: initial x type={type(x)}, x={x}") | |
| if isinstance(x, (tuple, list)): | |
| logging.debug(f"Model forward received tuple/list: type={type(x)}, length={len(x)}") | |
| x = x[0] | |
| if not isinstance(x, torch.Tensor): | |
| x = torch.tensor( | |
| x, dtype=torch.float32, device=next(self.parameters()).device | |
| ) | |
| return self.mlp(x[:, -1, :]) # flatten last timestep | |
| # ---------------- Hybrid CNN-GRU ---------------- | |
| class HybridCNNGRUModel(nn.Module): | |
| def __init__(self, input_size, hidden_size, num_layers, output_size, dropout=0.2): | |
| super(HybridCNNGRUModel, self).__init__() | |
| self.conv1 = nn.Conv1d(input_size, hidden_size, kernel_size=3, padding=1) | |
| self.gru = nn.GRU(hidden_size, hidden_size, num_layers, batch_first=True) | |
| self.fc = nn.Linear(hidden_size, output_size) | |
| self.dropout = nn.Dropout(dropout) | |
| def forward(self, x): | |
| logging.debug(f"Inside forward: initial x type={type(x)}, x={x}") | |
| if isinstance(x, (tuple, list)): | |
| logging.debug(f"Model forward received tuple/list: type={type(x)}, length={len(x)}") | |
| x = x[0] | |
| if not isinstance(x, torch.Tensor): | |
| x = torch.tensor( | |
| x, dtype=torch.float32, device=next(self.parameters()).device | |
| ) | |
| x = x.transpose(1, 2) | |
| out = self.conv1(x).transpose(1, 2) | |
| out, _ = self.gru(out) | |
| out = self.dropout(out[:, -1, :]) | |
| return self.fc(out) | |
| # ---------------- Transformer ---------------- | |
| class TransformerModel(nn.Module): | |
| def __init__( | |
| self, input_size, hidden_size, num_layers, output_size, dropout=0.2, nhead=4 | |
| ): | |
| super(TransformerModel, self).__init__() | |
| self.embedding = nn.Linear(input_size, hidden_size) | |
| encoder_layer = nn.TransformerEncoderLayer( | |
| d_model=hidden_size, nhead=nhead, dropout=dropout | |
| ) | |
| self.transformer = nn.TransformerEncoder(encoder_layer, num_layers=num_layers) | |
| self.fc = nn.Linear(hidden_size, output_size) | |
| def forward(self, x): | |
| logging.debug(f"Inside forward: initial x type={type(x)}, x={x}") | |
| if isinstance(x, (tuple, list)): | |
| logging.debug(f"Model forward received tuple/list: type={type(x)}, length={len(x)}") | |
| x = x[0] | |
| if not isinstance(x, torch.Tensor): | |
| x = torch.tensor( | |
| x, dtype=torch.float32, device=next(self.parameters()).device | |
| ) | |
| x = self.embedding(x) | |
| out = self.transformer(x.transpose(0, 1)) # seq_first | |
| out = out[-1, :, :] | |
| return self.fc(out) | |
| # ---------------- BiLSTM ---------------- | |
| class BiLSTMModel(nn.Module): | |
| def __init__(self, input_size, hidden_size, num_layers, output_size, dropout=0.2): | |
| super(BiLSTMModel, self).__init__() | |
| self.hidden_size = hidden_size | |
| self.num_layers = num_layers | |
| self.lstm = nn.LSTM( | |
| input_size=input_size, | |
| hidden_size=hidden_size, | |
| num_layers=num_layers, | |
| batch_first=True, | |
| dropout=dropout if num_layers > 1 else 0.0, | |
| bidirectional=True, | |
| ) | |
| self.fc = nn.Linear(hidden_size * 2, output_size) | |
| self.dropout = nn.Dropout(dropout) | |
| def forward(self, x): | |
| logging.debug(f"Inside forward: initial x type={type(x)}, x={x}") | |
| if isinstance(x, (tuple, list)): | |
| logging.debug(f"Model forward received tuple/list: type={type(x)}, length={len(x)}") | |
| x = x[0] | |
| if not isinstance(x, torch.Tensor): | |
| x = torch.tensor( | |
| x, dtype=torch.float32, device=next(self.parameters()).device | |
| ) | |
| batch_size = x.size(0) | |
| h0 = torch.zeros(self.num_layers * 2, batch_size, self.hidden_size).to(x.device) | |
| c0 = torch.zeros(self.num_layers * 2, batch_size, self.hidden_size).to(x.device) | |
| out, _ = self.lstm(x, (h0, c0)) | |
| out = self.dropout(out[:, -1, :]) | |
| return self.fc(out) | |