def train(data, model, optimizer, epoch, args):
    model.train()

    avg_loss = 0.0
    n_batches = 0
    progress_bar = tqdm(data)
    for batch_idx, sample_batched in enumerate(progress_bar):
        img, qst, label = utils.load_tensor_data(sample_batched, args.cuda, args.invert_questions)

        # forward and backward pass
        optimizer.zero_grad()
        output = model(img, qst)
        loss = F.nll_loss(output, label)
        loss.backward()

        # Gradient Clipping
        if args.clip_norm:
            clip_grad_norm(model.parameters(), args.clip_norm)

        optimizer.step()

        # Show progress
        progress_bar.set_postfix(dict(loss=loss.data[0]))
        avg_loss += loss.data[0]
        n_batches += 1

        if batch_idx % args.log_interval == 0:
            avg_loss /= n_batches
            processed = batch_idx * args.batch_size
            n_samples = len(data) * args.batch_size
            progress = float(processed) / n_samples
            print('Train Epoch: {} [{}/{} ({:.0%})] Train loss: {}'.format(
                epoch, processed, n_samples, progress, avg_loss))
            avg_loss = 0.0
            n_batches = 0
Beispiel #2
0
def test(data, model, epoch, dictionaries, args):
    model.eval()

    # accuracy for every class
    class_corrects = {}
    # for every class, among all the wrong answers, how much are non pertinent
    class_invalids = {}
    # total number of samples for every class
    class_n_samples = {}
    # initialization
    for c in dictionaries[2].values():
        class_corrects[c] = 0
        class_invalids[c] = 0
        class_n_samples[c] = 0

    corrects = 0.0
    invalids = 0.0
    n_samples = 0

    inverted_answ_dict = {v: k for k, v in dictionaries[1].items()}
    sorted_classes = sorted(
        dictionaries[2].items(),
        key=lambda x: hash(x[1])
        if x[1] != 'number' else int(inverted_answ_dict[x[0]]))
    sorted_classes = [c[0] - 1 for c in sorted_classes]

    confusion_matrix_target = []
    confusion_matrix_pred = []

    sorted_labels = sorted(dictionaries[1].items(), key=lambda x: x[1])
    sorted_labels = [c[0] for c in sorted_labels]
    sorted_labels = [sorted_labels[c] for c in sorted_classes]

    avg_loss = 0.0
    progress_bar = tqdm(data)
    for batch_idx, sample_batched in enumerate(progress_bar):
        img, qst, label = utils.load_tensor_data(sample_batched,
                                                 args.cuda,
                                                 args.invert_questions,
                                                 volatile=True)

        output = model(img, qst)
        pred = output.data.max(1)[1]

        loss = F.nll_loss(output, label)

        # compute per-class accuracy
        pred_class = [dictionaries[2][o + 1] for o in pred]
        real_class = [dictionaries[2][o + 1] for o in label.data]
        for idx, rc in enumerate(real_class):
            class_corrects[rc] += (pred[idx] == label.data[idx])
            class_n_samples[rc] += 1

        for pc, rc in zip(pred_class, real_class):
            class_invalids[rc] += (pc != rc)

        for p, l in zip(pred, label.data):
            confusion_matrix_target.append(sorted_classes.index(l))
            confusion_matrix_pred.append(sorted_classes.index(p))

        # compute global accuracy
        corrects += (pred == label.data).sum()
        assert corrects == sum(class_corrects.values()
                               ), 'Number of correct answers assertion error!'
        invalids = sum(class_invalids.values())
        n_samples += len(label)
        assert n_samples == sum(class_n_samples.values()
                                ), 'Number of total answers assertion error!'

        avg_loss += loss.data[0]

        if batch_idx % args.log_interval == 0:
            accuracy = corrects / n_samples
            invalids_perc = invalids / n_samples
            progress_bar.set_postfix(
                dict(acc='{:.2%}'.format(accuracy),
                     inv='{:.2%}'.format(invalids_perc)))

    avg_loss /= len(data)
    invalids_perc = invalids / n_samples
    accuracy = corrects / n_samples

    print(
        'Test Epoch {}: Accuracy = {:.2%} ({:g}/{}); Invalids = {:.2%} ({:g}/{}); Test loss = {}'
        .format(epoch, accuracy, corrects, n_samples, invalids_perc, invalids,
                n_samples, avg_loss))
    for v in class_n_samples.keys():
        accuracy = 0
        invalid = 0
        if class_n_samples[v] != 0:
            accuracy = class_corrects[v] / class_n_samples[v]
            invalid = class_invalids[v] / class_n_samples[v]
        print('{} -- acc: {:.2%} ({}/{}); invalid: {:.2%} ({}/{})'.format(
            v, accuracy, class_corrects[v], class_n_samples[v], invalid,
            class_invalids[v], class_n_samples[v]))

    # dump results on file
    filename = os.path.join(args.test_results_dir, 'test.pickle')
    dump_object = {
        'class_corrects': class_corrects,
        'class_invalids': class_invalids,
        'class_total_samples': class_n_samples,
        'confusion_matrix_target': confusion_matrix_target,
        'confusion_matrix_pred': confusion_matrix_pred,
        'confusion_matrix_labels': sorted_labels,
        'global_accuracy': accuracy
    }
    pickle.dump(dump_object, open(filename, 'wb'))
Beispiel #3
0
                          output_size=output_size,
                          ode_fun=FuncODE(latent_size),
                          device=device,
                          decoder=nn.Sequential(
                              nn.Linear(latent_size, latent_size), nn.ReLU(),
                              nn.Linear(latent_size, latent_size), nn.ReLU(),
                              nn.Linear(latent_size, output_size)))

    optimizer = optim.Adam(latentODE.parameters(), lr=1.5e-3)
    metric = nn.MSELoss()

    # load data
    test_T, test_X, training_T, training_X, val_T, val_X = load_tensor_data(
        data_folder='./data',
        k=500,
        batch_size=16,
        seq_size=seq_len * 2,
        validation_size=0.2,
        test_size=0.1)

    # loss loggers
    loss_meter = RunningAverageMeter(use_log_scale=True)
    val_loss_meter = RunningAverageMeter(use_log_scale=True)

    # init printers
    vis = Visualisator(device)
    vis.visualise_alpha(latentODE,
                        test_T,
                        test_X,
                        save_to_dir=dir,
                        show_fig=False,