def test_cnn_do(model, criterion, test_iterator, cur_epoch, dataset, log_file,
                gpus):
    losses, losses_a, losses_b, top1_a, top5_a, top1_b, top5_b = AverageMeter(
    ), AverageMeter(), AverageMeter(), AverageMeter(), AverageMeter(
    ), AverageMeter(), AverageMeter()
    with torch.no_grad():
        model.eval()
        print_and_save(
            'Evaluating after epoch: {} on {} set'.format(cur_epoch, dataset),
            log_file)
        for batch_idx, (inputs, targets) in enumerate(test_iterator):
            inputs = torch.tensor(inputs).cuda(gpus[0])

            targets_a = torch.tensor(targets[0]).cuda(gpus[0])
            targets_b = torch.tensor(targets[1]).cuda(gpus[0])
            output_a, output_b = model(inputs)
            loss_a = criterion(output_a, targets_a)
            loss_b = criterion(output_b, targets_b)
            loss = 0.75 * loss_a + 0.25 * loss_b

            t1_a, t5_a = accuracy(output_a.detach().cpu(),
                                  targets_a.detach().cpu(),
                                  topk=(1, 5))
            t1_b, t5_b = accuracy(output_b.detach().cpu(),
                                  targets_b.detach().cpu(),
                                  topk=(1, 5))
            top1_a.update(t1_a.item(), output_a.size(0))
            top5_a.update(t5_a.item(), output_a.size(0))
            top1_b.update(t1_b.item(), output_b.size(0))
            top5_b.update(t5_b.item(), output_b.size(0))
            losses_a.update(loss_a.item(), output_a.size(0))
            losses_b.update(loss_b.item(), output_b.size(0))
            losses.update(loss.item(), output_a.size(0))

            to_print = '[Epoch:{}, Batch {}/{}]' \
                       '[Top1_a {:.3f}[avg:{:.3f}], Top5_a {:.3f}[avg:{:.3f}],' \
                       'Top1_b {:.3f}[avg:{:.3f}], Top5_b {:.3f}[avg:{:.3f}]]'.format(
                       cur_epoch, batch_idx, len(test_iterator),
                       top1_a.val, top1_a.avg, top5_a.val, top5_a.avg,
                       top1_b.val, top1_b.avg, top5_b.val, top5_b.avg)
            print_and_save(to_print, log_file)

        print_and_save(
            '{} Results: Loss {:.3f}, Top1_a {:.3f}, Top5_a {:.3f}, Top1_b {:.3f}, Top5_b {:.3f}'
            .format(dataset, losses.avg, top1_a.avg, top5_a.avg, top1_b.avg,
                    top5_b.avg), log_file)
    return top1_a.avg, top1_b.avg
def test_cnn(model, criterion, test_iterator, cur_epoch, dataset, log_file,
             gpus):
    losses, top1, top5 = AverageMeter(), AverageMeter(), AverageMeter()
    with torch.no_grad():
        model.eval()
        print_and_save(
            'Evaluating after epoch: {} on {} set'.format(cur_epoch, dataset),
            log_file)
        for batch_idx, (inputs, targets) in enumerate(test_iterator):
            inputs = inputs.cuda(gpus[0])
            targets = targets.cuda(gpus[0])

            output = model(inputs)
            loss = criterion(output, targets)

            t1, t5 = accuracy(output.detach(), targets.detach(), topk=(1, 5))
            top1.update(t1.item(), output.size(0))
            top5.update(t5.item(), output.size(0))
            losses.update(loss.item(), output.size(0))

            print_and_save(
                '[Epoch:{}, Batch {}/{}][Top1 {:.3f}[avg:{:.3f}], Top5 {:.3f}[avg:{:.3f}]]'
                .format(cur_epoch, batch_idx, len(test_iterator), top1.val,
                        top1.avg, top5.val, top5.avg), log_file)

        print_and_save(
            '{} Results: Loss {:.3f}, Top1 {:.3f}, Top5 {:.3f}'.format(
                dataset, losses.avg, top1.avg, top5.avg), log_file)
    return top1.avg
