示例#1
0
def main(args, num_epochs = 30):
    """
    Args:
        args (dict):    Dictionary of parametres
            args['train_folder']    (str): folder's prefix where dataset is stored
            args['batchsize']       (int): batchsize
            args['opt']             (str): optimizer type
            args['learning_rate']   (float): learning_rate
            args['seed']            (int): number to fix random processes
            args['cuda']            (boolean): True if we can use GPU
            args['load_weight_file'](str): file with weights
            args['model_type']      (str): model type
            args['encoder_latent_vector'] (int): size of encoder latent vector
            args['decoder_latent_vector'] (int): size of decoder latent vector
            args['future_window_size']         (int): number of seconds to predict
            args['past_window_size']          (int): number of seconds using like input
            args['frame_interval']   (int): interval at witch the data was generated
            args["weight_decay"]     (float): L2 penalty
            args["use_n_episodes"]   (int): number of episodes use for work
            args["test_dir"]         (str): if you run a parameter test, all results will be stored in test folder

        num_epochs (int) : Number of epochs
                            Default: 30
    Return (dict) : {float, float, float, bool}
                    best train loss, best validation loss, final test loss, early stops
    """
    # setting parametres for training

    train_folder = args['train_folder']        # 50
    batchsize = args['batchsize']            # 32
    opt = args['opt']
    learning_rate = args['learning_rate']    # 0.0001
    seed = args['seed']                      # 42
    cuda = args['cuda']                      # True
    hyperparams['load_weight'] = False
    hyperparams['load_weight_date'] = "none"
    load_weight_file = args['load_weight_file']
    model_type = args['model_type']          # "CNN_LSTM_encoder_decoder_images_PR"
    encoder_latent_vector = args['encoder_latent_vector']
    decoder_latent_vector = args['decoder_latent_vector']
    evaluate_print = 1
    future_window_size = args['future_window_size']              # 5
    past_window_size = args['past_window_size']                # 5,
    frame_interval = args['frame_interval']  # 12
    weight_decay = args["weight_decay"]      # 1e-3
    use_n_episodes = args["use_n_episodes"]    # 320
    test_dir = args["test_dir"]
    change_fps = args["change_fps"]
    print(args)

    im_in_one_second = int(24/frame_interval)
    predict_n_pr = im_in_one_second * future_window_size
    use_n_im = im_in_one_second*past_window_size
    use_LSTM = False
    use_stack = False
    use_n_channels = 3
    seq_per_ep = SEQ_PER_EPISODE_C
    use_2_encoders = False
    # parametr for different models
    if 'LSTM' in model_type:
        use_LSTM = True
    else:
        seq_per_ep = int(360/use_n_im)

    if 'stack' in model_type:
        use_stack = True
        use_n_channels = 3*use_n_im


    # indicate randomseed , so that we will be able to reproduce the result in the future
    np.random.seed(seed)
    random.seed(seed)
    torch.manual_seed(seed)
    # if you are using GPU
    print('Use cuda ->  ', cuda)
    if cuda:
        th.cuda.manual_seed(seed)
        th.cuda.manual_seed_all(seed)
    th.backends.cudnn.enabled = False
    th.backends.cudnn.benchmark = False
    th.backends.cudnn.deterministic = True
    #---------------------------------------------------------------------------


    today = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    # Create folders for results
    base_dir = "./Pre/results"+test_dir+"/test_"+ model_type +"_using_" +str(past_window_size)+  "_s_to_predict_"+str(future_window_size)+ "_s_lr_" + str(learning_rate) + "_" + today
    ress_dir = base_dir+ "/result"
    lable_dir = base_dir+ "/labels"
    weight_dir = base_dir + "/weight"
    img_dir = base_dir + "/img"

    os.mkdir(base_dir)
    os.mkdir(ress_dir)
    os.mkdir(lable_dir)
    os.mkdir(weight_dir)
    os.mkdir(img_dir)


    # parametres for different models

    tmp_str = '/' + model_type + "_predict_" + str(future_window_size) + "_s_using_" + str(past_window_size) + "_s_lr_" + str(learning_rate)

    # split our dataset for three parts
    _ , _, test_labels = loadLabels(train_folder, 0, use_n_episodes, seq_per_ep, p_train=0.7, p_val=0.15, p_test=0.15)

    # Keywords for pytorch dataloader, augment num_workers could work faster
    kwargs = {'num_workers': 4, 'pin_memory': False} if cuda else {}
    # Create data loaders


    test_loader = th.utils.data.DataLoader(
                                            JsonDataset(test_labels,
                                                        preprocess=True,
                                                        folder_prefix=train_folder,
                                                        predict_n_im = predict_n_pr,
                                                        use_n_im = use_n_im,
                                                        seq_per_ep = seq_per_ep,
                                                        use_LSTM = use_LSTM,
                                                        use_stack = use_stack,
                                                        change_fps = change_fps),
                                            batch_size=batchsize,
                                            shuffle=True,
                                            **kwargs
                                        )


    n_test = len(test_loader)*batchsize

    print("Model  --->  ", model_type)
    # model of Nazar
    if model_type == "CNN_stack_PR_FC":
        model = CNN_stack_PR_FC(cuda = cuda, num_channel=use_n_channels, cnn_fc_size = 1024 + use_n_im*2, num_output=predict_n_pr*2 )
    elif model_type == "CNN_PR_FC":
        model = CNN_PR_FC(cuda = cuda, cnn_fc_size = use_n_im*1026, num_output=predict_n_pr*2)
    elif model_type == "CNN_stack_FC_first":
        model = CNN_stack_FC_first(cuda = cuda, num_channel = use_n_channels,  cnn_fc_size = 1024, num_output=predict_n_pr*2)
    elif model_type == "CNN_stack_FC":
        model = CNN_stack_FC(cuda = cuda, num_channel = use_n_channels,  cnn_fc_size = 1024, num_output=predict_n_pr*2)
    elif model_type == "CNN_LSTM_encoder_decoder_images_PR":
        model = CNN_LSTM_encoder_decoder_images_PR(cuda = cuda, encoder_input_size = use_n_im*1026, encoder_hidden_size = encoder_latent_vector, decoder_input_size = encoder_latent_vector, decoder_hidden_size = decoder_latent_vector,  output_size = 2*predict_n_pr)
        #use pretrained model
        use_pretrainted(model, AutoEncoder())



    elif model_type == "LSTM_encoder_decoder_PR":
        model = LSTM_encoder_decoder_PR(cuda=cuda, encoder_input_size=use_n_im * 2,
                                        encoder_hidden_size=encoder_latent_vector,
                                        decoder_hidden_size=decoder_latent_vector, output_size=2 * predict_n_pr)
    elif model_type == "CNN_LSTM_encoder_decoder_images":
        model = CNN_LSTM_encoder_decoder_images(cuda = cuda, encoder_input_size = use_n_im*1024, encoder_hidden_size = encoder_latent_vector, decoder_hidden_size = encoder_latent_vector,  output_size = 2*predict_n_pr)
        #use pretrained model
        use_pretrainted(model, AutoEncoder())
    elif model_type == 'CNN_LSTM_decoder_images_PR':
        model = CNN_LSTM_decoder_images_PR(cuda = cuda, decoder_input_size = use_n_im*1026, decoder_hidden_size = 1000, output_size = 2*predict_n_pr)
        #use pretrained model
        CNN_part_tmp = AutoEncoder()
        use_pretrainted(model, AutoEncoder())
    elif model_type == "CNN_LSTM_image_encoder_PR_encoder_decoder":
        model = CNN_LSTM_image_encoder_PR_encoder_decoder(cuda = cuda, im_encoder_input_size = use_n_im*1024, pr_encoder_input_size = use_n_im*2 , im_encoder_hidden_size = 600, pr_encoder_hidden_size = 300, decoder_hidden_size = 900,  output_size = predict_n_pr*2)
        #use pretrained model
        use_pretrainted(model, AutoEncoder())
        use_2_encoders = True


    #model of Dajing
    elif model_type == "CNN_LSTM_encoder_GRU_decoder_images_PR":
        model = CNN_LSTM_encoder_GRU_decoder_images_PR(cuda = cuda, encoder_input_size = use_n_im*1026, encoder_hidden_size = encoder_latent_vector, decoder_input_size = encoder_latent_vector, decoder_hidden_size = decoder_latent_vector,  output_size = 2*predict_n_pr)
        #use pretrained model
        use_pretrainted(model, AutoEncoder())

    elif model_type == "LSTM_encoder_GRU_decoder_PR":
        model = LSTM_encoder_GRU_decoder_PR(cuda=cuda, encoder_input_size=use_n_im * 2,
                                        encoder_hidden_size=encoder_latent_vector,
                                        decoder_hidden_size=decoder_latent_vector, output_size=2 * predict_n_pr)

    elif model_type == "LSTM_encoder_GRU_decoder_PR_many":
        model = LSTM_encoder_GRU_decoder_PR_many(cuda=cuda, encoder_input_size= 2,
                                        encoder_hidden_size=encoder_latent_vector,
                                        decoder_hidden_size=decoder_latent_vector, output_size=2 )

    elif model_type == "CNN_LSTM_encoder_attention_decoder_images_PR_many":
        model = CNN_LSTM_encoder_attention_decoder_images_PR_many(cuda = cuda, encoder_input_size = use_n_im*1026, encoder_hidden_size = encoder_latent_vector, decoder_input_size = encoder_latent_vector + decoder_latent_vector, decoder_hidden_size = encoder_latent_vector ,  output_size = 2)
        #use pretrained model
        use_pretrainted(model, AutoEncoder())

    elif model_type == "CNN_LSTM_encoder_decoder_images_PR_many":
        model = CNN_LSTM_encoder_decoder_images_PR_many(cuda = cuda, encoder_input_size = 1026, encoder_hidden_size = encoder_latent_vector, decoder_input_size = encoder_latent_vector , decoder_hidden_size = encoder_latent_vector ,  output_size = 2)
        #use pretrained model
        use_pretrainted(model, AutoEncoder())

    elif model_type == "CNN_LSTM_encoder_GRU_attention_decoder_images_PR_many":
        model = CNN_LSTM_encoder_GRU_attention_decoder_images_PR_many(cuda = cuda, encoder_input_size = use_n_im*1026, encoder_hidden_size = encoder_latent_vector, decoder_input_size = encoder_latent_vector + decoder_latent_vector, decoder_hidden_size = encoder_latent_vector ,  output_size = 2)
        #use pretrained model
        use_pretrainted(model, AutoEncoder())

    elif model_type == "CNN_GRU_encoder_decoder_images_PR":
        model = CNN_GRU_encoder_decoder_images_PR(cuda = cuda, encoder_input_size = use_n_im*1026, encoder_hidden_size = encoder_latent_vector, decoder_input_size = encoder_latent_vector , decoder_hidden_size = decoder_latent_vector ,  output_size = 2*predict_n_pr)
        #use pretrained model
        use_pretrainted(model, AutoEncoder())

    elif model_type == "CNN_GRU_encoder_attention_decoder_images_PR":
        model = CNN_GRU_encoder_attention_decoder_images_PR(cuda = cuda, encoder_input_size = use_n_im*1026, encoder_hidden_size = encoder_latent_vector, decoder_input_size = encoder_latent_vector + decoder_latent_vector, decoder_hidden_size = decoder_latent_vector,  output_size = 2*predict_n_pr)
        #use pretrained model
        use_pretrainted(model, AutoEncoder())

    elif model_type == "CNN_LSTM_encoder_attention_decoder_images_PR":
        model = CNN_LSTM_encoder_attention_decoder_images_PR(cuda = cuda, encoder_input_size = use_n_im*1026, encoder_hidden_size = encoder_latent_vector, decoder_input_size = encoder_latent_vector + decoder_latent_vector, decoder_hidden_size = decoder_latent_vector,  output_size = 2*predict_n_pr)
        #use pretrained model
        use_pretrainted(model, AutoEncoder())

    elif model_type == "CNN_LSTM_encoder_GRU_attention_decoder_images_PR":
        model = CNN_LSTM_encoder_GRU_attention_decoder_images_PR(cuda = cuda, encoder_input_size = use_n_im*1026, encoder_hidden_size = encoder_latent_vector, decoder_input_size = encoder_latent_vector + decoder_latent_vector, decoder_hidden_size = decoder_latent_vector,  output_size = 2*predict_n_pr)
        #use pretrained model
        use_pretrainted(model, AutoEncoder())

    elif model_type == "LSTM_encoder_decoder_PR_many":
        model = LSTM_encoder_decoder_PR_many(cuda = cuda, encoder_input_size = 2, encoder_hidden_size = encoder_latent_vector, decoder_hidden_size = decoder_latent_vector, output_size = 2)

    elif model_type == "LSTM_encoder_attention_decoder_PR":
        model = LSTM_encoder_attention_decoder_PR(cuda = cuda, encoder_input_size = use_n_im*2, encoder_hidden_size = encoder_latent_vector, decoder_hidden_size = decoder_latent_vector,  output_size = 2*predict_n_pr, batch_size = batchsize)

    elif model_type == "LSTM_encoder_GRU_attention_decoder_PR":
        model = LSTM_encoder_GRU_attention_decoder_PR(cuda = cuda, encoder_input_size = use_n_im*2, encoder_hidden_size = encoder_latent_vector, decoder_hidden_size = decoder_latent_vector,  output_size = 2*predict_n_pr, batch_size = batchsize)

    elif model_type == "LSTM_encoder_attention_decoder_PR_many":
        model = LSTM_encoder_attention_decoder_PR_many(cuda = cuda, encoder_input_size = 2, encoder_hidden_size = encoder_latent_vector, decoder_hidden_size = decoder_latent_vector, output_size = 2)

    elif model_type == "GRU_encoder_decoder_PR":
        model = GRU_encoder_decoder_PR(cuda=cuda, encoder_input_size=use_n_im * 2,
                                        encoder_hidden_size=encoder_latent_vector,
                                        decoder_hidden_size=decoder_latent_vector, output_size=2 * predict_n_pr)
    elif model_type == "GRU_encoder_attention_decoder_PR":
        model = GRU_encoder_attention_decoder_PR(cuda = cuda, encoder_input_size = use_n_im*2, encoder_hidden_size = encoder_latent_vector, decoder_hidden_size = decoder_latent_vector,  output_size = 2*predict_n_pr, batch_size = batchsize)

    elif model_type == "GRU_encoder_decoder_PR_many":
        model = GRU_encoder_decoder_PR_many(cuda = cuda, encoder_input_size = 2, encoder_hidden_size = encoder_latent_vector, decoder_hidden_size = decoder_latent_vector, output_size = 2)

    elif model_type == "GRU_encoder_attention_decoder_PR_many":
        model = GRU_encoder_attention_decoder_PR_many(cuda = cuda, encoder_input_size = 2, encoder_hidden_size = encoder_latent_vector, decoder_hidden_size = decoder_latent_vector, output_size = 2)

    elif model_type == "TransformerModel_PR":
        model = TransformerModel_PR(cuda=cuda, encoder_input_size=use_n_im * 2, encoder_hidden_size=encoder_latent_vector, decoder_hidden_size=decoder_latent_vector, output_size=2 * predict_n_pr)

    else:
        raise ValueError("Model type not supported")

    # Load model's weights

    model.load_state_dict(torch.load(load_weight_file))

    # Move model to the GPU if possible
    if cuda:
        model.cuda()

    # Optimizers
    if opt == "adam":
        optimizer = th.optim.Adam(model.parameters(),
                                    lr=learning_rate,
                                    weight_decay=weight_decay
                                )
    elif opt == "sgd":
        optimizer = th.optim.SGD(model.parameters(),
                                    lr=learning_rate,
                                    momentum=0.9,
                                    weight_decay=weight_decay,
                                    nesterov=True
                                )

    # Loss functions
    loss_fn = nn.MSELoss(reduction = 'sum')
    start_time = time.time()
    print("Start testing...")
    test_loss = 0.0

    with th.no_grad():

        # Preparation files for saving origin and predicted pitch and roll for visualization
        origins = [{} for i in range(predict_n_pr)]
        origin_names = [lable_dir+ '/origin' + model_type +'_use_' + str(past_window_size) + '_s_to_predict_'+str(i+1)+':'+str(future_window_size)+'_lr_'+str(learning_rate)+'.json' for i in range(predict_n_pr)]
        preds = [{} for i in range(predict_n_pr)]
        pred_names = [lable_dir+'/pred' + model_type +'_use_' + str(past_window_size) + '_s_to_predict_'+str(i+1)+':'+str(future_window_size)+'_lr_'+str(learning_rate)+'.json' for i in range(predict_n_pr)]

        for key, data  in enumerate(test_loader):
            # use right testing process for different models
            if use_LSTM:
                # unpacked data
                inputs, p_and_roll = data[0], data[1]
                # move data to GPU
                if cuda:
                    inputs, p_and_roll = inputs.cuda(), p_and_roll.cuda()
                # Convert to pytorch variables
                inputs, p_and_roll = Variable(inputs), Variable(p_and_roll)
                # test through the sequence
                loss, origins, preds  = test(cuda, change_fps, key, origins, preds , batchsize, inputs, p_and_roll, model, loss_fn, predict_n_pr, use_n_im, use_2_encoders)
                test_loss += loss

            else:
                # unpacked data
                inputs, p_and_roll, targets = data[0], data[1], data[2]
                # move data to GPU
                if cuda:
                    inputs, p_and_roll, targets = inputs.cuda(), p_and_roll.cuda(), targets.cuda()
                # Convert to pytorch variables
                inputs, p_and_roll, targets = Variable(inputs), Variable(p_and_roll),Variable(targets)

                predictions = model(inputs, p_and_roll, use_n_im)

                # save results of prediction for visualization
                key_tmp = np.linspace(key*batchsize , (key+1)*batchsize, batchsize, dtype =int )
                for pred_im in range(predict_n_pr):
                    tmp1 = gen_dict_for_json(key_tmp, targets[:,pred_im,:].cpu())
                    tmp2 = gen_dict_for_json(key_tmp, predictions[:,pred_im,:].cpu())

                    origins[pred_im] = {**origins[pred_im], **tmp1}
                    preds[pred_im] = {**preds[pred_im], **tmp2}

                loss = loss_fn(predictions, targets)/ predict_n_pr
                test_loss += loss.item()

        for i in range(predict_n_pr):
            json.dump(preds[i], open(pred_names[i],'w'))
            json.dump(origins[i], open(origin_names[i],'w'))

    final_test_loss = test_loss /n_test

    print("Final results:")
    print("Test loss[normalized (-1 : 1) ]:\t\t\t{:.6f}".format(final_test_loss))

    # write result into result.txt
    final_time = (time.time() - start_time)/60
    print("Total test time: {:.2f} mins".format(final_time))

    # set lenght of sequence used
    tmp_seq_len = use_n_im
    if use_LSTM:
        tmp_seq_len = LEN_SEQ

    # write configuration in file
    write_result(args, [model], [optimizer], result_file_name = ress_dir + "/result.txt",
                best_train_loss = -1, best_val_loss = -1,
                final_test_loss = final_test_loss, time = final_time, seq_per_ep = seq_per_ep,
                seq_len = tmp_seq_len, num_epochs = num_epochs
                )
    return {"best_train_loss": -1, "best_val_loss": -1, "final_test_loss": final_test_loss}
