示例#1
0
def run_demo(best_path, record_save_path):
    print("============Begin Testing============")
    test_record_path = f'{record_save_path}/stgat_test_record.csv'
    dataloader = util.load_dataset(device, args.data_path, args.batch_size, args.batch_size, args.batch_size)
    g_temp = util.add_nodes_edges(adj_filename=args.adj_path, num_of_vertices=args.num_nodes)
    scaler = dataloader['scaler']
    run_gconv = 1
    lr_decay_rate = 0.97

    model = stgat(g=g_temp, run_gconv=run_gconv)
    model.to(device)
    model.zero_grad()
    optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
    optimizer.zero_grad()
    scheduler = torch.optim.lr_scheduler.LambdaLR(
        optimizer, lr_lambda=lambda epoch: lr_decay_rate ** epoch)

    if torch.cuda.is_available():
        model.load_state_dict(torch.load(best_path))
    else:
        model.load_state_dict(torch.load(best_path, map_location='cpu'))

    outputs = []
    target = torch.Tensor(dataloader['y_test']).to(device)
    target = target[:, :, :, 0]
    print("201 y_test:", target.shape)

    for iter, (x, y) in enumerate(dataloader['test_loader'].get_iterator()):
        testx = torch.Tensor(x).to(device).transpose(1, 3)
        testx = nn.functional.pad(testx, (1, 0, 0, 0))
        with torch.no_grad():
            pred = model.forward(testx).squeeze(3)
        print("iter: ", iter)
        print("pred: ", pred.shape)
        outputs.append(pred)

    yhat = torch.cat(outputs, dim=0)
    yhat = yhat[:target.size(0), ...]
    test_record, amape, armse, amae = [], [], [], []

    pred = scaler.inverse_transform(yhat)
    for i in range(12):
        pred_t = pred[:, i, :]
        real_target = target[:, i, :]
        evaluation = evaluate_all(pred_t, real_target)
        log = 'test for horizon {:d}, Test MAPE: {:.4f}, Test RMSE: {:.4f}, Test MAE: {:.4f}'
        print(log.format(i + 1, evaluation[0], evaluation[1], evaluation[2]))
        amape.append(evaluation[0])
        armse.append(evaluation[1])
        amae.append(evaluation[2])
        test_record.append([x for x in evaluation])
    test_record_df = pd.DataFrame(test_record, columns=['mape', 'rmse', 'mae']).rename_axis('t')
    test_record_df.round(3).to_csv(test_record_path)
    log = 'On average over 12 horizons, Test MAE: {:.4f}, Test MAPE: {:.4f}, Test RMSE: {:.4f}'
    print(log.format(np.mean(amae), np.mean(amape), np.mean(armse)))
    print("=" * 10)