Example #3
0
def validate_lstm(model, criterion, test_iterator, cur_epoch, dataset,
                  log_file, args):
    losses, top1, top5 = AverageMeter(), AverageMeter(), AverageMeter()
    outputs = []

    print_and_save(
        'Evaluating after epoch: {} on {} set'.format(cur_epoch, dataset),
        log_file)
    with torch.no_grad():
        model.eval()
        for batch_idx, (inputs, seq_lengths, targets,
                        video_names) in enumerate(test_iterator):
            inputs = torch.tensor(inputs).cuda()
            targets = torch.tensor(targets).cuda()

            inputs = inputs.transpose(1, 0)
            output = model(inputs, seq_lengths)
            loss = criterion(output, targets)

            batch_preds = []
            for j in range(output.size(0)):
                res = np.argmax(output[j].detach().cpu().numpy())
                label = targets[j].cpu().numpy()
                outputs.append([res, label])
                batch_preds.append("{}, P-L:{}-{}".format(
                    video_names[j], res, label))

            t1, t5 = accuracy(output.detach().cpu(),
                              targets.detach().cpu(),
                              topk=(1, 5))
            top1.update(t1.item(), output.size(0))
            top5.update(t5.item(), output.size(0))
            losses.update(loss.item(), output.size(0))

            print_and_save(
                '[Batch {}/{}][Top1 {:.3f}[avg:{:.3f}], Top5 {:.3f}[avg:{:.3f}]]\n\t{}'
                .format(batch_idx, len(test_iterator), top1.val, top1.avg,
                        top5.val, top5.avg, batch_preds), log_file)
        print_and_save(
            '{} Results: Loss {:.3f}, Top1 {:.3f}, Top5 {:.3f}'.format(
                dataset, losses.avg, top1.avg, top5.avg), log_file)
    return top1.avg, outputs
Example #4
0
def validate_lstm_do(model, criterion, test_iterator, cur_epoch, dataset,
                     log_file, args):
    losses, losses_a, losses_b, top1_a, top5_a, top1_b, top5_b = AverageMeter(
    ), AverageMeter(), AverageMeter(), AverageMeter(), AverageMeter(
    ), AverageMeter(), AverageMeter()
    outputs_a, outputs_b = [], []

    print_and_save(
        'Evaluating after epoch: {} on {} set'.format(cur_epoch, dataset),
        log_file)
    with torch.no_grad():
        model.eval()
        for batch_idx, (inputs, seq_lengths, targets,
                        video_names) in enumerate(test_iterator):
            inputs = torch.tensor(inputs).cuda()
            inputs = inputs.transpose(1, 0)

            output_a, output_b = model(inputs, seq_lengths)

            targets_a = torch.tensor(targets[:, 0]).cuda()
            targets_b = torch.tensor(targets[:, 1]).cuda()
            loss_a = criterion(output_a, targets_a)
            loss_b = criterion(output_b, targets_b)
            loss = 0.75 * loss_a + 0.25 * loss_b

            batch_preds = []
            for j in range(output_a.size(0)):
                res_a = np.argmax(output_a[j].detach().cpu().numpy())
                res_b = np.argmax(output_b[j].detach().cpu().numpy())
                label_a = targets_a[j].cpu().numpy()
                label_b = targets_b[j].cpu().numpy()
                outputs_a.append([res_a, label_a])
                outputs_b.append([res_b, label_b])
                batch_preds.append("{}, a P-L:{}-{}, b P-L:{}-{}".format(
                    video_names[j], res_a, label_a, res_b, label_b))

            t1_a, t5_a = accuracy(output_a.detach().cpu(),
                                  targets_a.detach().cpu(),
                                  topk=(1, 5))
            t1_b, t5_b = accuracy(output_b.detach().cpu(),
                                  targets_b.detach().cpu(),
                                  topk=(1, 5))
            top1_a.update(t1_a.item(), output_a.size(0))
            top5_a.update(t5_a.item(), output_a.size(0))
            top1_b.update(t1_b.item(), output_b.size(0))
            top5_b.update(t5_b.item(), output_b.size(0))
            losses_a.update(loss_a.item(), output_a.size(0))
            losses_b.update(loss_b.item(), output_b.size(0))
            losses.update(loss.item(), output_a.size(0))

            to_print = '[Batch {}/{}]' \
                '[Top1_a {:.3f}[avg:{:.3f}], Top5_a {:.3f}[avg:{:.3f}],' \
                'Top1_b {:.3f}[avg:{:.3f}], Top5_b {:.3f}[avg:{:.3f}]]\n\t{}'.format(
                batch_idx, len(test_iterator),
                top1_a.val, top1_a.avg, top5_a.val, top5_a.avg,
                top1_b.val, top1_b.avg, top5_b.val, top5_b.avg,
                batch_preds)
            print_and_save(to_print, log_file)

        print_and_save(
            '{} Results: Loss {:.3f}, Top1_a {:.3f}, Top5_a {:.3f}, Top1_b {:.3f}, Top5_b {:.3f}'
            .format(dataset, losses.avg, top1_a.avg, top5_a.avg, top1_b.avg,
                    top5_b.avg), log_file)
    return (top1_a.avg, top1_b.avg), (outputs_a, outputs_b)