示例#2
0
def main(args, num_epochs ):


    train_folder = args["train_folder"]
    num_epochs = num_epochs
    batchsize=args["batchsize"]
    learning_rate= args["learning_rate"]
    seed=args["seed"]
    cuda=args["cuda"]
    model_type= "VAE"
    evaluate_print=1
    load_model= ""
    time_gap= args["time_gap"]
    num_images = args["num_images"]
    weight_decay = args["weight_decay"]
    stat_data_file = args["stat_data_file"]
    test_dir = args["test_dir"]
    print(args)

    # indicqte randomseed , so that we will be able to reproduce the result in the future
    np.random.seed(seed)
    random.seed(seed)
    torch.manual_seed(seed)
    # if you are suing GPU
    if cuda:
        th.cuda.manual_seed(seed)
        th.cuda.manual_seed_all(seed)
    th.backends.cudnn.enabled = False
    th.backends.cudnn.benchmark = False
    th.backends.cudnn.deterministic = True
    #---------------------------------------------------------------------------
    print('has cuda?', cuda)

    today = datetime.now()
    base_dir = "./Pre/results"+test_dir+"/train_VAE_"+str(num_images)+ "image_to_"+str(num_images)+"_image_"+str(today)
    ress_dir = base_dir+ "/result"
    lable_dir = base_dir+ "/labels"
    weight_dir = base_dir + "/weight"
    img_dir = base_dir + "/img"

    os.mkdir(base_dir)
    os.mkdir(ress_dir)
    os.mkdir(lable_dir)
    os.mkdir(weight_dir)
    os.mkdir(img_dir)


    # Will be changed to separe plus efective

    train_labels, val_labels, test_labels = loadLabels(train_folder, 0, 540, 400 ,p_train=0.7, p_val=0.15, p_test=0.15)

    # Retrieve number of samples per set
    n_train, n_val, n_test = len(train_labels), len(val_labels), len(test_labels)


    stat_data = json.load(open(stat_data_file))
    # print('mean -> ', stat_data['mean'])
    # print('std -> ', stat_data['std'])


    # Keywords for pytorch dataloader, augment num_workers could work faster
    kwargs = {'num_workers': 4, 'pin_memory': False} if cuda else {}
    # Create data loaders
    train_loader = th.utils.data.DataLoader(JsonDataset(train_labels,
                                                        preprocess=True,
                                                        folder_prefix=train_folder,
                                                        predict_n_im = 0,
                                                        use_n_im = 1,
                                                        seq_per_ep = 400,
                                                        use_LSTM = False,
                                                        use_stack = True),
                                            batch_size=batchsize,
                                            shuffle=True,
                                            **kwargs)

    # Random transform also for val ?
    val_loader = th.utils.data.DataLoader(
                                            JsonDataset(train_labels,
                                                        preprocess=True,
                                                        folder_prefix=train_folder,
                                                        predict_n_im = 0,
                                                        use_n_im = 1,
                                                        seq_per_ep = 400,
                                                        use_LSTM = False,
                                                        use_stack = True),
                                            batch_size=batchsize,
                                            shuffle=True,
                                            **kwargs
                                        )

    test_loader = th.utils.data.DataLoader(
                                            JsonDataset(train_labels,
                                                        preprocess=True,
                                                        folder_prefix=train_folder,
                                                        predict_n_im = 0,
                                                        use_n_im = 1,
                                                        seq_per_ep = 400,
                                                        use_LSTM = False,
                                                        use_stack = True),
                                            batch_size=batchsize,
                                            shuffle=True,
                                            **kwargs)

    numChannel = 3
    print("numChannel _______", numChannel)
    model = AutoEncoder(num_channel=numChannel)
    if cuda:
        model.cuda()

    optimizer = th.optim.Adam(model.parameters(), lr=learning_rate, weight_decay=weight_decay)
    # Loss functions
    loss_fn = nn.MSELoss(reduction = 'sum')

    best_error = np.inf
    best_train_error = np.inf
    # error list for updata loss figure
    train_err_list = []
    val_err_list = []
    # epoch list
    xdata = []
    model_name = "autoencoder_model_{}s_{}im_tmp".format(model_type, time_gap, num_images)
    best_model_path = "/{}.pth".format(model_name)
    best_model_path = ress_dir + best_model_path
    tmp_str = '/' + model_type + "_predict_" + str(time_gap) + "_s_using_" + str(num_images) + "_s_lr_" + str(learning_rate)
    # setup figure parameters
    fig = plt.figure()
    ax = fig.add_subplot(111)
    li, = ax.plot(xdata, train_err_list, 'b-', label='train loss')
    l2, = ax.plot(xdata, val_err_list, 'r-', label='val loss')
    plt.legend(loc='upper right')
    fig.canvas.draw()
    plt.title("train epochs - loss")
    plt.xlabel("epochs")
    plt.ylabel("loss")
    plt.show(block=False)
    # Finally, launch the training loop.
    start_time = time.time()

    print("Starting training...")
    # We iterate over epochs:
    test1 = th.zeros(numChannel, XX, YY, dtype = th.float32 )
    test2 =  th.zeros(2, dtype = th.float32 )

    for epoch in tqdm(range(num_epochs)):
        # Switch to training mode
        model.train()
        train_loss, val_loss = 0.0, 0.0
        # Full pass on training data
        # Update the model after each minibatch
        for i, (inputs, targets, _) in enumerate(train_loader):
            # if we have incomplete mini_time_series we will skip it
            if( th.all(th.eq(inputs[0], test1))  and  th.all(th.eq(targets[0], test2))):
                print("----GAP---")
                continue
                      batch=i, n_batch=len(train_loader), method='multistep')
            # Move variables to GPU
            if cuda:
                inputs, targets = inputs.cuda(), targets.cuda()
            # Convert to pytorch variables
            inputs, targets = Variable(inputs), Variable(targets)
            features, recon_images = model(inputs, cuda)
            loss = loss_fn(recon_images, inputs)
            optimizer.zero_grad()
            loss.backward()
            train_loss += loss.item()
            optimizer.step()


        # Do a full pass on validation data
        with th.no_grad():
            model.eval()
            for inputs, targets, _ in val_loader:
                # if we have incomplete mini_time_series we will skip it
                if( th.all(th.eq(inputs[0], test1))  and  th.all(th.eq(targets[0], test2))):
                    print("----GAP---")
                    continue
                if cuda:
                    inputs, targets = inputs.cuda(), targets.cuda()
                features, recon_images = model(inputs, cuda)
                loss = loss_fn(recon_images, inputs)
                val_loss += loss.item()

            # Compute error per sample
            val_error = val_loss / n_val
            if val_error < best_error:
                best_error = val_error
                # Move back weights to cpu
                if cuda:
                    model.cpu()
                # Save Weights
                th.save(model.state_dict(), best_model_path)
                if cuda:
                    model.cuda()
            if (train_loss / n_train) < best_train_error:
                best_train_error = train_loss / n_train

        if (epoch + 1) % evaluate_print == 0:
            # update figure value and drawing
            train_l = train_loss / n_train
            xdata.append(epoch+1)
            train_err_list.append(train_l)
            val_err_list.append(val_error)
            li.set_xdata(xdata)
            li.set_ydata(train_err_list)
            l2.set_xdata(xdata)
            l2.set_ydata(val_err_list)
            ax.relim()
            ax.autoscale_view(True,True,True)
            fig.canvas.draw()
            time.sleep(0.01)
            fig.show()
            # Then we print the results for this epoch:
            # Losses are averaged over the samples
            # print("Epoch {} of {} took {:.3f}s".format(
            #     epoch + 1, num_epochs, time.time() - start_time))
            json.dump(train_err_list, open(ress_dir+tmp_str+"_train_loss.json",'w'))
            json.dump(val_err_list, open(ress_dir+tmp_str+"_val_loss.json",'w'))
            print("  training loss:\t\t{:.6f}".format(train_loss / n_train))
            print("  validation loss:\t\t{:.6f}".format(val_error))