示例#2
0
def run_demo(best_path, record_save_path, model_type):
    print("============Begin Testing============")
    test_record_path = f'{record_save_path}/test_record.csv'
    dataloader = util.load_dataset(device, args.data_path, args.batch_size,
                                   args.batch_size, args.batch_size)
    g_temp = util.add_nodes_edges(adj_filename=args.adj_path,
                                  num_of_vertices=args.num_nodes)
    scaler = dataloader['scaler']
    run_gconv = 1
    lr_decay_rate = 0.97

    sensor_ids, sensor_id_to_ind, adj_mx = util.load_adj(
        args.adj_path_forbase, args.adjtype)
    supports = [torch.tensor(i).to(device) for i in adj_mx]

    _, _, A = util.load_pickle(args.adj_path_forbase)
    A_wave = util.get_normalized_adj(A)
    A_wave = torch.from_numpy(A_wave).to(device)
    # print("A_wave:", A_wave.shape, type(A_wave))
    best_mae = 100

    if args.randomadj:
        adjinit = None
    else:
        adjinit = supports[0]
    if args.aptonly:
        supports = None

    if model_type == "GWaveNet":
        print("=========Model:GWaveNet=========")
        print("with scaler")
        model = GWNET(device,
                      args.num_nodes,
                      args.dropout,
                      supports=supports,
                      gcn_bool=args.gcn_bool,
                      addaptadj=args.addaptadj,
                      aptinit=adjinit,
                      in_dim=args.in_dim,
                      out_dim=args.seq_length,
                      residual_channels=args.nhid,
                      dilation_channels=args.nhid,
                      skip_channels=args.nhid * 8,
                      end_channels=args.nhid * 16)

    if model_type == "STGCN":
        print("=========Model:STGCN=========")
        print("with scaler")
        model = STGCN(A_wave.shape[0],
                      2,
                      num_timesteps_input=12,
                      num_timesteps_output=12)

    if model_type == "LSTM":
        print("=========Model:LSTM=========")
        input_dim = 2
        hidden_dim = 2
        output_dim = 2
        model = LSTM(input_dim, hidden_dim, output_dim)

    model.to(device)
    model.zero_grad()
    optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
    optimizer.zero_grad()
    scheduler = torch.optim.lr_scheduler.LambdaLR(
        optimizer, lr_lambda=lambda epoch: lr_decay_rate**epoch)

    if torch.cuda.is_available():
        model.load_state_dict(torch.load(best_path))
    else:
        model.load_state_dict(torch.load(best_path, map_location='cpu'))

    outputs = []
    target = torch.Tensor(dataloader['y_test']).to(device)
    target = target[:, :, :, 0]
    print("201 y_test:", target.shape)

    for iter, (x, y) in enumerate(dataloader['test_loader'].get_iterator()):
        testx = torch.Tensor(x).to(device).transpose(1, 3)
        testx = nn.functional.pad(testx, (1, 0, 0, 0))
        with torch.no_grad():
            pred = model.forward(testx).squeeze(3)
        print("iter: ", iter)
        print("pred: ", pred.shape)
        outputs.append(pred)

    yhat = torch.cat(outputs, dim=0)
    yhat = yhat[:target.size(0), ...]
    test_record, amape, armse, amae = [], [], [], []

    pred = scaler.inverse_transform(yhat)
    for i in range(12):
        pred_t = pred[:, i, :]
        real_target = target[:, i, :]
        evaluation = evaluate_all(pred_t, real_target)
        log = 'test for horizon {:d}, Test MAPE: {:.4f}, Test RMSE: {:.4f}, Test MAE: {:.4f}'
        print(log.format(i + 1, evaluation[0], evaluation[1], evaluation[2]))
        amape.append(evaluation[0])
        armse.append(evaluation[1])
        amae.append(evaluation[2])
        test_record.append([x for x in evaluation])
    test_record_df = pd.DataFrame(test_record,
                                  columns=['mape', 'rmse',
                                           'mae']).rename_axis('t')
    test_record_df.round(3).to_csv(test_record_path)
    log = 'On average over 12 horizons, Test MAE: {:.4f}, Test MAPE: {:.4f}, Test RMSE: {:.4f}'
    print(log.format(np.mean(amae), np.mean(amape), np.mean(armse)))
    print("=" * 10)
