def trajectory_overlap(gt_trajs, pred_traj):
    """
    Calculate overlap among trajectories
    """
    max_overlap = 0
    max_index = -1
    thresh = 0.5
    for t, gt_traj in enumerate(gt_trajs):
        top1 = 0
        total = len(set(gt_traj.keys()) | set(pred_traj.keys()))
        for i, fid in enumerate(gt_traj):
            if fid not in pred_traj:
                continue
            sIoU = iou(gt_traj[fid], pred_traj[fid])
            if sIoU >= thresh:
                top1 += 1

        # tIoU = (top1 + top2 + top3) * 1.0 / (3 * total)
        tIoU = (top1) * 1.0 / (total)

        if tIoU > max_overlap:
            max_index = t
            max_overlap = tIoU

    return max_overlap, max_index
Example #2
0
def merge_by_iou(preds):
    """
    Just process the adjacent lines.
    Args:
        preds: pred_row_list

    Returns:
        preds: Merge some rows according to "w_iou < 0.2 and h_iou > 0.45"
    """
    # col_width_max = max([len(row) for row in preds])
    total_cell_count = sum([len(row) for row in preds])
    i_list = []  # The index of rows merged into other rows

    def take_x_min(elem):
        return elem[2][0]

    for i, _ in enumerate(preds):
        if i == 0 or i - 1 in i_list:
            continue
        _, w_iou, h_iou = iou(preds[i - 1][0][2], preds[i][0][2])
        if w_iou < 0.2 and h_iou > 0.45:  # and len(preds[i-1]) + len(preds[i]) <= col_width_max:
            preds[i - 1] += preds[i]
            preds[i - 1] = sorted(preds[i - 1], key=take_x_min)
            preds[i] = []
            i_list.append(i)

    for i in sorted(i_list,
                    reverse=True):  # delete the row merged into other rows
        if len(preds[i]) == 0:
            del preds[i]

    cell_count = 0  # renumber the preds
    for pred in preds:
        for p in pred:
            cell_count += 1
            p[0] = cell_count
    assert total_cell_count == cell_count

    # col_width_max = max([len(row) for row in preds])
    # print(col_width_max)
    return preds
Example #3
0
def merge_by_iou_v2(preds):
    """
    Merge rows which has only one original cell according to "w_iou < 0.2 and h_iou > 0.45"
    Args:
        preds: The original one cell per row

    Returns:
        preds: Merge some rows according to "w_iou < 0.2 and h_iou > 0.45"
    """
    print(preds)
    total_cell_count = sum([len(row) for row in preds])
    i_list = []

    def take_x_min(elem):
        return elem[2][0]

    for i, _ in enumerate(preds):
        if i in i_list:
            continue
        i_tmp = i + 1
        while i_tmp < total_cell_count:
            print(i_tmp, total_cell_count)
            _, w_iou, h_iou = iou(preds[i][0][2], preds[i_tmp][0][2])
            if w_iou < 0.2 and h_iou > 0.45:  # and len(preds[i-1]) + len(preds[i]) <= col_width_max:
                preds[i] += preds[i_tmp]
                preds[i] = sorted(preds[i], key=take_x_min)
                preds[i_tmp] = []
                i_list.append(i_tmp)
            else:
                break
            i_tmp += 1

    for i in sorted(i_list, reverse=True):
        if len(preds[i]) == 0:
            del preds[i]

    print(preds)
    col_width_max = max([len(row) for row in preds])
    print(col_width_max)
    return preds
Example #4
0
def tubelets_overlap(tubelets_proto, annot_proto, class_idx):
    for tubelet in tubelets_proto:
        class_index = tubelet['class_index']
        ious = []
        # for each tubelet_box find the best gt_overlap
        for tubelet_box in tubelet['boxes']:
            tubelet_box['gt_overlap'] = 0
            for annot_track in annot_proto['annotations']:
                for annot_box in annot_track['track']:
                    if annot_box['class_index'] != class_index:
                        # only need to check class of first annot_box, so we break
                        break
                    if tubelet_box['frame'] == annot_box['frame']:
                        cur_iou = iou([annot_box['bbox']],  [tubelet_box['bbox']])
                        # convert ndarray to a scalar
                        cur_iou = float(cur_iou.ravel())
                        if 'gt_overlap' not in tubelet_box or cur_iou > tubelet_box['gt_overlap']:
                            tubelet_box['gt_overlap'] = cur_iou
        ious = [box['gt_overlap'] for box in tubelet['boxes']]
        mean_iou = np.asarray(ious).mean()
        if abs(mean_iou - 1) < np.finfo(float).eps:
            tubelet['gt'] = 1
    return tubelets_proto
