コード例 #1
0
ファイル: fit.py プロジェクト: yubryanj/Ad-hoc-MARL
def main():

    args = init_args()

    # Prepare the dataloader
    train_dataloaders, validation_dataloaders, test_dataloader, args = initialize_dataloader(
        args, subset=None)

    # Prepare the model
    model, criterion, optimizer = initialize_model(args)

    best_validation_loss = evaluate(model, validation_dataloaders, criterion)
    log(-1, args, validation_loss=best_validation_loss)

    training_losses = []
    validation_losses = []
    model.train()
    epoch = 0

    # Iterate through the data
    while best_validation_loss > args.threshold:

        epoch += 1.0
        training_loss = 0.0
        n_batches = 0.0

        env = np.random.choice(args.training_agents)

        for observations, actions, target in tqdm(train_dataloaders[env]):

            # Zero out the gradient for this round of updates
            optimizer.zero_grad()

            # Conduct a forward pass of the transformer
            prediction = model.forward(observations, actions)

            # Compare the output of the model to the target
            prediction = torch.Tensor(prediction.flatten())
            target = torch.Tensor(target.flatten().float())
            loss = criterion(prediction, target)

            # Update the model
            loss.backward()
            optimizer.step()

            training_loss += loss.item()
            n_batches += 1.0

        # Check against the validation dataset
        validation_loss = evaluate(model, validation_dataloaders, criterion)

        # Scale by the batch size
        training_loss = training_loss / n_batches

        # Save the losses
        training_losses.append(training_loss)
        validation_losses.append(validation_loss)
        np.save(f'{args.model_dir}/log/training_losses.npy', training_losses)
        np.save(f'{args.model_dir}/log/validation_losses.npy',
                validation_losses)

        # Update the logs
        log(epoch,
            args,
            validation_loss=validation_loss,
            training_loss=training_loss)

        # Save model
        if validation_loss < best_validation_loss:
            save_model(model, args, epoch)
            best_validation_loss = validation_loss

    # Apply to test dataset
    test_loss = evaluate(model, test_dataloader, criterion)
    log(-2, args, test_loss=test_loss)
コード例 #2
0
def meta_train():
    if datasource == 'sine_line':
        data_generator = DataGenerator(num_samples=num_samples_per_class)
        # create dummy sampler
        all_class_train = [0] * 10
    else:
        all_class_train, all_data_train = load_dataset(
            dataset_name=datasource,
            subset=train_set
        )
        all_class_val, all_data_val = load_dataset(
            dataset_name=datasource,
            subset=val_set
        )
        all_class_train.update(all_class_val)
        all_data_train.update(all_data_val)
        
    # initialize data loader
    train_loader = initialize_dataloader(
        all_classes=[class_label for class_label in all_class_train],
        num_classes_per_task=num_classes_per_task
    )

    for epoch in range(resume_epoch, resume_epoch + num_epochs):
        # variables used to store information of each epoch for monitoring purpose
        meta_loss_saved = [] # meta loss to save
        val_accuracies = []
        train_accuracies = []

        meta_loss = 0 # accumulate the loss of many ensambling networks to descent gradient for meta update
        num_meta_updates_count = 0

        meta_loss_avg_print = 0 # compute loss average to print

        meta_loss_avg_save = [] # meta loss to save

        task_count = 0 # a counter to decide when a minibatch of task is completed to perform meta update
        while (task_count < num_tasks_per_epoch):
            for class_labels in train_loader:
                if datasource == 'sine_line':
                    x_t, y_t, x_v, y_v = get_task_sine_line_data(
                        data_generator=data_generator,
                        p_sine=p_sine,
                        num_training_samples=num_training_samples_per_class,
                        noise_flag=True
                    )
                    x_t = torch.tensor(x_t, dtype=torch.float, device=device)
                    y_t = torch.tensor(y_t, dtype=torch.float, device=device)
                    x_v = torch.tensor(x_v, dtype=torch.float, device=device)
                    y_v = torch.tensor(y_v, dtype=torch.float, device=device)
                else:
                    x_t, y_t, x_v, y_v = get_train_val_task_data(
                        all_classes=all_class_train,
                        all_data=all_data_train,
                        class_labels=class_labels,
                        num_samples_per_class=num_samples_per_class,
                        num_training_samples_per_class=num_training_samples_per_class,
                        device=device
                    )

                w_task = adapt_to_task(x=x_t, y=y_t, w0=theta)
                y_pred = net.forward(x=x_v, w=w_task)
                
                loss_NLL = loss_fn(input=y_pred, target=y_v)

                if torch.isnan(loss_NLL).item():
                    sys.exit('NaN error')

                # accumulate meta loss
                meta_loss = meta_loss + loss_NLL

                task_count = task_count + 1

                if task_count % num_tasks_per_minibatch == 0:
                    meta_loss = meta_loss/num_tasks_per_minibatch

                    # accumulate into different variables for printing purpose
                    meta_loss_avg_print += meta_loss.item()

                    op_theta.zero_grad()
                    meta_loss.backward()
                    torch.nn.utils.clip_grad_norm_(parameters=theta.values(), max_norm=10)
                    op_theta.step()

                    # Printing losses
                    num_meta_updates_count += 1
                    if (num_meta_updates_count % num_meta_updates_print == 0):
                        meta_loss_avg_save.append(meta_loss_avg_print/num_meta_updates_count)
                        print('{0:d}, {1:2.4f}'.format(
                            task_count,
                            meta_loss_avg_save[-1]
                        ))

                        num_meta_updates_count = 0
                        meta_loss_avg_print = 0
                    
                    if (task_count % num_tasks_save_loss == 0):
                        meta_loss_saved.append(np.mean(meta_loss_avg_save))

                        meta_loss_avg_save = []

                        print('Saving loss...')
                        if datasource != 'sine_line':
                            val_accs = validate_classification(
                                all_classes=all_class_val,
                                all_data=all_data_val,
                                num_val_tasks=100,
                                p_rand=0.5,
                                uncertainty=False,
                                csv_flag=False
                            )
                            val_acc = np.mean(val_accs)
                            val_ci95 = 1.96*np.std(val_accs)/np.sqrt(num_val_tasks)
                            print('Validation accuracy = {0:2.4f} +/- {1:2.4f}'.format(val_acc, val_ci95))
                            val_accuracies.append(val_acc)

                            train_accs = validate_classification(
                                all_classes=all_class_train,
                                all_data=all_data_train,
                                num_val_tasks=100,
                                p_rand=0.5,
                                uncertainty=False,
                                csv_flag=False
                            )
                            train_acc = np.mean(train_accs)
                            train_ci95 = 1.96*np.std(train_accs)/np.sqrt(num_val_tasks)
                            print('Train accuracy = {0:2.4f} +/- {1:2.4f}\n'.format(train_acc, train_ci95))
                            train_accuracies.append(train_acc)
                    
                    # reset meta loss
                    meta_loss = 0

                if (task_count >= num_tasks_per_epoch):
                    break
        if ((epoch + 1)% num_epochs_save == 0):
            checkpoint = {
                'theta': theta,
                'meta_loss': meta_loss_saved,
                'val_accuracy': val_accuracies,
                'train_accuracy': train_accuracies,
                'op_theta': op_theta.state_dict()
            }
            print('SAVING WEIGHTS...')
            checkpoint_filename = 'Epoch_{0:d}.pt'.format(epoch + 1)
            print(checkpoint_filename)
            torch.save(checkpoint, os.path.join(dst_folder, checkpoint_filename))
        scheduler.step()
        print()