use burn::module::Module;
use burn::nn::{Dropout, DropoutConfig, Linear, LinearConfig};
use burn::tensor::{activation, backend::Backend, Tensor};
use super::step_2_lstm_cell::DailyLSTM;
#[derive(Module, Debug)]
pub struct DailyLSTMModel<B: Backend> {
input_size: usize,
hidden_size: usize,
output_size: usize,
lstm: DailyLSTM<B>,
dropout: Dropout,
output_layer: Linear<B>,
}
impl<B: Backend> DailyLSTMModel<B> {
pub fn new(
input_size: usize,
hidden_size: usize,
output_size: usize,
dropout_rate: f64,
device: &B::Device,
) -> Self {
let lstm = DailyLSTM::new(input_size, hidden_size, dropout_rate, device);
let dropout_config = DropoutConfig::new(dropout_rate);
let dropout = dropout_config.init();
let output_config = LinearConfig::new(hidden_size, output_size);
let output_layer = output_config.init(device);
Self {
input_size,
hidden_size,
output_size,
lstm,
dropout,
output_layer,
}
}
pub fn forward(&self, x: Tensor<B, 3>, is_training: bool) -> Tensor<B, 2> {
let batch_size = x.dims()[0];
let sequence_length = x.dims()[1];
let lstm_out = self.lstm.forward(x);
let last_output = lstm_out
.narrow(1, sequence_length - 1, 1)
.reshape([batch_size, self.hidden_size]);
let dropped = if is_training {
self.dropout.forward(last_output)
} else {
last_output
};
self.output_layer.forward(dropped)
}
pub fn predict(&self, x: Tensor<B, 3>) -> Tensor<B, 2> {
self.forward(x, false)
}
}
#[derive(Debug, Clone)]
pub struct DailyLSTMModelConfig {
pub input_size: usize,
pub hidden_size: usize,
pub output_size: usize,
pub dropout_rate: f64,
}
impl DailyLSTMModelConfig {
pub fn new(
input_size: usize,
hidden_size: usize,
output_size: usize,
dropout_rate: f64,
) -> Self {
Self {
input_size,
hidden_size,
output_size,
dropout_rate,
}
}
pub fn init<B: Backend>(&self, device: &B::Device) -> DailyLSTMModel<B> {
DailyLSTMModel::new(
self.input_size,
self.hidden_size,
self.output_size,
self.dropout_rate,
device,
)
}
}