Example #5
0
def train_stage1(net,
                 optimizer,
                 train_loader,
                 val_loader,
                 fold=None,
                 weight_path='stage_1_weights',
                 epochs=30):
    mkdir(weight_path)

    log = open('log{}.txt'.format(fold), 'a+')

    stat = pd.DataFrame(columns=[
        'Training Loss', 'Training Acc', 'Training IoU', 'Valid Loss',
        'Valid Acc', 'Valid IoU'
    ])

    best_val_iou = .0

    train_loss_record, train_acc_record, train_iou_record = [], [], []
    val_loss_record, val_acc_record, val_iou_record = [], [], []

    # criterion = torch.nn.BCELoss()
    criterion = FocalLoss2d()
    start = time.time()

    print(f'\nFold-{fold} Warm-up Training Overview')
    print('|          Train           |             Val          |')
    print('|-----------------------------------------------------|')
    print('|  Loss   |   Acc  |  IoU  |  Loss   |   Acc  |  IoU  |')
    log.write(f'\nFold-{fold} Warm-up Training Overview\n')
    log.write('|          Train           |             Val          |\n')
    log.write('|-----------------------------------------------------|\n')
    log.write('|  Loss   |   Acc  |  IoU  |  Loss   |   Acc  |  IoU  |\n')
    for epoch in range(epochs):
        epoch_loss = 0
        epoch_acc = 0
        epoch_iou = 0

        for batch_idx, batch in enumerate(train_loader):
            data, target = batch['image'].to(device), batch['mask'].to(device)
            output = net(data)
            # add sigmoid to the logits
            loss = criterion(nn.Sigmoid()(output), target)
            acc = accuracy(output, target)
            iou_ = iou(output, target.int())
            loss.backward()
            optimizer.step()
            optimizer.zero_grad()

            epoch_loss += loss.item() / len(train_loader)
            epoch_acc += acc.item() / len(train_loader)
            epoch_iou += iou_.item() / len(train_loader)

        print(f'|{epoch_loss:9.4f}|{epoch_acc:8.4f}|{epoch_iou:7.4f}', end='')
        log.write(f'|{epoch_loss:9.4f}|{epoch_acc:8.4f}|{epoch_iou:7.4f}')
        train_loss_record.append(epoch_loss)
        train_acc_record.append(epoch_acc)
        train_iou_record.append(epoch_iou)

        with torch.no_grad():
            epoch_val_loss = 0
            epoch_val_acc = 0
            epoch_val_iou = 0
            for batch_idx, batch in enumerate(val_loader):
                data, target = batch['image'].to(device), batch['mask'].to(
                    device)

                output = net(data)
                loss = criterion(nn.Sigmoid()(output), target)
                acc = accuracy(output, target)
                iou_ = iou(output, target.int())

                epoch_val_loss += loss.item() / len(val_loader)
                epoch_val_acc += acc.item() / len(val_loader)
                epoch_val_iou += iou_.item() / len(val_loader)

            print(
                f'|{epoch_val_loss:9.4f}|{epoch_val_acc:8.4f}|{epoch_val_iou:7.4f}|'
            )
            log.write(
                f'|{epoch_val_loss:9.4f}|{epoch_val_acc:8.4f}|{epoch_val_iou:7.4f}|\n'
            )
            val_loss_record.append(epoch_val_loss)
            val_acc_record.append(epoch_val_acc)
            val_iou_record.append(epoch_val_iou)

            if epoch_val_iou > best_val_iou:
                best_val_iou = epoch_val_iou
                torch.save(net.state_dict(),
                           f'{weight_path}/Stage-1_Fold-{fold}')

    stat['Epoch'] = [_ for _ in range(1, epochs + 1)]
    stat['Stage'] = 1
    stat['Fold'] = fold
    stat['Training Loss'] = train_loss_record
    stat['Training Acc'] = train_acc_record
    stat['Training IoU'] = train_iou_record
    stat['Valid Loss'] = val_loss_record
    stat['Valid Acc'] = val_acc_record
    stat['Valid IoU'] = val_iou_record
    print('Time used', time.time() - start)
    return net, stat
