Exemple #1
0
    def test_same_bbox_equal_to_one(self):
        # (xmin, ymin, xmax, ymax)
        bbox: torch.Tensor = torch.Tensor([0, 10, 10, 20])
        iou: float = metrics.bbox_iou(bbox, bbox)

        self.assertIsInstance(iou, float)
        self.assertAlmostEqual(iou, 1.)
Exemple #2
0
    def test_iou_zero(self):
        # (xmin, ymin, xmax, ymax)
        bbox_a: torch.Tensor = torch.Tensor([0, 10, 10, 20])
        bbox_b: torch.Tensor = torch.Tensor([10, 20, 20, 25])
        iou: float = metrics.bbox_iou(bbox_a, bbox_b)

        self.assertAlmostEqual(iou, 0.)
Exemple #3
0
def visualize(model, dataset, save_path):
    model.eval()
    torch.set_grad_enabled(False)

    avg_iou = 0
    for index in tqdm(range(len(dataset))):
        X, y = dataset[index]
        X, y = X.cuda().unsqueeze(0), y

        y_pred = model(X)

        iou = bbox_iou(y_pred, torch.from_numpy(y).unsqueeze(0).float().cuda())[0].item()
        avg_iou += iou

        x1, y1, x2, y2 = to_corner(y[0], y[1], y[2], y[3])
        y_pred = y_pred[0]
        pred_x1, pred_y1, pred_x2, pred_y2 = to_corner(y_pred[0], y_pred[1], y_pred[2], y_pred[3])

        path = dataset.image_names[index]
        origin_img = cv.imread(path)
        origin_img = padding_resize(origin_img)

        # draw ground truth
        cv.rectangle(
            origin_img,
            (int(x1 * 224), int(y1 * 224)),
            (int(x2 * 224), int(y2 * 224)),
            (0, 255, 0),
            1
        )

        # draw prediction
        cv.rectangle(
            origin_img,
            (int(pred_x1 * 224), int(pred_y1 * 224)),
            (int(pred_x2 * 224), int(pred_y2 * 224)),
            (255, 0, 0),
            1
        )

        img_name = os.path.split(path)[-1]
        new_name = '{}_{}.jpg'.format(os.path.splitext(img_name)[0], iou)
        new_path = os.path.join(save_path, new_name)
        cv.imwrite(new_path, origin_img)

    return avg_iou / len(dataset)
Exemple #4
0
def _eval(model, dataloader):
    model.eval()
    torch.set_grad_enabled(False)

    ious = 0
    total = 0
    for step, test_data in enumerate(dataloader):
        X, y = test_data
        X, y = X.cuda(), y.float().cuda()

        y_pred = model(X)
        total += y.size(0)
        ious += bbox_iou(y_pred, y).sum()
    iou = round(ious.item() / total, 4)

    model.train()
    torch.set_grad_enabled(True)
    return iou
Exemple #5
0
def _train(model, train_loader, val_loader, loss_function, optimizer, epochs, save_path,
           weighted_sampler=None, lr_scheduler=None, warmup_scheduler=None):
    model_dict = model.state_dict()
    trainable_layers = [(tensor, model_dict[tensor].size()) for tensor in model_dict]
    print_msg('Trainable layers: ', ['{}\t{}'.format(k, v) for k, v in trainable_layers])

    # train
    max_iou = 0
    record_epochs, val_ious, losses = [], [], []
    model.train()
    for epoch in range(1, epochs + 1):
        # resampling weight update
        if weighted_sampler:
            weighted_sampler.step()

        # learning rate update
        if warmup_scheduler and not warmup_scheduler.is_finish():
            if epoch > 1:
                curr_lr = optimizer.param_groups[0]['lr']
                print_msg('Learning rate warmup to {}'.format(curr_lr))
        elif lr_scheduler:
            if epoch % 10 == 0:
                curr_lr = optimizer.param_groups[0]['lr']
                print_msg('Current learning rate is {}'.format(curr_lr))

        ious = 0
        total = 0
        epoch_loss = 0
        progress = tqdm(enumerate(train_loader))
        for step, train_data in progress:
            if warmup_scheduler and not warmup_scheduler.is_finish():
                warmup_scheduler.step()
            elif lr_scheduler:
                lr_scheduler.step()

            X, y = train_data
            X, y = X.cuda(), y.float().cuda()

            # forward
            y_pred = model(X)
            loss = loss_function(y_pred, y)

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

            # metrics
            epoch_loss += loss.item()
            total += y.size(0)
            ious += bbox_iou(y_pred, y).sum()
            avg_loss = epoch_loss / (step + 1)
            avg_iou = ious / total
            progress.set_description(
                'epoch: {}, loss: {:.6f}, training IoU: {:.4f}'
                .format(epoch, avg_loss, avg_iou)
            )

        # save model
        iou = _eval(model, val_loader)
        print('validation IoU: {}'.format(iou))
        if iou > max_iou:
            torch.save(model, save_path)
            max_iou = iou
            print_msg('Model save at {}'.format(save_path))

        # record
        record_epochs.append(epoch)
        val_ious.append(iou)
        losses.append(avg_loss)

    return record_epochs, val_ious, losses