def __init__( self, freq: str, prediction_length: int, cardinality: List[int], add_trend: bool = False, past_length: Optional[int] = None, num_periods_to_train: int = 4, trainer: Trainer = Trainer(epochs=100, num_batches_per_epoch=50, hybridize=False), num_layers: int = 2, num_cells: int = 40, cell_type: str = "lstm", num_parallel_samples: int = 100, dropout_rate: float = 0.1, use_feat_dynamic_real: bool = False, use_feat_static_cat: bool = True, embedding_dimension: Optional[List[int]] = None, issm: Optional[ISSM] = None, scaling: bool = True, time_features: Optional[List[TimeFeature]] = None, noise_std_bounds: ParameterBounds = ParameterBounds(1e-6, 1.0), prior_cov_bounds: ParameterBounds = ParameterBounds(1e-6, 1.0), innovation_bounds: ParameterBounds = ParameterBounds(1e-6, 0.01), batch_size: int = 32, ) -> None: super().__init__(trainer=trainer, batch_size=batch_size) assert (prediction_length > 0), "The value of `prediction_length` should be > 0" assert (past_length is None or past_length > 0), "The value of `past_length` should be > 0" assert num_layers > 0, "The value of `num_layers` should be > 0" assert num_cells > 0, "The value of `num_cells` should be > 0" assert (num_parallel_samples > 0), "The value of `num_parallel_samples` should be > 0" assert dropout_rate >= 0, "The value of `dropout_rate` should be >= 0" assert not use_feat_static_cat or any(c > 1 for c in cardinality), ( f"Cardinality of at least one static categorical feature must be larger than 1 " f"if `use_feat_static_cat=True`. But cardinality provided is: {cardinality}" ) assert embedding_dimension is None or all( e > 0 for e in embedding_dimension ), "Elements of `embedding_dimension` should be > 0" assert all( np.isfinite(p.lower) and np.isfinite(p.upper) and p.lower > 0 for p in [noise_std_bounds, prior_cov_bounds, innovation_bounds] ), "All parameter bounds should be finite, and lower bounds should be positive" self.freq = freq self.past_length = (past_length if past_length is not None else num_periods_to_train * longest_period_from_frequency_str(freq)) self.prediction_length = prediction_length self.add_trend = add_trend self.num_layers = num_layers self.num_cells = num_cells self.cell_type = cell_type self.num_parallel_samples = num_parallel_samples self.scaling = scaling self.dropout_rate = dropout_rate self.use_feat_dynamic_real = use_feat_dynamic_real self.use_feat_static_cat = use_feat_static_cat self.cardinality = (cardinality if cardinality and use_feat_static_cat else [1]) self.embedding_dimension = ( embedding_dimension if embedding_dimension is not None else [min(50, (cat + 1) // 2) for cat in self.cardinality]) self.issm = (issm if issm is not None else CompositeISSM.get_from_freq( freq, add_trend)) self.time_features = (time_features if time_features is not None else time_features_from_frequency_str(self.freq)) self.noise_std_bounds = noise_std_bounds self.prior_cov_bounds = prior_cov_bounds self.innovation_bounds = innovation_bounds
def __init__( self, num_layers: int, num_cells: int, cell_type: str, past_length: int, prediction_length: int, issm: ISSM, dropout_rate: float, cardinality: List[int], embedding_dimension: List[int], scaling: bool = True, noise_std_bounds: ParameterBounds = ParameterBounds(1e-6, 1.0), prior_cov_bounds: ParameterBounds = ParameterBounds(1e-6, 1.0), innovation_bounds: ParameterBounds = ParameterBounds(1e-6, 0.01), **kwargs, ) -> None: super().__init__(**kwargs) self.num_layers = num_layers self.num_cells = num_cells self.cell_type = cell_type self.past_length = past_length self.prediction_length = prediction_length self.issm = issm self.dropout_rate = dropout_rate self.cardinality = cardinality self.embedding_dimension = embedding_dimension self.num_cat = len(cardinality) self.scaling = scaling assert len(cardinality) == len( embedding_dimension ), "embedding_dimension should be a list with the same size as cardinality" self.univariate = self.issm.output_dim() == 1 self.noise_std_bounds = noise_std_bounds self.prior_cov_bounds = prior_cov_bounds self.innovation_bounds = innovation_bounds with self.name_scope(): self.prior_mean_model = mx.gluon.nn.Dense( units=self.issm.latent_dim(), flatten=False ) self.prior_cov_diag_model = mx.gluon.nn.Dense( units=self.issm.latent_dim(), activation="sigmoid", flatten=False, ) self.lstm = mx.gluon.rnn.HybridSequentialRNNCell() self.lds_proj = LDSArgsProj( output_dim=self.issm.output_dim(), noise_std_bounds=self.noise_std_bounds, innovation_bounds=self.innovation_bounds, ) for k in range(num_layers): cell = mx.gluon.rnn.LSTMCell(hidden_size=num_cells) cell = mx.gluon.rnn.ResidualCell(cell) if k > 0 else cell cell = ( mx.gluon.rnn.ZoneoutCell(cell, zoneout_states=dropout_rate) if dropout_rate > 0.0 else cell ) self.lstm.add(cell) self.embedder = FeatureEmbedder( cardinalities=cardinality, embedding_dims=embedding_dimension ) if scaling: self.scaler = MeanScaler(keepdims=False) else: self.scaler = NOPScaler(keepdims=False)