Example #6
0
def finetune_stage(net,
                   train_loader,
                   val_loader,
                   fold=None,
                   weight_path='finetune_weights',
                   n_cycle=6,
                   initial_lr=0.01,
                   epochs_per_cycle=50):
    mkdir(f'{weight_path}_fold{fold}')

    log = open('finetune-log{}.txt'.format(fold), 'a+')
    net.load_state_dict(torch.load(f'stage_2_weights/NoDepth_Fold-{fold}'))
    print(f'\nModel weights from stage_2_weights/NoDepth_Fold-{fold} Loaded')
    log.write(
        f'\nModel weights from stage_2_weights/NoDepth_Fold-{fold} Loaded\n')

    lr_record = []
    train_loss_record, train_acc_record, train_iou_record = [], [], []
    val_loss_record, val_acc_record, val_iou_record = [], [], []

    optimizer = optim.SGD(net.parameters(),
                          lr=initial_lr,
                          momentum=0.9,
                          weight_decay=0.0001)

    for cycle in range(n_cycle):
        start = time.time()
        print(f'\nFold # {fold} Snapshot # {cycle} Overview')
        print('|          Train           |             Val          |')
        print('|-----------------------------------------------------|')
        print('|  Loss   |   Acc  |  IoU  |  Loss   |   Acc  |  IoU  |')
        log.write(f'\nFold # {fold} Snapshot # {cycle} Overview\n')
        log.write('|          Train           |             Val          |\n')
        log.write('|-----------------------------------------------------|\n')
        log.write('|  Loss   |   Acc  |  IoU  |  Loss   |   Acc  |  IoU  |\n')

        best_val_iou = .0
        for epoch in range(epochs_per_cycle):
            epoch_loss = 0
            epoch_acc = 0
            epoch_iou = 0

            lr = cos_annealing_lr(initial_lr, epoch, epochs_per_cycle)
            if lr < 0.001:
                break
            lr_record.append(lr)
            optimizer.state_dict()['param_groups'][0]['lr'] = lr

            for batch_idx, batch in enumerate(train_loader):
                data, target = batch['image'].to(device), batch['mask'].to(
                    device)

                output = net(data)
                loss = net.criterion(output, target.long())

                acc = accuracy(output, target)
                iou_ = iou(output, target.int())
                loss.backward()
                optimizer.step()
                optimizer.zero_grad()

                epoch_loss += loss.item() / len(train_loader)
                epoch_acc += acc.item() / len(train_loader)
                epoch_iou += iou_.item() / len(train_loader)

            print(f'|{epoch_loss:9.4f}|{epoch_acc:8.4f}|{epoch_iou:7.4f}',
                  end='')
            log.write(f'|{epoch_loss:9.4f}|{epoch_acc:8.4f}|{epoch_iou:7.4f}')

            train_loss_record.append(epoch_loss)
            train_acc_record.append(epoch_acc)
            train_iou_record.append(epoch_iou)

            with torch.no_grad():
                epoch_val_loss = 0
                epoch_val_acc = 0
                epoch_val_iou = 0
                for batch_idx, batch in enumerate(val_loader):
                    data, target = batch['image'].to(device), batch['mask'].to(
                        device)

                    output = net(data)
                    loss = net.criterion(output, target.long())
                    acc = accuracy(output, target)
                    iou_ = iou(output, target.int())

                    epoch_val_loss += loss.item() / len(val_loader)
                    epoch_val_acc += acc.item() / len(val_loader)
                    epoch_val_iou += iou_.item() / len(val_loader)

                print(
                    f'|{epoch_val_loss:9.4f}|{epoch_val_acc:8.4f}|{epoch_val_iou:7.4f}|'
                )
                log.write(
                    f'|{epoch_val_loss:9.4f}|{epoch_val_acc:8.4f}|{epoch_val_iou:7.4f}|{epoch}\n'
                )
                val_loss_record.append(epoch_val_loss)
                val_acc_record.append(epoch_val_acc)
                val_iou_record.append(epoch_val_iou)

                if epoch_val_iou > best_val_iou:
                    best_val_iou = epoch_val_iou
                    torch.save(
                        net.state_dict(),
                        f'{weight_path}_fold{fold}/cycle_{cycle}_{epoch_val_iou}'
                    )
        print(f'Best Result: {best_val_iou}')
        log.write(f'Best Result: {best_val_iou}\n')
        print('Time used', time.time() - start)