Example #5
0
def validate_lstm_attn(model, criterion, test_iterator, cur_epoch, dataset,
                       log_file, args):
    losses, top1, top5 = AverageMeter(), AverageMeter(), AverageMeter()
    predictions = []
    # for attention
    all_predictions = torch.zeros((0, args.lstm_seq_size, 1))
    all_attentions = torch.zeros((0, args.lstm_seq_size, args.lstm_seq_size))
    all_targets = torch.zeros((0, 1))
    all_video_names = []
    num_changing_in_seq = 0
    for_the_better, for_the_worse = [], []

    print_and_save(
        'Evaluating after epoch: {} on {} set'.format(cur_epoch, dataset),
        log_file)
    with torch.no_grad():
        model.eval()
        for batch_idx, (inputs, seq_lengths, targets,
                        video_names) in enumerate(test_iterator):
            inputs = torch.tensor(inputs).cuda()
            targets = torch.tensor(targets).cuda()

            inputs = inputs.transpose(1, 0)
            outputs, attn_weights = model(inputs, seq_lengths)

            loss = 0
            for output in outputs:
                loss += criterion(output, targets)
            loss /= len(outputs)

            outputs = torch.stack(outputs)
            outputs = torch.argmax(outputs, dim=2).detach().cpu(
            )  # edw exw thn provlepsh gia kathe step tou sequence gia olo to batch
            all_predictions = torch.cat(
                (all_predictions, torch.transpose(outputs, 0, 1).float()),
                dim=0)
            outputs = outputs.numpy()
            maj_vote = [
                np.bincount(outputs[:, kk]).argmax()
                for kk in range(len(outputs[0]))
            ]  # to argmax kanei majority voting
            for i in range(len(maj_vote)):  # iteration in the batch size
                if outputs[:, i].any() != outputs[-1, i]:
                    num_changing_in_seq += 1
                    if maj_vote[i] != outputs[
                            -1,
                            i]:  # compare the majority vote to the prediction of the last step in the sequence
                        tar = targets[i].cpu().numpy()
                        if maj_vote[i] == tar:
                            for_the_better.append(video_names[i])
                        elif outputs[-1, i] == tar:
                            for_the_worse.append(video_names[i])
            outputs = maj_vote
            attn_weights = torch.transpose(torch.stack(attn_weights), 0,
                                           1).detach().cpu()
            all_attentions = torch.cat((all_attentions, attn_weights), dim=0)
            all_targets = torch.cat(
                (all_targets, targets.detach().cpu().float()), dim=0)
            all_video_names = all_video_names + video_names

            batch_preds = []
            for j in range(len(outputs)):
                res = outputs[j]
                label = targets[j].cpu().numpy()
                predictions.append([res, label])
                batch_preds.append("{}, P-L:{}-{}".format(
                    video_names[j], res, label))

            t1, t5 = accuracy(
                output.detach().cpu(
                ),  # use output (instead of outputs) for accuracy; outputs is used for the confusion matrix
                targets.detach().cpu(),
                topk=(1, 5))
            top1.update(t1.item(), output.size(0))
            top5.update(t5.item(), output.size(0))
            losses.update(loss.item(), output.size(0))

            print_and_save(
                '[Batch {}/{}][Top1 {:.3f}[avg:{:.3f}], Top5 {:.3f}[avg:{:.3f}]]\n\t{}'
                .format(batch_idx, len(test_iterator), top1.val, top1.avg,
                        top5.val, top5.avg, batch_preds), log_file)

        print_and_save(
            "Num samples with differences {}".format(num_changing_in_seq),
            log_file)
        print_and_save(
            "{} changed for the better\n{}".format(len(for_the_better),
                                                   for_the_better), log_file)
        print_and_save(
            "{} changed for the worse\n{}".format(len(for_the_worse),
                                                  for_the_worse), log_file)

        print_and_save(
            '{} Results: Loss {:.3f}, Top1 {:.3f}, Top5 {:.3f}'.format(
                dataset, losses.avg, top1.avg, top5.avg), log_file)
        if args.save_attentions:
            all_predictions = all_predictions.numpy().astype(np.int)
            all_targets = all_targets.numpy().astype(np.int)
            output_dir = os.path.join(os.path.dirname(log_file), "figures")
            os.makedirs(output_dir, exist_ok=True)
            for i in range(len(all_targets)):
                name_parts = all_video_names[i].split("\\")[-2:]
                output_file = os.path.join(
                    output_dir,
                    "{}_{}.png".format(name_parts[0],
                                       name_parts[1].split('.')[0]))
                showAttention(args.lstm_seq_size, all_predictions[i],
                              all_targets[i], all_attentions[i], output_file)

    return top1.avg, predictions