示例#3
0
文件: train.py 项目: zroykhi/Pre
def main(train_folder,
         val_folder=None,
         num_epochs=100,
         batchsize=16,
         learning_rate=0.0001,
         seed=42,
         cuda=True,
         num_output=2,
         random_trans=0.5,
         model_type="cnn",
         evaluate_print=1,
         load_model="",
         time_gap=25):

    if ONE_IMG_ONLY or model_type == 'CNN_LSTM':
        from Pre.utils import JsonDatasetOne as JsonDataset
    else:
        from Pre.utils import JsonDatasetTwo as JsonDataset

    if val_folder == None:
        val_folder = train_folder
    if not train_folder.endswith('/'):
        train_folder += '/'
    if not val_folder.endswith('/'):
        val_folder += '/'

    print('has cuda?', cuda)
    # check whether val folder and train folder are the same
    if val_folder == train_folder:
        train_labels, val_labels, test_labels, _ = loadLabels(
            train_folder, model_type)
    else:
        train_labels, _ = loadTrainLabels(train_folder, model_type)
        val_labels, test_labels, _ = loadTestLabels(val_folder, model_type)

    # Seed the random generator
    np.random.seed(seed)
    th.manual_seed(seed)
    if cuda:
        th.cuda.manual_seed(seed)

    # Retrieve number of samples per set
    n_train, n_val, n_test = len(train_labels), len(val_labels), len(
        test_labels)

    # Keywords for pytorch dataloader, augment num_workers could work faster
    kwargs = {'num_workers': 4, 'pin_memory': False} if cuda else {}
    # Create data loaders
    train_loader = th.utils.data.DataLoader(JsonDataset(
        train_labels,
        preprocess=True,
        folder=train_folder,
        random_trans=random_trans,
        sequence=DATASET_SEQUENCE),
                                            batch_size=batchsize,
                                            shuffle=True,
                                            **kwargs)

    # Random transform also for val ?
    val_loader = th.utils.data.DataLoader(JsonDataset(
        val_labels,
        preprocess=True,
        folder=val_folder,
        random_trans=0,
        sequence=DATASET_SEQUENCE),
                                          batch_size=VAL_BATCH_SIZE,
                                          shuffle=False,
                                          **kwargs)

    test_loader = th.utils.data.DataLoader(JsonDataset(
        test_labels,
        preprocess=True,
        folder=val_folder,
        random_trans=0,
        sequence=DATASET_SEQUENCE),
                                           batch_size=VAL_BATCH_SIZE,
                                           shuffle=False,
                                           **kwargs)

    numChannel = train_loader.dataset.numChannel
    if model_type == "cnn":
        model = ConvolutionalNetwork(num_channel=numChannel,
                                     num_output=num_output)
    elif model_type == "CNN_LSTM":
        model = CNN_LSTM(num_channel=numChannel)
    else:
        raise ValueError("Model type not supported")

    if cuda:
        model.cuda()
    # L2 penalty
    weight_decay = 1e-3
    # Optimizers
    # optimizer = th.optim.Adam(model.parameters(), lr=learning_rate, weight_decay=weight_decay)
    optimizer = th.optim.SGD(model.parameters(),
                             lr=learning_rate,
                             momentum=0.9,
                             weight_decay=weight_decay,
                             nesterov=True)

    # Loss functions
    loss_fn = nn.MSELoss(size_average=False)
    # loss_fn = nn.SmoothL1Loss(size_average=False)
    best_error = np.inf
    best_train_error = np.inf
    # error list for updata loss figure
    train_err_list = []
    val_err_list = []
    # epoch list
    xdata = []
    model_name = "{}_model_{}_tmp".format(model_type, time_gap)
    best_model_path = "{}.pth".format(model_name)
    best_model_path = RES_DIR + best_model_path
    # setup figure parameters
    fig = plt.figure()
    ax = fig.add_subplot(111)
    li, = ax.plot(xdata, train_err_list, 'b-', label='train loss')
    l2, = ax.plot(xdata, val_err_list, 'r-', label='val loss')
    plt.legend(loc='upper right')
    fig.canvas.draw()
    plt.title("train epochs - loss")
    plt.xlabel("epochs")
    plt.ylabel("loss")
    plt.show(block=False)
    # Finally, launch the training loop.
    start_time = time.time()
    print("Starting training...")
    # We iterate over epochs:
    for epoch in tqdm(range(num_epochs)):
        # Switch to training mode
        model.train()
        train_loss, val_loss = 0.0, 0.0
        # Full pass on training data
        # Update the model after each minibatch
        for i, (inputs, targets) in enumerate(train_loader):
            # Adjust learning rate
            # adjustLearningRate(optimizer, epoch, num_epochs, lr_init=learning_rate,
            #                         batch=i, n_batch=len(train_loader), method='multistep')
            # Move variables to gpu
            if cuda:
                inputs, targets = inputs.cuda(), targets.cuda()
            # Convert to pytorch variables
            inputs, targets = Variable(inputs), Variable(targets)
            optimizer.zero_grad()
            predictions = model(inputs)
            # loss_tmp = lam*reg_loss(predictions)
            loss = loss_fn(predictions,
                           targets)  # + loss_tmp#Variable(loss_tmp)
            loss.backward()
            train_loss += loss.item()
            optimizer.step()

        # Do a full pass on validation data
        model.eval()
        for inputs, targets in val_loader:
            if cuda:
                inputs, targets = inputs.cuda(), targets.cuda()
            # Set volatile to True because we don't need to compute gradient
            predictions = model(inputs)
            # loss_tmp = lam*reg_loss(predictions)
            loss = loss_fn(predictions, targets)  # + loss_tmp
            val_loss += loss.item()

        # Compute error per sample
        val_error = val_loss / n_val
        if val_error < best_error:
            best_error = val_error
            # Move back weights to cpu
            if cuda:
                model.cpu()
            # Save Weights
            th.save(model.state_dict(), best_model_path)
            if cuda:
                model.cuda()
        if (train_loss / n_train) < best_train_error:
            best_train_error = train_loss / n_train

        if (epoch + 1) % evaluate_print == 0:
            # update figure value and drawing
            train_l = train_loss / n_train
            xdata.append(epoch + 1)
            train_err_list.append(train_l)
            val_err_list.append(val_error)
            li.set_xdata(xdata)
            li.set_ydata(train_err_list)
            l2.set_xdata(xdata)
            l2.set_ydata(val_err_list)
            ax.relim()
            ax.autoscale_view(True, True, True)
            fig.canvas.draw()
            time.sleep(0.01)
            fig.show()
            # Then we print the results for this epoch:
            # Losses are averaged over the samples
            # print("Epoch {} of {} took {:.3f}s".format(
            #     epoch + 1, num_epochs, time.time() - start_time))
            print("  training loss:\t\t{:.6f}".format(train_loss / n_train))
            print("  validation loss:\t\t{:.6f}".format(val_error))
    plt.savefig(RES_DIR + args.model_type + '_' + str(args.time_gap) +
                '_loss' + '.png')
    # After training, we compute and print the test error:
    model.load_state_dict(th.load(best_model_path))
    test_loss = 0.0
    for inputs, targets in test_loader:
        if cuda:
            inputs, targets = inputs.cuda(), targets.cuda()
        inputs, targets = Variable(inputs), Variable(targets)
        predictions = model(inputs)
        # loss_tmp = lam*reg_loss(predictions)
        loss = loss_fn(predictions, targets)  # + loss_tmp
        test_loss += loss.item()
    print("Final results:")
    # print("  best validation loss:\t\t{:.6f}".format(best_error))
    print("  best validation loss:\t\t{:.6f}".format(min(val_err_list)))
    print("  test loss:\t\t\t{:.6f}".format(test_loss / n_test))
    # write result into result.txt
    # format fixed because we use this file later in pltModelTimegap.py
    with open("./Pre/result.txt", "a") as f:
        f.write("current model: ")
        f.write(model_type)
        f.write("\nbest train error:")
        f.write(str(best_train_error))
        f.write("\nbest validation loss:")
        f.write(str(best_error))
        f.write("\nfinal test loss:")
        f.write(str(test_loss / n_test))
        f.write("\n")
        f.write("time gap is:")
        f.write(str(time_gap))
        f.write("\n")
        f.write(str(model))
        f.write("\n\n")
    f.close()
    print("Total train time: {:.2f} mins".format(
        (time.time() - start_time) / 60))