Example #7
0
def finetune_stage1(net,
                    train_loader,
                    val_loader,
                    fold=None,
                    weight_path='finetune_stage_1_weights',
                    epochs=80):
    mkdir(weight_path)

    log = open('log{}.txt'.format(fold), 'a+')
    net.load_state_dict(
        torch.load('stage_1_weights/Stage_1_Fold_{}'.format(fold)))
    print('\nModel weights from stage_1_weights/Stage_1_Fold_{} Loaded'.format(
        fold))
    log.write(
        '\nModel weights from stage_1_weights/Stage_1_Fold_{} Loaded\n'.format(
            fold))

    stat = pd.DataFrame(columns=[
        'Training Loss', 'Training Acc', 'Training IoU', 'Valid Loss',
        'Valid Acc', 'Valid IoU'
    ])

    best_val_iou = .0

    train_loss_record, train_acc_record, train_iou_record = [], [], []
    val_loss_record, val_acc_record, val_iou_record = [], [], []

    start = time.time()

    optimizer = optim.SGD(net.parameters(),
                          lr=0.005,
                          momentum=0.9,
                          weight_decay=0.0001)
    scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer,
                                                     mode='max',
                                                     factor=0.5,
                                                     patience=8)

    print('\nFold-{} Finetune Training Overview'.format(fold))
    print('|          Train           |             Val          |')
    print('|-----------------------------------------------------|')
    print('|  Loss   |   Acc  |  IoU  |  Loss   |   Acc  |  IoU  |')
    log.write('\nFold-{} Finetune Training Overview\n'.format(fold))
    log.write('|          Train           |             Val          |\n')
    log.write('|-----------------------------------------------------|\n')
    log.write('|  Loss   |   Acc  |  IoU  |  Loss   |   Acc  |  IoU  |\n')
    early_stop_counter = 0
    for epoch in range(epochs):
        if early_stop_counter > 15:
            print('\nEarly stop at epoch {}!'.format(epoch))
            log.write('\nEarly stop at epoch {}!\n'.format(epoch))
            break
        epoch_loss = 0
        epoch_acc = 0
        epoch_iou = 0

        for batch_idx, batch in enumerate(train_loader):
            data, target = batch['image'].to(device), batch['mask'].to(device)
            output = net(data)
            # add sigmoid to the logits
            loss = net.criterion(output, target)
            acc = accuracy(output, target)
            iou_ = iou(output, target.int())
            loss.backward()
            optimizer.step()
            optimizer.zero_grad()

            epoch_loss += loss.item() / len(train_loader)
            epoch_acc += acc.item() / len(train_loader)
            epoch_iou += iou_.item() / len(train_loader)

        print('|{:9.4f}|{:8.4f}|{:7.4f}'.format(epoch_loss, epoch_acc,
                                                epoch_iou),
              end='')
        log.write('|{:9.4f}|{:8.4f}|{:7.4f}'.format(epoch_loss, epoch_acc,
                                                    epoch_iou))
        train_loss_record.append(epoch_loss)
        train_acc_record.append(epoch_acc)
        train_iou_record.append(epoch_iou)

        with torch.no_grad():
            epoch_val_loss = 0
            epoch_val_acc = 0
            epoch_val_iou = 0
            for batch_idx, batch in enumerate(val_loader):
                data, target = batch['image'].to(device), batch['mask'].to(
                    device)

                output = net(data)
                loss = net.criterion(output, target)
                acc = accuracy(output, target)
                iou_ = iou(output, target.int())

                epoch_val_loss += loss.item() / len(val_loader)
                epoch_val_acc += acc.item() / len(val_loader)
                epoch_val_iou += iou_.item() / len(val_loader)

            # Learning rate decay step
            scheduler.step(epoch_val_iou)
            print('|{:9.4f}|{:8.4f}|{:7.4f}|'.format(epoch_val_loss,
                                                     epoch_val_acc,
                                                     epoch_val_iou))
            log.write('|{:9.4f}|{:8.4f}|{:7.4f}|\n'.format(
                epoch_val_loss, epoch_val_acc, epoch_val_iou))
            val_loss_record.append(epoch_val_loss)
            val_acc_record.append(epoch_val_acc)
            val_iou_record.append(epoch_val_iou)

            if epoch_val_iou > best_val_iou:
                early_stop_counter = 0
                best_val_iou = epoch_val_iou
                torch.save(net.state_dict(),
                           '{}/Stage_2_Fold_{}'.format(weight_path, fold))
            else:
                early_stop_counter += 1

    # stat['Epoch'] = [_ for _ in range(1, epochs + 1)]
    # stat['Stage'] = 1
    # stat['Fold'] = fold
    # stat['Training Loss'] = train_loss_record
    # stat['Training Acc'] = train_acc_record
    # stat['Training IoU'] = train_iou_record
    # stat['Valid Loss'] = val_loss_record
    # stat['Valid Acc'] = val_acc_record
    # stat['Valid IoU'] = val_iou_record
    print('Best --> {}'.format(best_val_iou))
    log.write('Best --> {}\n'.format(best_val_iou))
    print('Time used', time.time() - start)
    return net, stat