import torch.nn as nn import torch.nn.functional as F import torch class LSTMModel(nn.Module): def __init__(self, input_size=3, hidden_size=64, num_layers=2, output_size=1): super(LSTMModel, self).__init__() # LSTM layer self.lstm = nn.LSTM( input_size=input_size, hidden_size=hidden_size, num_layers=num_layers, batch_first=True, dropout=0.2 if num_layers > 1 else 0 # Chỉ áp dụng dropout khi có nhiều layer ) # Attention mechanism self.attention = nn.Sequential( nn.Linear(hidden_size, hidden_size), nn.Tanh(), nn.Linear(hidden_size, 1, bias=False) ) # Fully connected layer với ràng buộc đầu ra dương self.fc = nn.Sequential( nn.Linear(hidden_size, 32), nn.ReLU(), nn.Linear(32, output_size), nn.Softplus() # Thay ReLU bằng Softplus để mềm mại hơn ) # Khởi tạo trọng số self._init_weights() def _init_weights(self): for name, param in self.named_parameters(): if 'weight' in name: nn.init.xavier_normal_(param) elif 'bias' in name: nn.init.constant_(param, 0.1) def forward(self, x): # LSTM layer lstm_out, _ = self.lstm(x) # (batch_size, seq_len, hidden_size) # Attention mechanism attn_weights = F.softmax(self.attention(lstm_out), dim=1) context = torch.sum(attn_weights * lstm_out, dim=1) # Dự đoán đầu ra (luôn dương) out = self.fc(context) return out.squeeze(1) # (batch_size,)