def train(X, y, args, quantiles): num_ts, num_periods, num_features = X.shape num_quantiles = len(quantiles) model = MQRNN(args.seq_len, num_quantiles, num_features, args.embedding_size, args.encoder_hidden_size, args.n_layers, args.decoder_hidden_size) optimizer = Adam(model.parameters(), lr=args.lr) Xtr, ytr, Xte, yte = util.train_test_split(X, y) losses = [] yscaler = None if args.standard_scaler: yscaler = util.StandardScaler() elif args.log_scaler: yscaler = util.LogScaler() elif args.mean_scaler: yscaler = util.MeanScaler() if yscaler is not None: ytr = yscaler.fit_transform(ytr) num_obs_to_train = args.num_obs_to_train seq_len = args.seq_len progress = ProgressBar() for epoch in progress(range(args.num_epoches)): # print("Epoch {} start...".format(epoch)) for step in range(args.step_per_epoch): X_train_batch, y_train_batch, Xf, yf = batch_generator( Xtr, ytr, num_obs_to_train, args.seq_len, args.batch_size) X_train_tensor = torch.from_numpy(X_train_batch).float() y_train_tensor = torch.from_numpy(y_train_batch).float() Xf = torch.from_numpy(Xf).float() yf = torch.from_numpy(yf).float() ypred = model(X_train_tensor, y_train_tensor, Xf) # quantile loss loss = torch.zeros_like(yf) num_ts = Xf.size(0) for q, rho in enumerate(quantiles): ypred_rho = ypred[:, :, q].view(num_ts, -1) e = ypred_rho - yf loss += torch.max(rho * e, (rho - 1) * e) loss = loss.mean() losses.append(loss.item()) optimizer.zero_grad() loss.backward() optimizer.step() mape_list = [] X_test = Xte[:, -seq_len - num_obs_to_train:-seq_len, :].reshape( (num_ts, -1, num_features)) Xf_test = Xte[:, -seq_len:, :].reshape((num_ts, -1, num_features)) y_test = yte[:, -seq_len - num_obs_to_train:-seq_len].reshape((num_ts, -1)) if yscaler is not None: y_test = yscaler.transform(y_test) yf_test = yte[:, -seq_len:] ypred = model(X_test, y_test, Xf_test) # (1, num_quantiles, output_horizon) ypred = ypred.data.numpy() if yscaler is not None: ypred = yscaler.inverse_transform(ypred) ypred = np.maximum(0, ypred) # P50 quantile MAPE mape = util.MAPE(yf_test, ypred[:, :, 1]) print("MAPE: {}".format(mape)) mape_list.append(mape) if args.show_plot: show_idx = 0 plt.figure(1) plt.plot([k + seq_len + num_obs_to_train - seq_len \ for k in range(seq_len)], ypred[show_idx, :, 1], "r-") plt.fill_between(x=[k + seq_len + num_obs_to_train - seq_len for k in range(seq_len)], \ y1=ypred[show_idx, :, 0], y2=ypred[show_idx, :, 2], alpha=0.5) plt.title('Prediction uncertainty') yplot = yte[show_idx, -seq_len - num_obs_to_train:] plt.plot(range(len(yplot)), yplot, "k-") plt.legend(["P50 forecast", "true", "P10-P90 quantile"], loc="upper left") plt.xlabel("Periods") plt.ylabel("Y") plt.show() return losses, mape_list
def train(X, y, args): ''' Args: - X (array like): shape (num_samples, num_features, num_periods) - y (array like): shape (num_samples, num_periods) - epoches (int): number of epoches to run - step_per_epoch (int): steps per epoch to run - seq_len (int): output horizon - likelihood (str): what type of likelihood to use, default is gaussian - num_skus_to_show (int): how many skus to show in test phase - num_results_to_sample (int): how many samples in test phase as prediction ''' # rho = args.quantile num_ts, num_periods, num_features = X.shape model = DFRNN(num_features, args.noise_nlayers, args.noise_hidden_size, args.global_nlayers, args.global_hidden_size, args.n_factors) optimizer = Adam(model.parameters(), lr=args.lr) random.seed(2) # select sku with most top n quantities Xtr, ytr, Xte, yte = util.train_test_split(X, y) losses = [] cnt = 0 yscaler = None if args.standard_scaler: yscaler = util.StandardScaler() elif args.log_scaler: yscaler = util.LogScaler() elif args.mean_scaler: yscaler = util.MeanScaler() if yscaler is not None: ytr = yscaler.fit_transform(ytr) # training progress = ProgressBar() seq_len = args.seq_len num_obs_to_train = args.num_obs_to_train for epoch in progress(range(args.num_epoches)): # print("Epoch {} starts...".format(epoch)) for step in range(args.step_per_epoch): Xtrain, ytrain, Xf, yf = batch_generator(Xtr, ytr, num_obs_to_train, seq_len, args.batch_size) Xtrain_tensor = torch.from_numpy(Xtrain).float() ytrain_tensor = torch.from_numpy(ytrain).float() Xf = torch.from_numpy(Xf).float() yf = torch.from_numpy(yf).float() mu, sigma = model(Xtrain_tensor) loss = util.gaussian_likelihood_loss(ytrain_tensor, mu, sigma) losses.append(loss.item()) optimizer.zero_grad() loss.backward() optimizer.step() cnt += 1 # test mape_list = [] # select skus with most top K X_test = Xte[:, -seq_len - num_obs_to_train:-seq_len, :].reshape( (num_ts, -1, num_features)) Xf_test = Xte[:, -seq_len:, :].reshape((num_ts, -1, num_features)) y_test = yte[:, -seq_len - num_obs_to_train:-seq_len].reshape((num_ts, -1)) yf_test = yte[:, -seq_len:].reshape((num_ts, -1)) if yscaler is not None: y_test = yscaler.transform(y_test) result = [] n_samples = args.sample_size for _ in tqdm(range(n_samples)): y_pred = model.sample(Xf_test) y_pred = y_pred.data.numpy() if yscaler is not None: y_pred = yscaler.inverse_transform(y_pred) result.append(y_pred.reshape((-1, 1))) result = np.concatenate(result, axis=1) p50 = np.quantile(result, 0.5, axis=1) p90 = np.quantile(result, 0.9, axis=1) p10 = np.quantile(result, 0.1, axis=1) mape = util.MAPE(yf_test, p50) print("P50 MAPE: {}".format(mape)) mape_list.append(mape) if args.show_plot: plt.figure(1, figsize=(20, 5)) plt.plot([k + seq_len + num_obs_to_train - seq_len \ for k in range(seq_len)], p50, "r-") plt.fill_between(x=[k + seq_len + num_obs_to_train - seq_len for k in range(seq_len)], \ y1=p10, y2=p90, alpha=0.5) plt.title('Prediction uncertainty') yplot = yte[-1, -seq_len - num_obs_to_train:] plt.plot(range(len(yplot)), yplot, "k-") plt.legend(["P50 forecast", "true", "P10-P90 quantile"], loc="upper left") ymin, ymax = plt.ylim() plt.vlines(seq_len + num_obs_to_train - seq_len, ymin, ymax, color="blue", linestyles="dashed", linewidth=2) plt.ylim(ymin, ymax) plt.xlabel("Periods") plt.ylabel("Y") plt.show() return losses, mape_list
def train(X, y, args): ''' Args: - X (array like): shape (num_samples, num_features, num_periods) - y (array like): shape (num_samples, num_periods) - epoches (int): number of epoches to run - step_per_epoch (int): steps per epoch to run - seq_len (int): output horizon - likelihood (str): what type of likelihood to use, default is gaussian - num_skus_to_show (int): how many skus to show in test phase - num_results_to_sample (int): how many samples in test phase as prediction ''' rho = args.quantile num_ts, num_periods, num_features = X.shape model = DeepAR(num_features, args.embedding_size, args.hidden_size, args.n_layers, args.lr, args.likelihood) optimizer = Adam(model.parameters(), lr=args.lr) random.seed(2) # select sku with most top n quantities Xtr, ytr, Xte, yte = util.train_test_split(X, y) losses = [] cnt = 0 yscaler = None if args.standard_scaler: yscaler = util.StandardScaler() elif args.log_scaler: yscaler = util.LogScaler() elif args.mean_scaler: yscaler = util.MeanScaler() if yscaler is not None: ytr = yscaler.fit_transform(ytr) # training seq_len = args.seq_len num_obs_to_train = args.num_obs_to_train progress = ProgressBar() for epoch in progress(range(args.num_epoches)): # print("Epoch {} starts...".format(epoch)) for step in range(args.step_per_epoch): Xtrain, ytrain, Xf, yf = batch_generator(Xtr, ytr, num_obs_to_train, seq_len, args.batch_size) Xtrain_tensor = torch.from_numpy(Xtrain).float() ytrain_tensor = torch.from_numpy(ytrain).float() Xf = torch.from_numpy(Xf).float() yf = torch.from_numpy(yf).float() ypred, mu, sigma = model(Xtrain_tensor, ytrain_tensor, Xf) # ypred_rho = ypred # e = ypred_rho - yf # loss = torch.max(rho * e, (rho - 1) * e).mean() ## gaussian loss ytrain_tensor = torch.cat([ytrain_tensor, yf], dim=1) loss = util.gaussian_likelihood_loss(ytrain_tensor, mu, sigma) losses.append(loss.item()) optimizer.zero_grad() loss.backward() optimizer.step() cnt += 1 # test mape_list = [] # select skus with most top K X_test = Xte[:, -seq_len - num_obs_to_train:-seq_len, :].reshape( (num_ts, -1, num_features)) Xf_test = Xte[:, -seq_len:, :].reshape((num_ts, -1, num_features)) y_test = yte[:, -seq_len - num_obs_to_train:-seq_len].reshape((num_ts, -1)) yf_test = yte[:, -seq_len:].reshape((num_ts, -1)) if yscaler is not None: y_test = yscaler.transform(y_test) y_pred, _, _ = model(X_test, y_test, Xf_test) y_pred = y_pred.data.numpy() if yscaler is not None: y_pred = yscaler.inverse_transform(y_pred) mape = util.MAPE(yf_test, y_pred) print("MAPE: {}".format(mape)) mape_list.append(mape) if args.show_plot: plt.figure(1) plt.plot([k + seq_len + num_obs_to_train - seq_len \ for k in range(seq_len)], y_pred[-1], "r-") plt.title('Prediction uncertainty') yplot = yte[-1, -seq_len - num_obs_to_train:] plt.plot(range(len(yplot)), yplot, "k-") plt.legend(["P50 forecast", "true", "P10-P90 quantile"], loc="upper left") plt.xlabel("Periods") plt.ylabel("Y") plt.show() return losses, mape_list
def train(X, y, args): num_ts, num_periods, num_features = X.shape Xtr, ytr, Xte, yte = util.train_test_split(X, y) yscaler = None if args.standard_scaler: yscaler = util.StandardScaler() elif args.log_scaler: yscaler = util.LogScaler() elif args.mean_scaler: yscaler = util.MeanScaler() if yscaler is not None: ytr = yscaler.fit_transform(ytr) progress = ProgressBar() seq_len = args.seq_len num_obs_to_train = args.num_obs_to_train model = ExtremeModel(num_features) optimizer = Adam(model.parameters(), lr=args.lr) losses = [] cnt = 0 for epoch in progress(range(args.num_epoches)): # print("Epoch {} starts...".format(epoch)) for step in range(args.step_per_epoch): Xtrain, ytrain, Xf, yf = batch_generator(Xtr, ytr, num_obs_to_train, seq_len, args.batch_size) Xtrain_tensor = torch.from_numpy(Xtrain).float() ytrain_tensor = torch.from_numpy(ytrain).float() Xf = torch.from_numpy(Xf).float() yf = torch.from_numpy(yf).float() ypred = model(Xtrain_tensor, Xf) loss = F.mse_loss(ypred, yf) losses.append(loss.item()) optimizer.zero_grad() loss.backward() optimizer.step() cnt += 1 mape_list = [] mse_list = [] rmse_list = [] mae_list = [] # select skus with most top K X_test = Xte[:, -seq_len - num_obs_to_train:-seq_len, :].reshape( (num_ts, -1, num_features)) Xf_test = Xte[:, -seq_len:, :].reshape((num_ts, -1, num_features)) y_test = yte[:, -seq_len - num_obs_to_train:-seq_len].reshape((num_ts, -1)) yf_test = yte[:, -seq_len:].reshape((num_ts, -1)) if yscaler is not None: y_test = yscaler.transform(y_test) ypred = model(X_test, Xf_test) ypred = ypred.data.numpy() if yscaler is not None: ypred = yscaler.inverse_transform(ypred) mape = util.MAPE(yf_test, ypred) mae = util.MAE(yf_test, ypred) mse = util.MSE(yf_test, ypred) rmse = util.RMSE(yf_test, ypred) print("MAE: {}".format(mae)) print("RMSE: {}".format(rmse)) print("MSE: {}".format(mse)) print("MAPE: {}".format(mape)) mape_list.append(mape) mse_list.append(mse) mae_list.append(mae) rmse_list.append(rmse) if args.show_plot: plt.figure(1) plt.plot( [k + seq_len + num_obs_to_train - seq_len for k in range(seq_len)], ypred[-1], "r-") plt.title('Prediction uncertainty') yplot = yte[-1, -seq_len - num_obs_to_train:] plt.plot(range(len(yplot)), yplot, "k-") plt.legend(["forecast", "true"], loc="upper left") plt.xlabel("Periods") plt.ylabel("Y") plt.show() return losses, mape_list, mse_list, mae_list, rmse_list
result = [] n_samples = sample_size for _ in tqdm(range(n_samples)): y_pred, _, _ = model(X_test, y_test, Xf_test) y_pred = y_pred.data.numpy() if yscaler is not None: y_pred = yscaler.inverse_transform(y_pred) result.append(y_pred.reshape((-1, 1))) # result (100,12,1) result = np.concatenate(result, axis=1) # (12,100) p50 = np.quantile(result, 0.5, axis=1) # (12,) p90 = np.quantile(result, 0.9, axis=1) p10 = np.quantile(result, 0.1, axis=1) # yf_test(1,12) mape = util.MAPE(yf_test, p50) print("P50 MAPE: {}".format(mape)) mape_list.append(mape) if show_plot: plt.figure(1, figsize=(20, 5)) plt.plot([k + seq_len + num_obs_to_train - seq_len \ for k in range(seq_len)], p50, "r-") plt.fill_between(x=[k + seq_len + num_obs_to_train - seq_len for k in range(seq_len)], \ y1=p10, y2=p90, alpha=0.5) plt.title('Prediction uncertainty') yplot = yte[-1, -seq_len - num_obs_to_train:] plt.plot(range(len(yplot)), yplot, "k-") plt.legend(["P50 forecast", "true", "P10-P90 quantile"], loc="upper left") ymin, ymax = plt.ylim()