def train_cnn_do(model,
                 optimizer,
                 criterion,
                 train_iterator,
                 mixup_alpha,
                 cur_epoch,
                 log_file,
                 gpus,
                 lr_scheduler=None):
    batch_time, losses_a, losses_b, losses, top1_a, top5_a, top1_b, top5_b = AverageMeter(
    ), AverageMeter(), AverageMeter(), AverageMeter(), AverageMeter(
    ), AverageMeter(), AverageMeter(), AverageMeter()
    model.train()

    if not isinstance(lr_scheduler, CyclicLR):
        lr_scheduler.step()

    print_and_save('*********', log_file)
    print_and_save('Beginning of epoch: {}'.format(cur_epoch), log_file)
    t0 = time.time()
    for batch_idx, (inputs, targets) in enumerate(train_iterator):
        if isinstance(lr_scheduler, CyclicLR):
            lr_scheduler.step()

        inputs = torch.tensor(inputs, requires_grad=True).cuda(gpus[0])

        targets_a = torch.tensor(targets[0]).cuda(gpus[0])
        targets_b = torch.tensor(targets[1]).cuda(gpus[0])

        output_a, output_b = model(inputs)

        loss_a = criterion(output_a, targets_a)
        loss_b = criterion(output_b, targets_b)
        loss = 0.75 * loss_a + 0.25 * loss_b

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        t1_a, t5_a = accuracy(output_a.detach().cpu(),
                              targets_a.detach().cpu(),
                              topk=(1, 5))
        t1_b, t5_b = accuracy(output_b.detach().cpu(),
                              targets_b.detach().cpu(),
                              topk=(1, 5))
        top1_a.update(t1_a.item(), output_a.size(0))
        top5_a.update(t5_a.item(), output_a.size(0))
        top1_b.update(t1_b.item(), output_b.size(0))
        top5_b.update(t5_b.item(), output_b.size(0))
        losses_a.update(loss_a.item(), output_a.size(0))
        losses_b.update(loss_b.item(), output_b.size(0))
        losses.update(loss.item(), output_a.size(0))
        batch_time.update(time.time() - t0)
        t0 = time.time()
        to_print = '[Epoch:{}, Batch {}/{} in {:.3f} s]'\
                   '[Losses {:.4f}[avg:{:.4f}], loss_a {:.4f}[avg:{:.4f}], loss_b {:.4f}[avg:{:.4f}],' \
                   'Top1_a {:.3f}[avg:{:.3f}], Top5_a {:.3f}[avg:{:.3f}],' \
                   'Top1_b {:.3f}[avg:{:.3f}], Top5_b {:.3f}[avg:{:.3f}]],' \
                   'LR {:.6f}'.format(
                           cur_epoch, batch_idx, len(train_iterator), batch_time.val,
                           losses_a.val, losses_a.avg, losses_b.val, losses_b.avg, losses.val, losses.avg,
                           top1_a.val, top1_a.avg, top5_a.val, top5_a.avg,
                           top1_b.val, top1_b.avg, top5_b.val, top5_b.avg,
                           lr_scheduler.get_lr()[0])
        print_and_save(to_print, log_file)