示例#3
0
文件: train.py 项目: AI678/ST-MGAT
def main():
    print("*" * 10)
    print(args)
    print("*" * 10)

    dataloader = util.load_dataset(device, args.data_path, args.batch_size,
                                   args.batch_size, args.batch_size)
    g_temp = util.add_nodes_edges(adj_filename=args.adj_path,
                                  num_of_vertices=args.num_nodes)

    scaler = dataloader['scaler']
    test_scaler = dataloader['test_scaler']

    clip = 3
    run_gconv = 1
    best_mae = 100
    continue_train = 0
    lr_decay_rate = 0.97
    record = []

    model = stgat(g=g_temp, run_gconv=run_gconv)
    model.to(device)
    model.zero_grad()
    optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
    optimizer.zero_grad()
    scheduler = torch.optim.lr_scheduler.LambdaLR(
        optimizer, lr_lambda=lambda epoch: lr_decay_rate**epoch)

    loss = util.masked_mae
    best_path = os.path.join(args.save, 'best_model.pkl')
    # / in path ????

    # if you want to train model with the last parameters
    if continue_train:
        path = './experiment/last_record.pkl'
        print("reload the model from :{}", path)
        model.load_state_dict(torch.load(path))

    print("============Begin Training============")
    his_loss, val_time, train_time = [], [], []
    for epoch in range(args.num_epochs):
        print('-' * 10)
        print('Epoch {}/{}'.format(epoch, args.num_epochs - 1))
        train_loss, train_mape, train_rmse = [], [], []
        t1 = time.time()
        t = time.time()
        dataloader['train_loader'].shuffle()
        for iter, (x,
                   y) in enumerate(dataloader['train_loader'].get_iterator()):
            trainx = torch.Tensor(x).to(device).transpose(
                1, 3)  # x: (64, 2, 207, 12)
            trainy = torch.Tensor(y).to(device)  # (64, 12, 207, 2)
            trainy = trainy[:, :, :,
                            0]  # only predict speed/ you can replace it with any features you want

            if trainx.shape[0] != args.batch_size:
                continue
            # print("117:", trainx.shape)
            trainx = nn.functional.pad(trainx,
                                       (1, 0, 0, 0))  # ([64, 2, 207, 13])
            # print("119:", trainx.shape)
            pred = model.forward(trainx).squeeze(3)
            pred = scaler.inverse_transform(pred)
            # pred = test_scaler.inverse_transform(pred)

            if iter == 0:
                print("trainy:", trainy.shape)  # ([64, 12, 207])
                print("pred:", pred.shape)

            # loss_train = loss_MSE(pred, trainy)
            mae_loss_train = loss(pred, trainy, 0.0)
            optimizer.zero_grad()
            mae_loss_train.backward()
            if clip is not None:
                torch.nn.utils.clip_grad_norm_(model.parameters(), clip)
            optimizer.step()

            evaluation = evaluate(pred, trainy)
            train_loss.append(mae_loss_train.item())
            train_mape.append(evaluation[0])
            train_rmse.append(evaluation[1])

            if iter % args.interval == 0:
                log = 'Iter: {:03d}|Train Loss: {:.4f}|Time: {:.4f}'
                print(log.format(iter, train_loss[-1],
                                 time.time() - t),
                      flush=True)
                t = time.time()
        scheduler.step()
        t2 = time.time()
        train_time.append(t2 - t1)

        # validation
        valid_loss, valid_mape, valid_rmse = [], [], []
        s1 = time.time()
        for iter, (x_val, y_val) in enumerate(
                dataloader['val_loader'].get_iterator()):
            inputs_val = torch.Tensor(x_val).to(device).transpose(
                1, 3)  # x: (64, 24, 207, 2)
            labels_val = torch.Tensor(y_val).to(device)
            labels_val = labels_val[:, :, :, 0]

            inputs_val = nn.functional.pad(inputs_val, (1, 0, 0, 0))
            pred_val = model.forward(inputs_val).squeeze(3)
            pred_val = scaler.inverse_transform(pred_val)
            # pred_val = test_scaler.inverse_transform(pred_val)

            mae_loss_val = loss(pred_val, labels_val, 0.0)
            optimizer.zero_grad()
            mae_loss_val.backward()
            evaluation = evaluate(pred_val, labels_val)

            valid_loss.append(mae_loss_val.item())
            valid_mape.append(evaluation[0])
            valid_rmse.append(evaluation[1])

        s2 = time.time()
        # log = 'Epoch: {:03d}, Inference Time: {:.4f} secs'
        # print(log.format(epoch, (s2 - s1)))
        val_time.append(s2 - s1)

        mtrain_loss = np.mean(train_loss)
        mtrain_mape = np.mean(train_mape)
        mtrain_rmse = np.mean(train_rmse)

        mvalid_loss = np.mean(valid_loss)
        mvalid_mape = np.mean(valid_mape)
        mvalid_rmse = np.mean(valid_rmse)
        his_loss.append(mvalid_loss)

        # save best model parameters, evaluation of every epochs
        message = dict(train_loss=mtrain_loss,
                       train_mape=mtrain_mape,
                       train_rmse=mtrain_rmse,
                       valid_loss=mvalid_loss,
                       valid_mape=mvalid_mape,
                       valid_rmse=mvalid_rmse)
        message = pd.Series(message)
        record.append(message)
        record_df = pd.DataFrame(record)
        record_df.round(3).to_csv(f'{args.save}/record.csv')

        if message.valid_loss < best_mae:
            torch.save(model.state_dict(), best_path)
            best_mae = message.valid_loss
            epochs_since_best_mae = 0
            best_epoch = epoch
        else:
            epochs_since_best_mae += 1

        log = 'Epoch: {:03d}, Training Time: {:.4f}/epoch,\n' \
              'Train Loss: {:.4f}  \n' \
              'Valid Loss: {:.4f}, Valid MAPE: {:.4f}, Valid RMSE: {:.4f}' \
              'best epoch: {} , best val_loss: {}, epochs since best: {}'
        print(log.format(epoch, (t2 - t1), mtrain_loss, mvalid_loss,
                         mvalid_mape, mvalid_rmse, best_epoch,
                         record_df.valid_loss.min().round(3),
                         epochs_since_best_mae),
              flush=True)
        print("#" * 20)

    # finished train
    print("=" * 10)
    print("Average Train Time: {:.4f} secs/epoch".format(np.mean(train_time)))
    print("Average Valid Time: {:.4f} secs".format(np.mean(val_time)))
    print("=" * 10)

    # Testing
    bestid = np.argmin(his_loss)
    print("bestid: ", bestid)
    model.load_state_dict(torch.load(best_path))

    outputs = []
    target = torch.Tensor(dataloader['y_test']).to(device)
    target = target[:, :, :, 0]

    for iter, (x, y) in enumerate(dataloader['test_loader'].get_iterator()):
        testx = torch.Tensor(x).to(device).transpose(1, 3)
        testx = nn.functional.pad(testx, (1, 0, 0, 0))
        with torch.no_grad():
            pred = model.forward(testx).squeeze(3)
        outputs.append(pred)

    yhat = torch.cat(outputs, dim=0)
    yhat = yhat[:target.size(0), ...]
    test_record, amape, armse, amae = [], [], [], []

    pred = scaler.inverse_transform(yhat)
    for i in range(12):
        pred_t = pred[:, i, :]
        real_target = target[:, i, :]
        evaluation = evaluate_all(pred_t, real_target)
        log = 'test for horizon {:d}, Test MAPE: {:.4f}, Test RMSE: {:.4f}, Test MAE: {:.4f}'
        print(log.format(i + 1, evaluation[0], evaluation[1], evaluation[2]))
        amape.append(evaluation[0])
        armse.append(evaluation[1])
        amae.append(evaluation[2])
        test_record.append([x for x in evaluation])
    test_record_df = pd.DataFrame(test_record,
                                  columns=['mape', 'rmse',
                                           'mae']).rename_axis('t')
    test_record_df.round(3).to_csv(f'{args.save}/test_record.csv')
    log = 'On average over 12 horizons, Test MAE: {:.4f}, Test MAPE: {:.4f}, Test RMSE: {:.4f}'
    print(log.format(np.mean(amae), np.mean(amape), np.mean(armse)))
    print("=" * 10)
