def __init__( self, model: HybridBlock, is_sequential: bool, freq: str, context_length: int, prediction_length: int, trainer: Trainer = Trainer(), num_parallel_samples: int = 100, cardinality: List[int] = list([1]), embedding_dimension: int = 10, distr_output: DistributionOutput = StudentTOutput(), batch_size: int = 32, ) -> None: super().__init__(trainer=trainer, batch_size=batch_size) # TODO: error checking self.freq = freq self.context_length = context_length self.prediction_length = prediction_length self.distr_output = distr_output self.num_parallel_samples = num_parallel_samples self.cardinality = cardinality self.embedding_dimensions = [embedding_dimension for _ in cardinality] self.model = model self.is_sequential = is_sequential
def __init__( self, freq: str, context_length: int, prediction_length: int, trainer: Trainer = Trainer(), num_layers: int = 1, num_cells: int = 50, cell_type: str = "lstm", num_parallel_samples: int = 100, cardinality: List[int] = list([1]), embedding_dimension: int = 10, distr_output: DistributionOutput = StudentTOutput(), ) -> None: model = RNN(mode=cell_type, num_layers=num_layers, num_hidden=num_cells) super().__init__( model=model, is_sequential=True, freq=freq, context_length=context_length, prediction_length=prediction_length, trainer=trainer, num_parallel_samples=num_parallel_samples, cardinality=cardinality, embedding_dimension=embedding_dimension, distr_output=distr_output, )
def __init__( self, freq: str, context_length: int, prediction_length: int, trainer: Trainer = Trainer(), hidden_dim_sequence=list([50]), num_parallel_samples: int = 100, cardinality: List[int] = list([1]), embedding_dimension: int = 10, distr_output: DistributionOutput = StudentTOutput(), ) -> None: model = nn.HybridSequential() for layer, layer_dim in enumerate(hidden_dim_sequence): model.add( nn.Dense( layer_dim, flatten=False, activation="relu", prefix="mlp_%d_" % layer, )) super().__init__( model=model, is_sequential=False, freq=freq, context_length=context_length, prediction_length=prediction_length, trainer=trainer, num_parallel_samples=num_parallel_samples, cardinality=cardinality, embedding_dimension=embedding_dimension, distr_output=distr_output, )
def __init__( self, freq: str, prediction_length: int, num_hidden_global: int = 50, num_layers_global: int = 1, num_factors: int = 10, num_hidden_local: int = 5, num_layers_local: int = 1, cell_type: str = "lstm", trainer: Trainer = Trainer(), context_length: Optional[int] = None, num_parallel_samples: int = 100, cardinality: List[int] = list([1]), embedding_dimension: int = 10, distr_output: DistributionOutput = StudentTOutput(), ) -> None: super().__init__(trainer=trainer) assert (prediction_length > 0), "The value of `prediction_length` should be > 0" assert (context_length is None or context_length > 0 ), "The value of `context_length` should be > 0" assert num_layers_global > 0, "The value of `num_layers` should be > 0" assert num_hidden_global > 0, "The value of `num_hidden` should be > 0" assert num_factors > 0, "The value of `num_factors` should be > 0" assert (num_hidden_local > 0), "The value of `num_hidden_local` should be > 0" assert (num_layers_local > 0), "The value of `num_layers_local` should be > 0" assert all([c > 0 for c in cardinality ]), "Elements of `cardinality` should be > 0" assert (embedding_dimension > 0), "The value of `embedding_dimension` should be > 0" assert (num_parallel_samples > 0), "The value of `num_parallel_samples` should be > 0" self.freq = freq self.context_length = (context_length if context_length is not None else prediction_length) self.prediction_length = prediction_length self.distr_output = distr_output self.num_parallel_samples = num_parallel_samples self.cardinality = cardinality self.embedding_dimensions = [embedding_dimension for _ in cardinality] self.global_model = RNNModel( mode=cell_type, num_hidden=num_hidden_global, num_layers=num_layers_global, num_output=num_factors, ) # TODO: Allow the local model to be defined as an arbitrary local model, e.g. DF-GP and DF-LDS self.local_model = RNNModel( mode=cell_type, num_hidden=num_hidden_local, num_layers=num_layers_local, num_output=1, )
def __init__( self, freq: str, prediction_length: int, sampling: bool = True, trainer: Trainer = Trainer(), num_hidden_dimensions: Optional[List[int]] = None, context_length: Optional[int] = None, distr_output: DistributionOutput = StudentTOutput(), imputation_method: Optional[MissingValueImputation] = None, batch_normalization: bool = False, mean_scaling: bool = True, num_parallel_samples: int = 100, train_sampler: Optional[InstanceSampler] = None, validation_sampler: Optional[InstanceSampler] = None, batch_size: int = 32, ) -> None: """ Defines an estimator. All parameters should be serializable. """ super().__init__(trainer=trainer, batch_size=batch_size) assert (prediction_length > 0), "The value of `prediction_length` should be > 0" assert (context_length is None or context_length > 0 ), "The value of `context_length` should be > 0" assert num_hidden_dimensions is None or ([ d > 0 for d in num_hidden_dimensions ]), "Elements of `num_hidden_dimensions` should be > 0" assert (num_parallel_samples > 0), "The value of `num_parallel_samples` should be > 0" self.num_hidden_dimensions = (num_hidden_dimensions if num_hidden_dimensions is not None else list([40, 40])) self.prediction_length = prediction_length self.context_length = (context_length if context_length is not None else prediction_length) self.freq = freq self.distr_output = distr_output self.batch_normalization = batch_normalization self.mean_scaling = mean_scaling self.num_parallel_samples = num_parallel_samples self.sampling = sampling self.imputation_method = (imputation_method if imputation_method is not None else DummyValueImputation( self.distr_output.value_in_support)) self.train_sampler = (train_sampler if train_sampler is not None else ExpectedNumInstanceSampler( num_instances=1.0, min_future=prediction_length)) self.validation_sampler = (validation_sampler if validation_sampler is not None else ValidationSplitSampler( min_future=prediction_length))
def test_studentT_likelihood( mu: float, sigma: float, nu: float, hybridize: bool ) -> None: """ Test to check that maximizing the likelihood recovers the parameters """ # generate samples mus = mx.nd.zeros((NUM_SAMPLES,)) + mu sigmas = mx.nd.zeros((NUM_SAMPLES,)) + sigma nus = mx.nd.zeros((NUM_SAMPLES,)) + nu distr = StudentT(mus, sigmas, nus) samples = distr.sample() # nu takes very long to learn, so we initialize it at the true value. # transform used is softplus(x) + 2 init_bias = [ mu - START_TOL_MULTIPLE * TOL * mu, inv_softplus(sigma - START_TOL_MULTIPLE * TOL * sigma), inv_softplus(nu - 2), ] mu_hat, sigma_hat, nu_hat = maximum_likelihood_estimate_sgd( StudentTOutput(), samples, init_biases=init_bias, hybridize=hybridize, num_epochs=PositiveInt(10), learning_rate=PositiveFloat(1e-2), ) assert ( np.abs(mu_hat - mu) < TOL * mu ), f"mu did not match: mu = {mu}, mu_hat = {mu_hat}" assert ( np.abs(sigma_hat - sigma) < TOL * sigma ), f"sigma did not match: sigma = {sigma}, sigma_hat = {sigma_hat}" assert ( np.abs(nu_hat - nu) < TOL * nu ), "nu0 did not match: nu0 = %s, nu_hat = %s" % (nu, nu_hat)
def test_distribution(): """ Makes sure additional tensors can be accessed and have expected shapes """ prediction_length = ds_info.prediction_length estimator = DeepAREstimator( freq=freq, prediction_length=prediction_length, trainer=Trainer(epochs=2, num_batches_per_epoch=1), distr_output=StudentTOutput(), ) train_output = estimator.train_model(train_ds, test_ds) # todo adapt loader to anomaly detection use-case batch_size = 2 num_samples = 3 training_data_loader = TrainDataLoader( dataset=train_ds, transform=train_output.transformation, batch_size=batch_size, num_batches_per_epoch=estimator.trainer.num_batches_per_epoch, ctx=mx.cpu(), ) seq_len = 2 * ds_info.prediction_length for data_entry in islice(training_data_loader, 1): input_names = get_hybrid_forward_input_names(train_output.trained_net) distr = train_output.trained_net.distribution( *[data_entry[k] for k in input_names] ) assert distr.sample(num_samples).shape == ( num_samples, batch_size, seq_len, )
def __init__( self, freq: str, prediction_length: int, sampling: bool = True, trainer: Trainer = Trainer(), num_hidden_dimensions: Optional[List[int]] = None, context_length: Optional[int] = None, distr_output: DistributionOutput = StudentTOutput(), batch_normalization: bool = False, mean_scaling: bool = True, num_parallel_samples: int = 100, ) -> None: """ Defines an estimator. All parameters should be serializable. """ super().__init__(trainer=trainer) assert (prediction_length > 0), "The value of `prediction_length` should be > 0" assert (context_length is None or context_length > 0 ), "The value of `context_length` should be > 0" assert num_hidden_dimensions is None or ([ d > 0 for d in num_hidden_dimensions ]), "Elements of `num_hidden_dimensions` should be > 0" assert (num_parallel_samples > 0), "The value of `num_parallel_samples` should be > 0" self.num_hidden_dimensions = (num_hidden_dimensions if num_hidden_dimensions is not None else list([40, 40])) self.prediction_length = prediction_length self.context_length = (context_length if context_length is not None else prediction_length) self.freq = freq self.distr_output = distr_output self.batch_normalization = batch_normalization self.mean_scaling = mean_scaling self.num_parallel_samples = num_parallel_samples self.sampling = sampling
), f"categorical dist: nan_prob did not match: nan_prob = {nan_prob}, nan_prob_hat = {nan_prob_hat}" n_cat = 3 cat_probs = np.array([0.2, 0.3, 0.5]) cat_samples = np.random.choice( list(range(n_cat)), p=cat_probs, size=NUM_SAMPLES ) cat_samples = np.where( np.random.uniform(size=(NUM_SAMPLES)) > nan_prob, cat_samples, np.nan ) @pytest.mark.parametrize( "distribution_output", [GaussianOutput(), StudentTOutput(), CategoricalOutput(num_cats=2),], ) @pytest.mark.parametrize("serialize_fn", serialize_fn_list) def test_nanmixture_output(distribution_output, serialize_fn) -> None: nmdo = NanMixtureOutput(distribution_output) args_proj = nmdo.get_args_proj() args_proj.initialize() input = mx.nd.ones(shape=(3, 2)) distr_args = args_proj(input) d = nmdo.distribution(distr_args) d = serialize_fn(d)
def __init__( self, freq: str, prediction_length: int, context_length: Optional[int] = None, trainer: Trainer = Trainer(), dropout_rate: float = 0.1, cardinality: Optional[List[int]] = None, embedding_dimension: int = 20, distr_output: DistributionOutput = StudentTOutput(), model_dim: int = 32, inner_ff_dim_scale: int = 4, pre_seq: str = "dn", post_seq: str = "drn", act_type: str = "softrelu", num_heads: int = 8, scaling: bool = True, lags_seq: Optional[List[int]] = None, time_features: Optional[List[TimeFeature]] = None, use_feat_dynamic_real: bool = False, use_feat_static_cat: bool = False, num_parallel_samples: int = 100, train_sampler: Optional[InstanceSampler] = None, validation_sampler: Optional[InstanceSampler] = None, 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 (context_length is None or context_length > 0 ), "The value of `context_length` should be > 0" assert dropout_rate >= 0, "The value of `dropout_rate` should be >= 0" assert (cardinality is not None or not use_feat_static_cat ), "You must set `cardinality` if `use_feat_static_cat=True`" assert cardinality is None or all( [c > 0 for c in cardinality]), "Elements of `cardinality` should be > 0" assert (embedding_dimension > 0), "The value of `embedding_dimension` should be > 0" assert (num_parallel_samples > 0), "The value of `num_parallel_samples` should be > 0" self.freq = freq self.prediction_length = prediction_length self.context_length = (context_length if context_length is not None else prediction_length) self.distr_output = distr_output 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 use_feat_static_cat else [1] self.embedding_dimension = embedding_dimension self.num_parallel_samples = num_parallel_samples self.lags_seq = (lags_seq if lags_seq is not None else get_lags_for_frequency(freq_str=freq)) self.time_features = (time_features if time_features is not None else time_features_from_frequency_str(self.freq)) self.history_length = self.context_length + max(self.lags_seq) self.scaling = scaling self.config = { "model_dim": model_dim, "pre_seq": pre_seq, "post_seq": post_seq, "dropout_rate": dropout_rate, "inner_ff_dim_scale": inner_ff_dim_scale, "act_type": act_type, "num_heads": num_heads, } self.encoder = TransformerEncoder(self.context_length, self.config, prefix="enc_") self.decoder = TransformerDecoder(self.prediction_length, self.config, prefix="dec_") self.train_sampler = (train_sampler if train_sampler is not None else ExpectedNumInstanceSampler( num_instances=1.0, min_future=prediction_length)) self.validation_sampler = (validation_sampler if validation_sampler is not None else ValidationSplitSampler( min_future=prediction_length))
def __init__( self, freq: str, prediction_length: int, trainer: Trainer = Trainer(), context_length: Optional[int] = None, num_layers: int = 2, num_cells: int = 40, cell_type: str = "lstm", dropout_rate: float = 0.1, use_feat_dynamic_real: bool = False, use_feat_static_cat: bool = False, use_feat_static_real: bool = False, cardinality: Optional[List[int]] = None, embedding_dimension: Optional[List[int]] = None, distr_output: DistributionOutput = StudentTOutput(), scaling: bool = True, lags_seq: Optional[List[int]] = None, time_features: Optional[List[TimeFeature]] = None, num_parallel_samples: int = 100, imputation_method: Optional[MissingValueImputation] = None, dtype: DType = np.float32, ) -> None: super().__init__(trainer=trainer, dtype=dtype) assert ( prediction_length > 0 ), "The value of `prediction_length` should be > 0" assert ( context_length is None or context_length > 0 ), "The value of `context_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 dropout_rate >= 0, "The value of `dropout_rate` should be >= 0" assert (cardinality and use_feat_static_cat) or ( not (cardinality or use_feat_static_cat) ), "You should set `cardinality` if and only if `use_feat_static_cat=True`" assert cardinality is None or all( [c > 0 for c in cardinality] ), "Elements of `cardinality` should be > 0" assert embedding_dimension is None or all( [e > 0 for e in embedding_dimension] ), "Elements of `embedding_dimension` should be > 0" assert ( num_parallel_samples > 0 ), "The value of `num_parallel_samples` should be > 0" self.freq = freq self.context_length = ( context_length if context_length is not None else prediction_length ) self.prediction_length = prediction_length self.distr_output = distr_output self.distr_output.dtype = dtype self.num_layers = num_layers self.num_cells = num_cells self.cell_type = cell_type self.dropout_rate = dropout_rate self.use_feat_dynamic_real = use_feat_dynamic_real self.use_feat_static_cat = use_feat_static_cat self.use_feat_static_real = use_feat_static_real 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.scaling = scaling self.lags_seq = ( lags_seq if lags_seq is not None else get_lags_for_frequency(freq_str=freq) ) self.time_features = ( time_features if time_features is not None else time_features_from_frequency_str(self.freq) ) self.history_length = self.context_length + max(self.lags_seq) self.num_parallel_samples = num_parallel_samples self.imputation_method = ( imputation_method if imputation_method is not None else DummyValueImputation(self.distr_output.value_in_support) )
) @pytest.mark.parametrize( "distr_out, data, loc, scale, expected_batch_shape, expected_event_shape", [ ( GaussianOutput(), mx.nd.random.normal(shape=(3, 4, 5, 6)), [None, mx.nd.ones(shape=(3, 4, 5))], [None, mx.nd.ones(shape=(3, 4, 5))], (3, 4, 5), (), ), ( StudentTOutput(), mx.nd.random.normal(shape=(3, 4, 5, 6)), [None, mx.nd.ones(shape=(3, 4, 5))], [None, mx.nd.ones(shape=(3, 4, 5))], (3, 4, 5), (), ), ( GammaOutput(), mx.nd.random.gamma(shape=(3, 4, 5, 6)), [None, mx.nd.ones(shape=(3, 4, 5))], [None, mx.nd.ones(shape=(3, 4, 5))], (3, 4, 5), (), ), (
DirichletMultinomialOutput(dim=3, n_trials=5), DirichletOutput(dim=4), EmpiricalDistributionOutput(num_samples=10, distr_output=GaussianOutput()), GammaOutput(), GaussianOutput(), GenParetoOutput(), LaplaceOutput(), LogitNormalOutput(), LoglogisticOutput(), LowrankMultivariateGaussianOutput(dim=5, rank=2), MultivariateGaussianOutput(dim=4), NegativeBinomialOutput(), OneInflatedBetaOutput(), PiecewiseLinearOutput(num_pieces=10), PoissonOutput(), StudentTOutput(), UniformOutput(), WeibullOutput(), ZeroAndOneInflatedBetaOutput(), ZeroInflatedBetaOutput(), ZeroInflatedNegativeBinomialOutput(), ZeroInflatedPoissonOutput(), ], ) def test_distribution_output_serde(distr_output: DistributionOutput): distr_output_copy = decode(encode(distr_output)) assert isinstance(distr_output_copy, type(distr_output)) assert dump_json(distr_output_copy) == dump_json(distr_output)
def train(args): # Parse arguments epochs = args.epochs pred_length = args.pred_length num_layers = args.num_layers num_cells = args.num_cells dropout_rate = args.dropout_rate batch_size = args.batch_size lr = args.lr model_dir = args.model_dir data_dir = args.data_dir num_gpus = args.num_gpus output_dir = args.output_dir device = "gpu" if num_gpus > 0 else "cpu" FREQ = 'D' target_col = 'Weekly_Sales_sum' related_cols = ['Temperature', 'Fuel_Price', 'CPI', 'Unemployment'] # Get training data target_train_df = pd.read_csv(os.path.join(data_dir, 'target_train.csv'), index_col=0, header=[0,1]) related_train_df = pd.read_csv(os.path.join(data_dir, 'related_train.csv'), index_col=0, header=[0,1]) store_df = pd.read_csv(os.path.join(data_dir, 'item.csv'), index_col=0) num_steps, num_series = target_train_df.shape target = target_train_df.values start_train_dt = target_train_df.index[0] custom_ds_metadata = {'num_series': num_series, 'num_steps': num_steps, 'prediction_length': pred_length, 'freq': FREQ, 'start': [start_train_dt for _ in range(num_series)] } # Prepare GlounTS Dataset related_list = [related_train_df[c].values for c in related_cols] train_lst = [] for i in range(0, num_series): target_vec = target[:-pred_length, i] related_vecs = [related[:-pred_length, i] for related in related_list] item = store_df.loc[i+1] dic = {FieldName.TARGET: target_vec, FieldName.START: start_train_dt, FieldName.FEAT_DYNAMIC_REAL: related_vecs, FieldName.FEAT_STATIC_CAT: [item[0]], FieldName.FEAT_STATIC_REAL: [item[1]] } train_lst.append(dic) test_lst = [] for i in range(0, num_series): target_vec = target[:, i] related_vecs = [related[:, i] for related in related_list] item = store_df.loc[i+1] dic = {FieldName.TARGET: target_vec, FieldName.START: start_train_dt, FieldName.FEAT_DYNAMIC_REAL: related_vecs, FieldName.FEAT_STATIC_CAT: [item[0]], FieldName.FEAT_STATIC_REAL: [item[1]] } test_lst.append(dic) train_ds = ListDataset(train_lst, freq=FREQ) test_ds = ListDataset(test_lst, freq=FREQ) # Define Estimator trainer = Trainer( ctx=device, epochs=epochs, learning_rate=lr, batch_size=batch_size ) deepar_estimator = DeepAREstimator(freq=FREQ, prediction_length=pred_length, use_feat_dynamic_real=True, use_feat_static_cat=True, use_feat_static_real=True, cardinality=[3], num_cells=30, distr_output=StudentTOutput(), trainer=trainer) # Train the model deepar_predictor = deepar_estimator.train(train_ds) # Evaluate trained model on test data forecast_it, ts_it = make_evaluation_predictions(test_ds, deepar_predictor, num_samples=100) forecasts = list(forecast_it) tss = list(ts_it) evaluator = Evaluator(quantiles=[0.1, 0.5, 0.9]) agg_metrics, item_metrics = evaluator(iter(tss), iter(forecasts), num_series=len(test_ds)) metrics = ['RMSE', 'MAPE', 'wQuantileLoss[0.1]', 'wQuantileLoss[0.5]', 'wQuantileLoss[0.9]', 'mean_wQuantileLoss'] metrics_dic = dict((key,value) for key, value in agg_metrics.items() if key in metrics) print(json.dumps(metrics_dic, indent=2)) # Save the model deepar_predictor.serialize(pathlib.Path(model_dir)) return deepar_predictor
) < 0.05 ) # can only calculated cdf for gaussians currently if isinstance(distr1, Gaussian) and isinstance(distr2, Gaussian): emp_cdf, edges = empirical_cdf(samples_mix.asnumpy()) calc_cdf = mixture.cdf(mx.nd.array(edges)).asnumpy() assert np.allclose(calc_cdf[1:, :], emp_cdf, atol=1e-2) @pytest.mark.parametrize( "distribution_outputs", [ ((GaussianOutput(), GaussianOutput()),), ((GaussianOutput(), StudentTOutput(), LaplaceOutput()),), ((MultivariateGaussianOutput(3), MultivariateGaussianOutput(3)),), ], ) @pytest.mark.parametrize("serialize_fn", serialize_fn_list) def test_mixture_output(distribution_outputs, serialize_fn) -> None: mdo = MixtureDistributionOutput(*distribution_outputs) args_proj = mdo.get_args_proj() args_proj.initialize() input = mx.nd.ones(shape=(512, 30)) distr_args = args_proj(input) d = mdo.distribution(distr_args) d = serialize_fn(d)
CAN_USE_EXTERNAL_FEATURES: True, ESTIMATOR: TransformerEstimator, TRAINER: Trainer, }, "mqcnn": { LABEL: "MQ-CNN", CAN_USE_EXTERNAL_FEATURES: True, ESTIMATOR: MQCNNEstimator, TRAINER: Trainer, }, } # these parameter are classes but are set as strings in the UI CLASS_PARAMETERS = { "distr_output": { "StudentTOutput()": StudentTOutput(), "GaussianOutput()": GaussianOutput(), "NegativeBinomialOutput()": NegativeBinomialOutput() }, "model": { "ARIMA": ARIMA, "ETSModel": ETSModel }, } class ModelParameterError(ValueError): """Custom exception raised when the GluonTS model parameters chosen by the user are invalid""" pass
def __init__( self, freq: str, prediction_length: int, trainer: Trainer = Trainer(), context_length: Optional[int] = None, num_layers: int = 2, num_cells: int = 40, cell_type: str = "lstm", dropoutcell_type: str = "ZoneoutCell", dropout_rate: float = 0.1, use_feat_dynamic_real: bool = False, use_feat_static_cat: bool = False, use_feat_static_real: bool = False, cardinality: Optional[List[int]] = None, embedding_dimension: Optional[List[int]] = None, distr_output: DistributionOutput = StudentTOutput(), scaling: bool = True, lags_seq: Optional[List[int]] = None, time_features: Optional[List[TimeFeature]] = None, num_parallel_samples: int = 100, imputation_method: Optional[MissingValueImputation] = None, train_sampler: Optional[InstanceSampler] = None, validation_sampler: Optional[InstanceSampler] = None, dtype: DType = np.float32, alpha: float = 0.0, beta: float = 0.0, batch_size: int = 32, default_scale: Optional[float] = None, minimum_scale: float = 1e-10, impute_missing_values: bool = False, num_imputation_samples: int = 1, ) -> None: super().__init__(trainer=trainer, batch_size=batch_size, dtype=dtype) assert (prediction_length > 0), "The value of `prediction_length` should be > 0" assert (context_length is None or context_length > 0 ), "The value of `context_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" supported_dropoutcell_types = [ "ZoneoutCell", "RNNZoneoutCell", "VariationalDropoutCell", "VariationalZoneoutCell", ] assert ( dropoutcell_type in supported_dropoutcell_types ), f"`dropoutcell_type` should be one of {supported_dropoutcell_types}" assert dropout_rate >= 0, "The value of `dropout_rate` should be >= 0" assert (cardinality and use_feat_static_cat) or ( not (cardinality or use_feat_static_cat) ), "You should set `cardinality` if and only if `use_feat_static_cat=True`" assert cardinality is None or all( [c > 0 for c in cardinality]), "Elements of `cardinality` should be > 0" assert embedding_dimension is None or all([ e > 0 for e in embedding_dimension ]), "Elements of `embedding_dimension` should be > 0" assert (num_parallel_samples > 0), "The value of `num_parallel_samples` should be > 0" assert alpha >= 0, "The value of `alpha` should be >= 0" assert beta >= 0, "The value of `beta` should be >= 0" self.freq = freq self.context_length = (context_length if context_length is not None else prediction_length) self.prediction_length = prediction_length self.distr_output = distr_output self.distr_output.dtype = dtype self.num_layers = num_layers self.num_cells = num_cells self.cell_type = cell_type self.dropoutcell_type = dropoutcell_type self.dropout_rate = dropout_rate self.use_feat_dynamic_real = use_feat_dynamic_real self.use_feat_static_cat = use_feat_static_cat self.use_feat_static_real = use_feat_static_real 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.scaling = scaling self.lags_seq = (lags_seq if lags_seq is not None else get_lags_for_frequency(freq_str=freq)) self.time_features = (time_features if time_features is not None else time_features_from_frequency_str(self.freq)) self.history_length = self.context_length + max(self.lags_seq) self.num_parallel_samples = num_parallel_samples self.imputation_method = (imputation_method if imputation_method is not None else DummyValueImputation( self.distr_output.value_in_support)) self.train_sampler = (train_sampler if train_sampler is not None else ExpectedNumInstanceSampler( num_instances=1.0, min_future=prediction_length)) self.validation_sampler = (validation_sampler if validation_sampler is not None else ValidationSplitSampler( min_future=prediction_length)) self.alpha = alpha self.beta = beta self.num_imputation_samples = num_imputation_samples self.default_scale = default_scale self.minimum_scale = minimum_scale self.impute_missing_values = impute_missing_values
def train(args): # Parse arguments epochs = args.epochs pred_length = args.pred_length num_layers = args.num_layers num_cells = args.num_cells dropout_rate = args.dropout_rate batch_size = args.batch_size lr = args.lr model_dir = args.model_dir data_dir = args.data_dir num_gpus = args.num_gpus output_dir = args.output_dir device = "gpu" if num_gpus > 0 else "cpu" FREQ = 'D' # Get training data target_df = pd.read_csv(os.path.join(data_dir, 'target_train.csv')) target_df.set_index(target_df.columns[0], inplace=True) target = target_df.values num_steps, num_series = target_df.shape start_dt = target_df.index[0] custom_ds_metadata = { 'num_series': num_series, 'num_steps': num_steps, 'prediction_length': pred_length, 'freq': FREQ, 'start': [start_dt for _ in range(num_series)] } # Prepare GlounTS Dataset train_lst = [] for i in range(0, num_series): target_vec = target[:-pred_length, i] dic = {FieldName.TARGET: target_vec, FieldName.START: start_dt} train_lst.append(dic) test_lst = [] for i in range(0, num_series): target_vec = target[:, i] dic = {FieldName.TARGET: target_vec, FieldName.START: start_dt} test_lst.append(dic) train_ds = ListDataset(train_lst, freq=FREQ) test_ds = ListDataset(test_lst, freq=FREQ) train_entry = next(iter(train_ds)) train_entry.keys() # Define Estimator trainer = Trainer(ctx=device, epochs=epochs, learning_rate=lr, batch_size=batch_size) deepar_estimator = DeepAREstimator(freq=FREQ, prediction_length=pred_length, num_cells=num_cells, dropout_rate=dropout_rate, num_layers=num_layers, distr_output=StudentTOutput(), trainer=trainer) # Train the model deepar_predictor = deepar_estimator.train(train_ds) # Evaluate trained model on test data forecast_it, ts_it = make_evaluation_predictions(test_ds, deepar_predictor, num_samples=100) forecasts = list(forecast_it) tss = list(ts_it) evaluator = Evaluator(quantiles=[0.1, 0.5, 0.9]) agg_metrics, item_metrics = evaluator(iter(tss), iter(forecasts), num_series=len(test_ds)) metrics = [ 'RMSE', 'MAPE', 'wQuantileLoss[0.1]', 'wQuantileLoss[0.5]', 'wQuantileLoss[0.9]', 'mean_wQuantileLoss' ] metrics_dic = dict( (key, value) for key, value in agg_metrics.items() if key in metrics) print(json.dumps(metrics_dic, indent=2)) # Save the model deepar_predictor.serialize(pathlib.Path(model_dir)) return deepar_predictor