def main(args, num_epochs=30):
    """
    Args:
        args (dict):    Dictionary of parametres
            args['train_folder']    (str): folder's prefix where dataset is stored
            args['batchsize']       (int): batchsize
            args['opt']             (str): optimizer type
            args['learning_rate']   (float): learning_rate
            args['seed']            (int): number to fix random processes
            args['cuda']            (boolean): True if we can use GPU
            args['load_weight']     (boolean): True if we will load model
            args['load_weight_date'](str): date of the test (part of the path)
            args['model_type']      (str): model type
            args['encoder_latent_vector'] (int): size of encoder latent vector
            args['decoder_latent_vector'] (int): size of decoder latent vector
            args['future_window_size']         (int): number of seconds to predict
            args['past_window_size']          (int): number of seconds using like input
            args['frame_interval']   (int): interval at witch the data was generated
            args["weight_decay"]     (float): L2 penalty
            args["use_n_episodes"]   (int): number of episodes use for work
            args["test_dir"]         (str): if you run a parameter test, all results will be stored in test folder

        num_epochs (int) : Number of epochs
                            Default: 30
    Return (dict) : {float, float, float, bool}
                    best train loss, best validation loss, final test loss, early stops
    """
    # setting parametres for training

    train_folder = args['train_folder']  # 50
    batchsize = args['batchsize']  # 32
    opt = args['opt']
    learning_rate = args['learning_rate']  # 0.0001
    seed = args['seed']  # 42
    cuda = args['cuda']  # True
    load_weight = args['load_weight']  # False,
    load_weight_date = args['load_weight_date']
    model_type = args['model_type']  # "CNN_LSTM_encoder_decoder_images_PR"
    encoder_latent_vector = args['encoder_latent_vector']
    decoder_latent_vector = args['decoder_latent_vector']
    evaluate_print = 1
    future_window_size = args['future_window_size']  # 5
    past_window_size = args['past_window_size']  # 5,
    frame_interval = args['frame_interval']  # 12
    weight_decay = args["weight_decay"]  # 1e-3
    use_n_episodes = args["use_n_episodes"]  # 540
    test_dir = args["test_dir"]
    change_fps = args["change_fps"]
    print(args)

    im_in_one_second = int(24 / frame_interval)

    predict_n_pr = im_in_one_second * future_window_size
    use_n_im = im_in_one_second * past_window_size

    use_LSTM = False
    use_stack = False
    use_n_channels = 3
    seq_per_ep = SEQ_PER_EPISODE_C
    use_2_encoders = False
    # parametr for different models
    if 'LSTM' in model_type:
        use_LSTM = True
    else:
        seq_per_ep = int(360 / use_n_im)

    if 'stack' in model_type:
        use_stack = True
        use_n_channels = 3 * use_n_im

    # Set early stopping technique
    early_stopping = EarlyStopping(patience=8, verbose=False)

    # indicate randomseed , so that we will be able to reproduce the result in the future
    np.random.seed(seed)
    random.seed(seed)
    torch.manual_seed(seed)
    # if you are using GPU
    print('Use cuda ->  ', cuda)
    if cuda:
        th.cuda.manual_seed(seed)
        th.cuda.manual_seed_all(seed)
    th.backends.cudnn.enabled = False
    th.backends.cudnn.benchmark = False
    th.backends.cudnn.deterministic = True
    #---------------------------------------------------------------------------

    # Load model if True
    if load_weight:
        today = load_weight_date
    else:
        today = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    # Create folders for results
    base_dir = "./Pre/results" + test_dir + "/train_" + model_type + "_using_" + str(
        past_window_size) + "_s_to_predict_" + str(
            future_window_size) + "_s_lr_" + str(learning_rate) + "_" + today
    ress_dir = base_dir + "/result"
    lable_dir = base_dir + "/labels"
    weight_dir = base_dir + "/weight"
    img_dir = base_dir + "/img"

    if not load_weight:
        os.mkdir(base_dir)
        os.mkdir(ress_dir)
        os.mkdir(lable_dir)
        os.mkdir(weight_dir)
        os.mkdir(img_dir)

    # parametres for different models

    tmp_str = '/' + model_type + "_predict_" + str(
        future_window_size) + "_s_using_" + str(
            past_window_size) + "_s_lr_" + str(learning_rate)
    best_model_weight_path = weight_dir + tmp_str + "_tmp.pth"

    # split our dataset for three parts
    train_labels, val_labels, test_labels = loadLabels(train_folder,
                                                       0,
                                                       use_n_episodes,
                                                       seq_per_ep,
                                                       p_train=0.7,
                                                       p_val=0.15,
                                                       p_test=0.15)

    print('len(train_labels) -> ', len(train_labels))
    print('len(val_labels) -> ', len(val_labels))
    print('len(test_labels) -> ', len(test_labels))
    # Keywords for pytorch dataloader, augment num_workers could work faster
    kwargs = {'num_workers': 4, 'pin_memory': False} if cuda else {}
    # Create data loaders

    train_loader = th.utils.data.DataLoader(JsonDataset(
        train_labels,
        preprocess=True,
        folder_prefix=train_folder,
        predict_n_im=predict_n_pr,
        use_n_im=use_n_im,
        seq_per_ep=seq_per_ep,
        use_LSTM=use_LSTM,
        use_stack=use_stack,
        change_fps=change_fps),
                                            batch_size=batchsize,
                                            shuffle=True,
                                            **kwargs)

    val_loader = th.utils.data.DataLoader(JsonDataset(
        val_labels,
        preprocess=True,
        folder_prefix=train_folder,
        predict_n_im=predict_n_pr,
        use_n_im=use_n_im,
        seq_per_ep=seq_per_ep,
        use_LSTM=use_LSTM,
        use_stack=use_stack,
        change_fps=change_fps),
                                          batch_size=batchsize,
                                          shuffle=True,
                                          **kwargs)

    test_loader = th.utils.data.DataLoader(JsonDataset(
        test_labels,
        preprocess=True,
        folder_prefix=train_folder,
        predict_n_im=predict_n_pr,
        use_n_im=use_n_im,
        seq_per_ep=seq_per_ep,
        use_LSTM=use_LSTM,
        use_stack=use_stack,
        change_fps=change_fps),
                                           batch_size=batchsize,
                                           shuffle=True,
                                           **kwargs)

    n_train, n_val, n_test = len(train_loader) * batchsize, len(
        val_loader) * batchsize, len(test_loader) * batchsize

    if change_fps:
        predict_n_pr = future_window_size
        use_n_im = past_window_size

    print("Model  --->  ", model_type)
    if model_type == "CNN_stack_PR_FC":
        model = CNN_stack_PR_FC(cuda=cuda,
                                num_channel=use_n_channels,
                                cnn_fc_size=1024 + use_n_im * 2,
                                num_output=predict_n_pr * 2)
    elif model_type == "CNN_PR_FC":
        model = CNN_PR_FC(cuda=cuda,
                          cnn_fc_size=use_n_im * 1026,
                          num_output=predict_n_pr * 2)
    elif model_type == "CNN_stack_FC_first":
        model = CNN_stack_FC_first(cuda=cuda,
                                   num_channel=use_n_channels,
                                   cnn_fc_size=1024,
                                   num_output=predict_n_pr * 2)
    elif model_type == "CNN_stack_FC":
        model = CNN_stack_FC(cuda=cuda,
                             num_channel=use_n_channels,
                             cnn_fc_size=1024,
                             num_output=predict_n_pr * 2)
    elif model_type == "CNN_LSTM_encoder_decoder_images_PR":
        model = CNN_LSTM_encoder_decoder_images_PR(
            cuda=cuda,
            encoder_input_size=use_n_im * 1026,
            encoder_hidden_size=encoder_latent_vector,
            decoder_input_size=encoder_latent_vector,
            decoder_hidden_size=decoder_latent_vector,
            output_size=2 * predict_n_pr)
        #use pretrained model
        use_pretrainted(model, AutoEncoder())
    elif model_type == "LSTM_encoder_decoder_PR":
        model = LSTM_encoder_decoder_PR(cuda=cuda,
                                        encoder_input_size=use_n_im * 2,
                                        encoder_hidden_size=300,
                                        decoder_hidden_size=300,
                                        output_size=2 * predict_n_pr)
    elif model_type == "CNN_LSTM_encoder_decoder_images":
        model = CNN_LSTM_encoder_decoder_images(
            cuda=cuda,
            encoder_input_size=use_n_im * 1024,
            encoder_hidden_size=encoder_latent_vector,
            decoder_hidden_size=encoder_latent_vector,
            output_size=2 * predict_n_pr)
        #use pretrained model
        use_pretrainted(model, AutoEncoder())
    elif model_type == 'CNN_LSTM_decoder_images_PR':
        model = CNN_LSTM_decoder_images_PR(cuda=cuda,
                                           decoder_input_size=use_n_im * 1026,
                                           decoder_hidden_size=1000,
                                           output_size=2 * predict_n_pr)
        #use pretrained model
        CNN_part_tmp = AutoEncoder()
        use_pretrainted(model, AutoEncoder())
    elif model_type == "CNN_LSTM_image_encoder_PR_encoder_decoder":
        model = CNN_LSTM_image_encoder_PR_encoder_decoder(
            cuda=cuda,
            im_encoder_input_size=use_n_im * 1024,
            pr_encoder_input_size=use_n_im * 2,
            im_encoder_hidden_size=600,
            pr_encoder_hidden_size=300,
            decoder_hidden_size=900,
            output_size=predict_n_pr * 2)
        #use pretrained model
        use_pretrainted(model, AutoEncoder())
        use_2_encoders = True
    else:
        raise ValueError("Model type not supported")

    # Load model's weights
    if load_weight:
        model.load_state_dict(
            torch.load(weight_dir + "/" + model_type + "_predict_" +
                       str(future_window_size) + "_s_using_" +
                       str(past_window_size) + "_s_lr_" + str(learning_rate) +
                       "_tmp.pth"))

    # Move model to the GPU if possible
    if cuda:
        model.cuda()

    # Optimizers
    if opt == "adam":
        optimizer = th.optim.Adam(model.parameters(),
                                  lr=learning_rate,
                                  weight_decay=weight_decay)
    elif opt == "sgd":
        optimizer = th.optim.SGD(model.parameters(),
                                 lr=learning_rate,
                                 momentum=0.9,
                                 weight_decay=weight_decay,
                                 nesterov=True)

    # Loss functions
    loss_fn = nn.MSELoss(reduction='sum')

    best_val_error = np.inf
    best_train_loss = np.inf

    # error list for updata loss figure
    train_err_list = []
    val_err_list = []
    # epoch list
    xdata = []

    plt.figure(1)
    fig = plt.figure(figsize=(22, 15))
    ax = fig.add_subplot(111)
    li, = ax.plot(xdata, train_err_list, 'b-', label='train loss')
    l2, = ax.plot(xdata, val_err_list, 'r-', label='validation loss')
    plt.legend(loc='upper right', fontsize=18)
    fig.canvas.draw()
    plt.title("Evolution of loss function")
    plt.xlabel("Epochs", fontsize=18)
    plt.ylabel("Loss function", fontsize=18)
    plt.show(block=False)

    # Finally, launch the training loop.
    start_time = time.time()
    print("Start training...")

    # We iterate over epochs:
    for epoch in tqdm(range(num_epochs)):
        # Do a full pass on training data
        # Switch to training mode
        model.train()
        train_loss, val_loss = 0.0, 0.0

        for k, data in enumerate(train_loader):
            # use right training process for different models
            if use_LSTM:
                # unpacked data
                inputs, p_and_roll = data[0], data[1]
                # move data to GPU
                if cuda:
                    inputs, p_and_roll = inputs.cuda(), p_and_roll.cuda()
                # Convert to pytorch variables
                inputs, p_and_roll = Variable(inputs), Variable(p_and_roll)
                # training through the sequence
                loss = train(cuda, change_fps, inputs, p_and_roll, model,
                             optimizer, loss_fn, predict_n_pr, use_n_im,
                             use_2_encoders)
                train_loss += loss

            else:
                # unpacked data
                inputs, p_and_roll, targets = data[0], data[1], data[2]
                # move data to GPU
                if cuda:
                    inputs, p_and_roll, targets = inputs.cuda(
                    ), p_and_roll.cuda(), targets.cuda()
                # Convert to pytorch variables
                inputs, p_and_roll, targets = Variable(inputs), Variable(
                    p_and_roll), Variable(targets)

                # training process
                optimizer.zero_grad()
                predictions = model(inputs, p_and_roll, use_n_im)
                loss = loss_fn(predictions, targets) / predict_n_pr

                loss.backward()
                train_loss += loss.item()
                optimizer.step()

        # train MSE for pitch and roll
        train_error = train_loss / n_train

        # if the train_error is so big stop training and save time (usefull for Hyperband)
        if np.isnan(train_error):
            return {
                "best_train_loss": np.inf,
                "best_val_loss": np.inf,
                "final_test_loss": np.inf
            }

        # Do a full pass on validation data
        with th.no_grad():
            # Switch to evaluation mode
            model.eval()
            for data in val_loader:
                # use right validation process for different models
                if use_LSTM:
                    # unpacked data
                    inputs, p_and_roll = data[0], data[1]
                    # move data to GPU
                    if cuda:
                        inputs, p_and_roll = inputs.cuda(), p_and_roll.cuda()
                    # Convert to pytorch variables
                    inputs, p_and_roll = Variable(inputs), Variable(p_and_roll)
                    # validation through the sequence
                    loss = eval(cuda, change_fps, inputs, p_and_roll, model,
                                loss_fn, predict_n_pr, use_n_im,
                                use_2_encoders)
                    val_loss += loss

                else:
                    # unpacked data
                    inputs, p_and_roll, targets = data[0], data[1], data[2]
                    # move data to GPU
                    if cuda:
                        inputs, p_and_roll, targets = inputs.cuda(
                        ), p_and_roll.cuda(), targets.cuda()
                    # Convert to pytorch variables
                    inputs, p_and_roll, targets = Variable(inputs), Variable(
                        p_and_roll), Variable(targets)

                    # validation process
                    predictions = model(inputs, p_and_roll, use_n_im)
                    loss = loss_fn(predictions, targets) / predict_n_pr
                    val_loss += loss.item()

            # validation MSE for pitch and roll
            val_error = val_loss / n_val

            early_stopping(val_error, model, best_model_weight_path, cuda)

            if train_error < best_train_loss:
                best_train_loss = train_error

        if (epoch + 1) % evaluate_print == 0:
            # update figure value and drawing

            xdata.append(epoch + 1)
            train_err_list.append(train_error)
            val_err_list.append(val_error)
            li.set_xdata(xdata)
            li.set_ydata(train_err_list)
            l2.set_xdata(xdata)
            l2.set_ydata(val_err_list)
            ax.relim()
            ax.autoscale_view(True, True, True)
            fig.canvas.draw()

            # Save evolution of train and validation loss functions
            json.dump(train_err_list,
                      open(ress_dir + tmp_str + "_train_loss.json", 'w'))
            json.dump(val_err_list,
                      open(ress_dir + tmp_str + "_val_loss.json", 'w'))
            print(
                "  training avg loss [normalized -1, 1]   :\t\t{:.6f}".format(
                    train_error))
            print(
                "  validation avg loss [normalized -1, 1] :\t\t{:.6f}".format(
                    val_error))

        if early_stopping.early_stop:
            print("----Early stopping----")
            break

    # Save figure
    plt.savefig(img_dir + tmp_str + '_log_losses.png')
    plt.close()

    # Load the best weight configuration
    model.load_state_dict(th.load(best_model_weight_path))

    print("Start testing...")
    test_loss = 0.0

    with th.no_grad():

        # Preparation files for saving origin and predicted pitch and roll for visualization
        origins = [{} for i in range(predict_n_pr)]
        origin_names = [
            lable_dir + '/origin' + model_type + '_use_' +
            str(past_window_size) + '_s_to_predict_' + str(i + 1) + ':' +
            str(predict_n_pr) + '_lr_' + str(learning_rate) + '.json'
            for i in range(predict_n_pr)
        ]
        preds = [{} for i in range(predict_n_pr)]
        pred_names = [
            lable_dir + '/pred' + model_type + '_use_' +
            str(past_window_size) + '_s_to_predict_' + str(i + 1) + ':' +
            str(predict_n_pr) + '_lr_' + str(learning_rate) + '.json'
            for i in range(predict_n_pr)
        ]

        for key, data in enumerate(test_loader):
            # use right testing process for different models
            if use_LSTM:
                # unpacked data
                inputs, p_and_roll = data[0], data[1]
                # move data to GPU
                if cuda:
                    inputs, p_and_roll = inputs.cuda(), p_and_roll.cuda()
                # Convert to pytorch variables
                inputs, p_and_roll = Variable(inputs), Variable(p_and_roll)
                # test through the sequence
                loss, origins, preds = test(cuda, change_fps, key, origins,
                                            preds, batchsize, inputs,
                                            p_and_roll, model, loss_fn,
                                            predict_n_pr, use_n_im,
                                            use_2_encoders)
                test_loss += loss

            else:
                # unpacked data
                inputs, p_and_roll, targets = data[0], data[1], data[2]
                # move data to GPU
                if cuda:
                    inputs, p_and_roll, targets = inputs.cuda(
                    ), p_and_roll.cuda(), targets.cuda()
                # Convert to pytorch variables
                inputs, p_and_roll, targets = Variable(inputs), Variable(
                    p_and_roll), Variable(targets)

                predictions = model(inputs, p_and_roll, use_n_im)

                # save results of prediction for visualization
                key_tmp = np.linspace(key * batchsize, (key + 1) * batchsize,
                                      batchsize,
                                      dtype=int)
                for pred_im in range(predict_n_pr):
                    tmp1 = gen_dict_for_json(key_tmp,
                                             targets[:, pred_im, :].cpu())
                    tmp2 = gen_dict_for_json(key_tmp,
                                             predictions[:, pred_im, :].cpu())

                    origins[pred_im] = {**origins[pred_im], **tmp1}
                    preds[pred_im] = {**preds[pred_im], **tmp2}

                loss = loss_fn(predictions, targets) / predict_n_pr
                test_loss += loss.item()

        for i in range(predict_n_pr):
            json.dump(preds[i], open(pred_names[i], 'w'))
            json.dump(origins[i], open(origin_names[i], 'w'))

    final_test_loss = test_loss / n_test

    print("Final results:")
    print("  best avg training loss [normalized (-1 : 1) ]:\t\t{:.6f}".format(
        best_train_loss))
    print(
        "  best avg validation loss [normalized (-1 : 1) ]:\t\t{:.6f}".format(
            min(val_err_list)))
    print("  test avg loss[normalized (-1 : 1) ]:\t\t\t{:.6f}".format(
        final_test_loss))

    # write result into result.txt
    final_time = (time.time() - start_time) / 60
    print("Total train time: {:.2f} mins".format(final_time))

    # set lenght of sequence used
    tmp_seq_len = use_n_im
    if use_LSTM:
        tmp_seq_len = LEN_SEQ

    # write configuration in file
    write_result(args, [model], [optimizer],
                 result_file_name=ress_dir + "/result.txt",
                 best_train_loss=best_train_loss,
                 best_val_loss=early_stopping.val_loss_min,
                 final_test_loss=final_test_loss,
                 time=final_time,
                 seq_per_ep=seq_per_ep,
                 seq_len=tmp_seq_len,
                 num_epochs=num_epochs)
    return {
        "best_train_loss": best_train_loss,
        "best_val_loss": early_stopping.val_loss_min,
        "final_test_loss": final_test_loss,
        "early_stop": early_stopping.early_stop
    }