def train_cnn(model,
              optimizer,
              criterion,
              train_iterator,
              mixup_alpha,
              cur_epoch,
              log_file,
              gpus,
              lr_scheduler=None):
    batch_time, losses, top1, top5 = AverageMeter(), AverageMeter(
    ), AverageMeter(), AverageMeter()
    model.train()

    if not isinstance(lr_scheduler, CyclicLR):
        lr_scheduler.step()

    print_and_save('*********', log_file)
    print_and_save('Beginning of epoch: {}'.format(cur_epoch), log_file)
    t0 = time.time()
    for batch_idx, (inputs, targets) in enumerate(train_iterator):
        if isinstance(lr_scheduler, CyclicLR):
            lr_scheduler.step()

        inputs = inputs.cuda(gpus[0])
        targets = targets.cuda(gpus[0])

        # TODO: Fix mixup and cuda integration, especially for mfnet
        if mixup_alpha != 1:
            inputs, targets_a, targets_b, lam = mixup_data(
                inputs, targets, mixup_alpha)

        output = model(inputs)

        if mixup_alpha != 1:
            loss = mixup_criterion(criterion, output, targets_a, targets_b,
                                   lam)
        else:
            loss = criterion(output, targets)

        optimizer.zero_grad()
        loss.backward()

        #        if clip_gradient is not None:
        #            total_norm = torch.nn.clip_grad_norm_(model.parameters(), clip_gradient)
        #            if total_norm > clip_gradient:
        #                to_print = "clipping gradient: {} with coef {}".format(total_norm, clip_gradient / total_norm)
        #                print_and_save(to_print, log_file)

        optimizer.step()

        t1, t5 = accuracy(output.detach(), targets.detach(), topk=(1, 5))
        top1.update(t1.item(), output.size(0))
        top5.update(t5.item(), output.size(0))
        losses.update(loss.item(), output.size(0))
        batch_time.update(time.time() - t0)
        t0 = time.time()
        print_and_save(
            '[Epoch:{}, Batch {}/{} in {:.3f} s][Loss {:.4f}[avg:{:.4f}], Top1 {:.3f}[avg:{:.3f}], Top5 {:.3f}[avg:{:.3f}]], LR {:.6f}'
            .format(cur_epoch, batch_idx, len(train_iterator), batch_time.val,
                    losses.val, losses.avg, top1.val, top1.avg, top5.val,
                    top5.avg,
                    lr_scheduler.get_lr()[0]), log_file)
    print_and_save("Epoch train time: {}".format(batch_time.sum), log_file)