示例#4
0
文件: train.py 项目: DLwbm123/STGAT
def main():
    print("*" * 10)
    print(args)
    print("*" * 10)
    dataloader = util.load_dataset(device, args.data_path, args.batch_size,
                                   args.batch_size, args.batch_size)
    scaler = dataloader['scaler']
    test_scaler = dataloader['test_scaler']
    g_temp = util.add_nodes_edges(adj_filename=args.adj_path,
                                  num_of_vertices=args.num_nodes)
    record = []

    clip = 3
    best_mae = 100
    lr_decay_rate = 0.97
    run_gconv = 0
    loss = util.masked_mae
    model = batch_g_gat(g_temp, run_gconv)
    print("run_gconv:", run_gconv)
    model.to(device)
    model.zero_grad()
    optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
    optimizer.zero_grad()
    scheduler = torch.optim.lr_scheduler.LambdaLR(
        optimizer, lr_lambda=lambda epoch: lr_decay_rate**epoch)
    bar = progress_bar(list(range(1, args.num_epochs + 1)))
    best_path = os.path.join(args.save, 'best_model.pth')
    his_loss, val_time, train_time = [], [], []
    print("============Begin Training============")
    for epoch in bar:
        # print('-' * 10)
        # print('Epoch {}/{}'.format(epoch, args.num_epochs - 1))
        train_loss, train_mape, train_rmse = [], [], []
        dataloader['train_loader'].shuffle()

        for iter, (x,
                   y) in enumerate(dataloader['train_loader'].get_iterator()):
            trainx = torch.Tensor(x).to(device).transpose(
                1, 3)  # x: (64, 2, 207, 12)
            trainy = torch.Tensor(y).to(device)  # (64, 12, 207, 2)
            trainy = trainy[:, :, :, 0]

            if trainx.shape[0] != args.batch_size:
                continue

            trainx = nn.functional.pad(trainx, (1, 0, 0, 0))
            pred = model.forward(trainx).squeeze(3)
            pred = scaler.inverse_transform(pred)
            # pred = test_scaler.inverse_transform(pred)
            # loss_train = loss_MSE(pred, trainy)
            mae_loss_train = loss(pred, trainy, 0.0)
            optimizer.zero_grad()
            mae_loss_train.backward()
            if clip is not None:
                torch.nn.utils.clip_grad_norm_(model.parameters(), clip)
            optimizer.step()

            evaluation = evaluate(pred, trainy)
            train_loss.append(mae_loss_train.item())
            train_mape.append(evaluation[0])
            train_rmse.append(evaluation[1])
        scheduler.step()

        # validation
        valid_loss, valid_mape, valid_rmse = [], [], []
        for iter, (x_val, y_val) in enumerate(
                dataloader['val_loader'].get_iterator()):
            inputs_val = torch.Tensor(x_val).to(device).transpose(
                1, 3)  # x: (64, 24, 207, 2)
            labels_val = torch.Tensor(y_val).to(device)
            labels_val = labels_val[:, :, :, 0]

            inputs_val = nn.functional.pad(inputs_val, (1, 0, 0, 0))
            pred_val = model.forward(inputs_val).squeeze(3)
            pred_val = scaler.inverse_transform(pred_val)
            # pred_val = test_scaler.inverse_transform(pred_val)

            mae_loss_val = loss(pred_val, labels_val, 0.0)
            optimizer.zero_grad()
            mae_loss_val.backward()
            evaluation = evaluate(pred_val, labels_val)

            valid_loss.append(mae_loss_val.item())
            valid_mape.append(evaluation[0])
            valid_rmse.append(evaluation[1])

        mtrain_loss = np.mean(train_loss)
        mtrain_mape = np.mean(train_mape)
        mtrain_rmse = np.mean(train_rmse)

        mvalid_loss = np.mean(valid_loss)
        mvalid_mape = np.mean(valid_mape)
        mvalid_rmse = np.mean(valid_rmse)
        his_loss.append(mvalid_loss)

        message = dict(train_loss=mtrain_loss,
                       train_mape=mtrain_mape,
                       train_rmse=mtrain_rmse,
                       valid_loss=mvalid_loss,
                       valid_mape=mvalid_mape,
                       valid_rmse=mvalid_rmse)
        message = pd.Series(message)
        record.append(message)

        # save model parameters
        if message.valid_loss < best_mae:
            torch.save(model.state_dict(), best_path)
            best_mae = message.valid_loss
            epochs_since_best_mae = 0
            best_epoch = epoch
        else:
            epochs_since_best_mae += 1

        record_df = pd.DataFrame(record)
        bar.comment = f'best epoch: {best_epoch}, best val_loss: {record_df.valid_loss.min(): .3f}, current val_loss: {message.valid_loss:.3f},current train loss: {message.train_loss: .3f}'
        record_df.round(3).to_csv(f'{args.save}/record.csv')

    # Testing
    bestid = np.argmin(his_loss)
    # print("bestid: ", bestid)
    # print("best_epoch: ", best_epoch)
    # print("best_path: ", best_path)
    model.load_state_dict(torch.load(best_path))

    outputs = []
    target = torch.Tensor(dataloader['y_test']).to(device)
    target = target[:, :, :, 0]

    for iter, (x, y) in enumerate(dataloader['test_loader'].get_iterator()):
        testx = torch.Tensor(x).to(device).transpose(1, 3)
        testx = nn.functional.pad(testx, (1, 0, 0, 0))
        with torch.no_grad():
            pred = model.forward(testx).squeeze(3)
        outputs.append(pred)

    yhat = torch.cat(outputs, dim=0)
    yhat = yhat[:target.size(0), ...]
    amape, armse, amae = [], [], []
    # test_mape, test_rmse, test_mae = evaluate_all(yhat, target)
    # print("=" * 10)
    # print("yhat:", yhat.shape)  # yhat: torch.Size([6850, 12, 207])
    # print("target:", target.shape)  # target: torch.Size([6850, 12, 207])

    pred = scaler.inverse_transform(yhat)
    # pred = test_scaler.inverse_transform(yhat)
    test_record = []
    for i in range(12):
        pred_t = pred[:, i, :]
        real_target = target[:, i, :]
        evaluation = evaluate_all(pred_t, real_target)
        log = 'test data for {:d}, Test MAPE: {:.4f}, Test RMSE: {:.4f}, Test MAE: {:.4f}'
        print(log.format(i + 1, evaluation[0], evaluation[1], evaluation[2]))
        amape.append(evaluation[0])
        armse.append(evaluation[1])
        amae.append(evaluation[2])
        test_record.append([x for x in evaluation])
    test_record_df = pd.DataFrame(test_record,
                                  columns=['mape', 'rmse',
                                           'mae']).rename_axis('t')
    test_record_df.round(3).to_csv(f'{args.save}/test_record.csv')
    log = 'On average over 12 horizons, Test MAE: {:.4f}, Test MAPE: {:.4f}, Test RMSE: {:.4f}'
    print(log.format(np.mean(amae), np.mean(amape), np.mean(armse)))