Example #1
0
def edge_detection(depth):
    if use_cuda:
        get_edge = sobel.Sobel().cuda()
    else:
        get_edge = sobel.Sobel()

    edge_xy = get_edge(depth)
    edge_sobel = torch.pow(edge_xy[:, 0, :, :], 2) + \
     torch.pow(edge_xy[:, 1, :, :], 2)
    edge_sobel = torch.sqrt(edge_sobel)

    return edge_sobel
def train(train_loader, model, optimizer, epoch):
    criterion = nn.L1Loss()
    batch_time = AverageMeter()
    losses = AverageMeter()

    model.train()

    cos = nn.CosineSimilarity(dim=1, eps=0)
    get_gradient = sobel.Sobel().cuda()

    end = time.time()
    for i, sample_batched in enumerate(train_loader):
        image, depth = sample_batched['image'], sample_batched['depth']

        #depth = depth.cuda(async=True)
        depth = depth.cuda()
        image = image.cuda()
        image = torch.autograd.Variable(image)
        depth = torch.autograd.Variable(depth)

        ones = torch.ones(depth.size(0), 1, depth.size(2),depth.size(3)).float().cuda()
        ones = torch.autograd.Variable(ones)
        optimizer.zero_grad()

        output = model(image)

        depth_grad = get_gradient(depth)
        output_grad = get_gradient(output)
        depth_grad_dx = depth_grad[:, 0, :, :].contiguous().view_as(depth)
        depth_grad_dy = depth_grad[:, 1, :, :].contiguous().view_as(depth)
        output_grad_dx = output_grad[:, 0, :, :].contiguous().view_as(depth)
        output_grad_dy = output_grad[:, 1, :, :].contiguous().view_as(depth)

        depth_normal = torch.cat((-depth_grad_dx, -depth_grad_dy, ones), 1)
        output_normal = torch.cat((-output_grad_dx, -output_grad_dy, ones), 1)

        # depth_normal = F.normalize(depth_normal, p=2, dim=1)
        # output_normal = F.normalize(output_normal, p=2, dim=1)

        loss_depth = torch.log(torch.abs(output - depth) + 0.5).mean()
        loss_dx = torch.log(torch.abs(output_grad_dx - depth_grad_dx) + 0.5).mean()
        loss_dy = torch.log(torch.abs(output_grad_dy - depth_grad_dy) + 0.5).mean()
        loss_normal = torch.abs(1 - cos(output_normal, depth_normal)).mean()

        loss = loss_depth + loss_normal + (loss_dx + loss_dy)

        #losses.update(loss.data[0], image.size(0))
        losses.update(loss.data.item(), image.size(0))
        loss.backward()
        optimizer.step()

        batch_time.update(time.time() - end)
        end = time.time()
   
        batchSize = depth.size(0)

        print('Epoch: [{0}][{1}/{2}]\t'
          'Time {batch_time.val:.3f} ({batch_time.sum:.3f})\t'
          'Loss {loss.val:.4f} ({loss.avg:.4f})'
          .format(epoch, i, len(train_loader), batch_time=batch_time, loss=losses))
Example #3
0
def get_loss_function():
    get_gradient = sobel.Sobel().get_gradient

    def loss_function(disp, pred):
        # disp loss
        loss_disp = K.mean(K.abs(pred - disp))

        # grad loss
        pred_grad = get_gradient(pred)
        disp_grad = get_gradient(disp)
        pred_grad_dx = K.expand_dims(pred_grad[..., 0], axis=-1)
        pred_grad_dy = K.expand_dims(pred_grad[..., 1], axis=-1)
        disp_grad_dx = K.expand_dims(disp_grad[..., 0], axis=-1)
        disp_grad_dy = K.expand_dims(disp_grad[..., 1], axis=-1)
        loss_dx = K.mean(K.abs(pred_grad_dx - disp_grad_dx))
        loss_dy = K.mean(K.abs(pred_grad_dy - disp_grad_dy))

        # normal loss
        ones = K.ones_like(disp_grad_dx)
        pred_normal = K.concatenate([-pred_grad_dx, -pred_grad_dy, ones],
                                    axis=-1)
        disp_normal = K.concatenate([-disp_grad_dx, -disp_grad_dy, ones],
                                    axis=-1)
        loss_normal = K.mean(
            K.abs(1 - cos_similarity(pred_normal, disp_normal, axis=-1)))

        return loss_disp + (loss_dx + loss_dy) + loss_normal

    return loss_function
Example #4
0
def testing_loss(depth , output, losses, batchSize):
    
    ones = torch.ones(depth.size(0), 1, depth.size(2),depth.size(3)).float().cuda()
    get_gradient = sobel.Sobel().cuda()
    cos = nn.CosineSimilarity(dim=1, eps=0)
    depth_grad = get_gradient(depth)
    output_grad = get_gradient(output)
    depth_grad_dx = depth_grad[:, 0, :, :].contiguous().view_as(depth)
    depth_grad_dy = depth_grad[:, 1, :, :].contiguous().view_as(depth)
    output_grad_dx = output_grad[:, 0, :, :].contiguous().view_as(depth)
    output_grad_dy = output_grad[:, 1, :, :].contiguous().view_as(depth)
    depth_normal = torch.cat((-depth_grad_dx, -depth_grad_dy, ones), 1)
    output_normal = torch.cat((-output_grad_dx, -output_grad_dy, ones), 1)

    loss_depth = torch.log(torch.abs(output - depth) + 0.5).mean()

    loss_dx = torch.log(torch.abs(output_grad_dx - depth_grad_dx) + 0.5).mean()
    loss_dy = torch.log(torch.abs(output_grad_dy - depth_grad_dy) + 0.5).mean()
    loss_normal = torch.abs(1 - cos(output_normal, depth_normal)).mean()
    loss = loss_depth + loss_normal + (loss_dx + loss_dy)
    losses.update(loss.data, batchSize)
Example #5
0
def train(train_loader, model, optimizer, epoch):
    criterion = nn.L1Loss()
    batch_time = AverageMeter()
    losses = AverageMeter()

    model.train()

    cos = nn.CosineSimilarity(dim=1, eps=0)
    get_gradient = sobel.Sobel().cuda()
    global args
    args = parser.parse_args()

    end = time.time()
    for i, sample_batched in enumerate(train_loader):

        image, depth = sample_batched['image'], sample_batched['depth']

        depth = depth.cuda(async=True)
        image = image.cuda()

        image = torch.autograd.Variable(image)
        depth = torch.autograd.Variable(depth)

        ones = torch.ones(depth.size(0), 1, depth.size(2),
                          depth.size(3)).float().cuda()
        ones = torch.autograd.Variable(ones)
        optimizer.zero_grad()

        output = model(image)

        if i % 200 == 0:
            x = output[0]
            x = x.view([220, 220])
            x = x.cpu().detach().numpy()
            x = x * 100000
            x2 = depth[0]
            print(x)
            x2 = x2.view([220, 220])
            x2 = x2.cpu().detach().numpy()
            x2 = x2 * 100000
            print(x2)

            x = x.astype('uint16')
            cv2.imwrite(args.data + str(i) + '_out.png', x)
            x2 = x2.astype('uint16')
            cv2.imwrite(args.data + str(i) + '_out2.png', x2)

        depth_grad = get_gradient(depth)
        output_grad = get_gradient(output)
        depth_grad_dx = depth_grad[:, 0, :, :].contiguous().view_as(depth)
        depth_grad_dy = depth_grad[:, 1, :, :].contiguous().view_as(depth)
        output_grad_dx = output_grad[:, 0, :, :].contiguous().view_as(depth)
        output_grad_dy = output_grad[:, 1, :, :].contiguous().view_as(depth)
        depth_normal = torch.cat((-depth_grad_dx, -depth_grad_dy, ones), 1)
        output_normal = torch.cat((-output_grad_dx, -output_grad_dy, ones), 1)
        loss_depth = torch.log(torch.abs(output - depth) + 0.5).mean()
        loss_dx = torch.log(torch.abs(output_grad_dx - depth_grad_dx) +
                            0.5).mean()
        loss_dy = torch.log(torch.abs(output_grad_dy - depth_grad_dy) +
                            0.5).mean()
        loss_normal = torch.abs(1 - cos(output_normal, depth_normal)).mean()
        loss = loss_depth + loss_normal + (loss_dx + loss_dy)
        losses.update(loss.data, image.size(0))
        loss.backward()
        optimizer.step()

        batch_time.update(time.time() - end)
        end = time.time()

        batchSize = depth.size(0)

        print('Epoch: [{0}][{1}/{2}]\t'
              'Time {batch_time.val:.3f} ({batch_time.sum:.3f})\t'
              'Loss {loss.val:.4f} ({loss.avg:.4f})'.format(
                  epoch,
                  i,
                  len(train_loader),
                  batch_time=batch_time,
                  loss=losses))
    log_value('training loss', losses.avg, epoch)
def train(train_loader, model, optimizer, epoch):
    criterion = nn.L1Loss()
    batch_time = AverageMeter()
    losses = AverageMeter()

    model.train()

    cos = nn.CosineSimilarity(dim=1, eps=0)
    get_gradient = sobel.Sobel().cuda()

    end = time.time()
    for i, sample_batched in enumerate(train_loader):
        image, depth = sample_batched['image'], sample_batched['depth']
        # print('--------Input information:')
        # print('image0 = {0},  image1 = {1},  image2 = {2},  image3 = {3}'.format(image.size(0), image.size(1), image.size(2), image.size(3)))

        depth = depth.cuda(async=True)  #  This can be used to overlap data transfers with computation.
        image = image.cuda()
        image = torch.autograd.Variable(image)  # torch.autograd provides classes and functions implementing automatic differentiation of arbitrary scalar valued functions. 
        depth = torch.autograd.Variable(depth)

        ones = torch.ones(depth.size(0), 1, depth.size(2),depth.size(3)).float().cuda() # batchSize = depth.size(0)
        ones = torch.autograd.Variable(ones)
        optimizer.zero_grad()   # we need to set the gradients to zero before starting to do backpropragation because PyTorch accumulates the gradients on subsequent backward passes. 
                                # the default action is to accumulate (i.e. sum) the gradients on every loss.backward() call.

        output = model(image)
        # print('--------Output information:')
        # print('output0 = {0},  output1 = {1},  output2 = {2},  output3 = {3}'.format(output.size(0), output.size(1), output.size(2), output.size(3)))

        depth_grad = get_gradient(depth)
        output_grad = get_gradient(output)
        depth_grad_dx = depth_grad[:, 0, :, :].contiguous().view_as(depth)      # depth_grad.shape = (-1, 2, x.size(2), x.size(3))
        depth_grad_dy = depth_grad[:, 1, :, :].contiguous().view_as(depth)
        output_grad_dx = output_grad[:, 0, :, :].contiguous().view_as(depth)
        output_grad_dy = output_grad[:, 1, :, :].contiguous().view_as(depth)

        # print('--------Output_grad_dx information:')
        # print('output_grad_dx0 = {0},  output_grad_dx1 = {1},  output_grad_dx2 = {2},  output_grad_dx3 = {3}'.format(output_grad_dx.size(0), output_grad_dx.size(1), output_grad_dx.size(2), output_grad_dx.size(3)))

        depth_normal = torch.cat((-depth_grad_dx, -depth_grad_dy, ones), 1)
        output_normal = torch.cat((-output_grad_dx, -output_grad_dy, ones), 1)
        
        # print('--------output_normal information:')
        # print('output_normal0 = {0},  output_normal1 = {1},  output_normal2 = {2},  output_normal3 = {3}'.format(output_normal.size(0), output_normal.size(1), output_normal.size(2), output_normal.size(3)))

        # depth_normal = F.normalize(depth_normal, p=2, dim=1)
        # output_normal = F.normalize(output_normal, p=2, dim=1)

        loss_depth = torch.log(torch.abs(output - depth) + 0.5).mean()
        loss_dx = torch.log(torch.abs(output_grad_dx - depth_grad_dx) + 0.5).mean()
        loss_dy = torch.log(torch.abs(output_grad_dy - depth_grad_dy) + 0.5).mean()
        loss_normal = torch.abs(1 - cos(output_normal, depth_normal)).mean()
        # print('--------loss information:')
        # print('loss_depth.info = ', loss_depth)
        # print('loss_dx.info = ', loss_dx)
        # print('loss_dy.info = ', loss_dy)
        # print('loss_normal.info = ', loss_normal)
        
        loss = loss_depth + loss_normal + (loss_dx + loss_dy)
        # print('loss.info = ', loss)

        # print('+++++++')
        # print('loss.data[0] = ', loss.data)
        # print('loss.data[0].item = ', loss.item)

        # print('image.size(0) = ', image.size(0))
        # losses.update(loss.data[0], image.size(0))  # bai2 old PyTorch=0.4.1
        losses.update(loss.data, image.size(0))  # bai2 new PyTorch>=0.5

        loss.backward() # The graph is used by loss.backward() to compute gradients.
        optimizer.step()    # Performs a parameter update based on the current gradient (stored in .grad attribute of a parameter) and the update rule

        batch_time.update(time.time() - end)
        end = time.time()
   
        batchSize = depth.size(0)

        print('Epoch: [{0}][{1}/{2}]\t'
          'Time {batch_time.val:.3f} ({batch_time.sum:.3f})\t'
          'Loss {loss.val:.4f} ({loss.avg:.4f})'
          .format(epoch, i, len(train_loader), batch_time=batch_time, loss=losses))
def train(train_loader,  model,model_final, optimizer, epoch,logger ):
    batch_time = AverageMeter()
    losses = AverageMeter()
    model.train()

    #梯度与预先相似度
    cos = nn.CosineSimilarity(dim=1, eps=0)
    get_gradient = sobel.Sobel().cuda()

    end = time.time()

    for i, sample_batched in enumerate(train_loader):
        total_step = len(train_loader)
        image, depth,focal,_ = sample_batched['image'], sample_batched['depth'], sample_batched['focal'],sample_batched['depth1']
        depth = depth.cuda()
        image = image.cuda()
        focal = focal .cuda()
        focal = torch.cat(torch.chunk(focal, 12, dim=1), dim=0)  # 2*12*3*256*256
        focal = focal.squeeze(1)

        image = torch.autograd.Variable(image)
        depth = torch.autograd.Variable(depth)
        ones = torch.ones(depth.size(0), 1, depth.size(2), depth.size(3)).float().cuda()
        ones = torch.autograd.Variable(ones)

        optimizer.zero_grad()

        out = model(image)
        output = model_final(out, focal)

        # 梯度
        depth_grad = get_gradient(depth)
        output_grad = get_gradient(output)
        depth_grad_dx = depth_grad[:, 0, :, :].contiguous().view_as(depth)
        depth_grad_dy = depth_grad[:, 1, :, :].contiguous().view_as(depth)
        output_grad_dx = output_grad[:, 0, :, :].contiguous().view_as(depth)
        output_grad_dy = output_grad[:, 1, :, :].contiguous().view_as(depth)

        # 法线
        depth_normal = torch.cat((-depth_grad_dx, -depth_grad_dy, ones), 1)
        output_normal = torch.cat((-output_grad_dx, -output_grad_dy, ones), 1)

        # loss
        loss_depth = torch.log(torch.abs(output - depth) + 1.0).mean()
        loss_dx = torch.log(torch.abs(output_grad_dx - depth_grad_dx) + 1.0).mean()
        loss_dy = torch.log(torch.abs(output_grad_dy - depth_grad_dy) +1.0).mean()
        loss_normal = torch.abs(1 - cos(output_normal, depth_normal)).mean()
        loss = loss_depth + loss_normal + (loss_dx + loss_dy)

        logger.log_value('loss',loss,step=i+(epoch-1)*total_step)

        losses.update(loss.item(), image.size(0))
        loss.backward()
        torch.cuda.empty_cache()
        optimizer.step()
        batch_time.update(time.time() - end)
        end = time.time()

        print('Epoch: [{0}][{1}/{2}]\t'
          'Time {batch_time.val:.3f} ({batch_time.sum:.3f})\t'
          'Loss {loss.val:.4f} ({loss.avg:.4f})\t'
          .format(epoch, i, len(train_loader), batch_time=batch_time, loss=losses))
Example #8
0
def train(train_loader, model, model2, optimizer, epoch):
    batch_time = AverageMeter()
    losses = AverageMeter()
    totalNumber = 0
    errorSum = {
        'MSE': 0,
        'RMSE': 0,
        'ABS_REL': 0,
        'LG10': 0,
        'MAE': 0,
        'DELTA1': 0,
        'DELTA2': 0,
        'DELTA3': 0
    }
    model.eval()
    model2.train()

    cos = nn.CosineSimilarity(dim=1, eps=0)
    get_gradient = sobel.Sobel().cuda()

    end = time.time()
    for i, sample_batched in enumerate(train_loader):
        image, depth_ = sample_batched['image'], sample_batched['depth']

        image = torch.autograd.Variable(image).cuda()
        depth_ = torch.autograd.Variable(depth_).cuda()

        ones = torch.ones(depth_.size(0), 1, depth_.size(2),
                          depth_.size(3)).float().cuda()
        ones = torch.autograd.Variable(ones)

        depth = model(image.clone()).detach()

        optimizer.zero_grad()
        mask = model2(image)
        output = model(image * mask)

        depth_grad = get_gradient(depth)
        output_grad = get_gradient(output)
        depth_grad_dx = depth_grad[:, 0, :, :].contiguous().view_as(depth)
        depth_grad_dy = depth_grad[:, 1, :, :].contiguous().view_as(depth)
        output_grad_dx = output_grad[:, 0, :, :].contiguous().view_as(depth)
        output_grad_dy = output_grad[:, 1, :, :].contiguous().view_as(depth)

        depth_normal = torch.cat((-depth_grad_dx, -depth_grad_dy, ones), 1)
        output_normal = torch.cat((-output_grad_dx, -output_grad_dy, ones), 1)

        loss_depth = torch.log(torch.abs(output - depth) + 0.5).mean()
        loss_dx = torch.log(torch.abs(output_grad_dx - depth_grad_dx) +
                            0.5).mean()
        loss_dy = torch.log(torch.abs(output_grad_dy - depth_grad_dy) +
                            0.5).mean()
        loss_normal = torch.abs(1 - cos(output_normal, depth_normal)).mean()

        loss_rec = loss_depth + loss_normal + (loss_dx + loss_dy)
        loss_sparse = mask.mean()

        loss = loss_rec + loss_sparse * 5

        losses.update(loss_sparse.data[0], image.size(0))
        loss.backward()
        optimizer.step()

        batch_time.update(time.time() - end)
        end = time.time()

        batchSize = depth.size(0)

        errors = util.evaluateError(output, depth)
        errorSum = util.addErrors(errorSum, errors, batchSize)
        totalNumber = totalNumber + batchSize
        averageError = util.averageErrors(errorSum, totalNumber)

        print('Epoch: [{0}][{1}/{2}]\t'
              'Time {batch_time.val:.3f} ({batch_time.sum:.3f})\t'
              'Loss {loss.val:.4f} ({loss.avg:.4f})'.format(
                  epoch,
                  i,
                  len(train_loader),
                  batch_time=batch_time,
                  loss=losses))
    print('errors: ', averageError)
Example #9
0
def train_model(
    train_ds: tf.data.Dataset,
    dev_ds: tf.data.Dataset,
    model: nn.Module,
    optimizer: optim.Optimizer,
    lr_scheduler: optim.lr_scheduler._LRScheduler,
    args: argparse.Namespace,
) -> nn.Module:

    device = model_utils.get_device()
    loss_fn = model_utils.depth_proportional_loss
    val_loss_fn = model_utils.l1_norm_loss
    best_val_loss = torch.tensor(float('inf'))
    saved_checkpoints = []
    writer = SummaryWriter(log_dir=f'{args.log_dir}/{args.experiment}')

    cos = nn.CosineSimilarity(dim=1, eps=0)
    get_gradient: nn.Module = sobel.Sobel().to(device)

    for e in range(1, args.train_epochs + 1):
        print(f'Training epoch {e}...')

        if args.use_scheduler:
            lr_scheduler.step()

        # Training portion
        torch.cuda.empty_cache()
        torch.set_grad_enabled(True)
        with tqdm(total=args.train_batch_size * len(train_ds)) as progress_bar:
            model.train()
            for i, (x_batch_orig,
                    y_batch) in enumerate(train_ds.as_numpy_iterator()):
                x_batch, y_batch = model_utils.preprocess_training_example(
                    x_batch_orig, y_batch)
                y_blurred = model_utils.blur_depth_map(y_batch)

                ones = torch.ones(y_batch.shape,
                                  dtype=torch.float32,
                                  device=device)

                # Forward pass on model
                optimizer.zero_grad()
                y_pred = model(x_batch)

                depth_grad = get_gradient(y_blurred)
                output_grad = get_gradient(y_pred)
                depth_grad_dx = depth_grad[:, 0, :, :].contiguous().view_as(
                    y_blurred)
                depth_grad_dy = depth_grad[:, 1, :, :].contiguous().view_as(
                    y_batch)
                output_grad_dx = output_grad[:, 0, :, :].contiguous().view_as(
                    y_blurred)
                output_grad_dy = output_grad[:, 1, :, :].contiguous().view_as(
                    y_batch)

                depth_normal = torch.cat(
                    (-depth_grad_dx, -depth_grad_dy, ones), 1)
                output_normal = torch.cat(
                    (-output_grad_dx, -output_grad_dy, ones), 1)

                loss_depth = torch.log(torch.abs(y_pred - y_batch) +
                                       0.5).mean()
                loss_dx = torch.log(
                    torch.abs(output_grad_dx - depth_grad_dx) + 0.5).mean()
                loss_dy = torch.log(
                    torch.abs(output_grad_dy - depth_grad_dy) + 0.5).mean()
                loss_normal = torch.abs(
                    1 - cos(output_normal, depth_normal)).mean()

                loss = loss_depth + loss_normal + (loss_dx + loss_dy)

                # Backward pass and optimization
                loss.backward()
                optimizer.step()

                progress_bar.update(len(x_batch))
                progress_bar.set_postfix(loss=loss.item())
                writer.add_scalar("train/Loss", loss,
                                  ((e - 1) * len(train_ds) + i) *
                                  args.train_batch_size)

                # Periodically save a diagram
                if (i + 1) % args.picture_frequency == 0:
                    model_utils.make_diagram(
                        np.transpose(x_batch_orig, (0, 3, 1, 2)),
                        x_batch.cpu().numpy(),
                        y_batch.cpu().numpy(),
                        y_pred.cpu().detach().numpy(),
                        f'{args.save_path}/{args.experiment}/diagram_{e}_{i+1}.png',
                    )

                del x_batch
                del y_batch
                del y_blurred
                del y_pred
                del loss

        # Validation portion
        torch.cuda.empty_cache()
        torch.set_grad_enabled(False)

        with tqdm(total=args.dev_batch_size * len(dev_ds)) as progress_bar:
            model.eval()
            val_loss = 0.0
            num_batches_processed = 0
            total_pixels = 0
            total_examples = 0
            squared_error = 0
            rel_error = 0
            log_error = 0
            threshold1 = 0  # 1.25
            threshold2 = 0  # 1.25^2
            threshold3 = 0  # corresponds to 1.25^3

            for i, (x_batch, y_batch) in enumerate(dev_ds.as_numpy_iterator()):
                x_batch, y_batch = model_utils.preprocess_test_example(
                    x_batch, y_batch)
                # Forward pass on model in validation environment
                y_pred = model(x_batch)

                # TODO: Process y_pred in whatever way inference requires.
                loss = val_loss_fn(y_pred, y_batch)
                val_loss += loss.item()
                num_batches_processed += 1

                nanmask = getNanMask(y_batch)
                total_pixels = torch.sum(~nanmask)
                total_examples += x_batch.shape[0]

                # RMS, REL, LOG10, threshold calculation
                squared_error += (
                    torch.sum(torch.pow(y_pred - y_batch, 2)).item() /
                    total_pixels)**0.5
                rel_error += torch.sum(
                    removeNans(torch.abs(y_pred - y_batch) /
                               y_batch)).item() / total_pixels
                log_error += torch.sum(
                    torch.abs(
                        removeNans(torch.log10(y_pred)) - removeNans(
                            torch.log10(y_batch)))).item() / total_pixels
                threshold1 += torch.sum(
                    torch.max(y_pred / y_batch, y_batch /
                              y_pred) < 1.25).item() / total_pixels
                threshold2 += torch.sum(
                    torch.max(y_pred / y_batch, y_batch /
                              y_pred) < 1.25**2).item() / total_pixels
                threshold3 += torch.sum(
                    torch.max(y_pred / y_batch, y_batch /
                              y_pred) < 1.25**3).item() / total_pixels

                progress_bar.update(len(x_batch))
                progress_bar.set_postfix(val_loss=val_loss /
                                         num_batches_processed)
                writer.add_scalar("Val/Loss", loss,
                                  ((e - 1) * len(dev_ds) + i) *
                                  args.dev_batch_size)

                del x_batch
                del y_batch
                del y_pred
                del loss

            writer.add_scalar("Val/RMS", squared_error / total_examples, e)
            writer.add_scalar("Val/REL", rel_error / total_examples, e)
            writer.add_scalar("Val/LOG10", log_error / total_examples, e)
            writer.add_scalar("Val/delta1", threshold1 / total_examples, e)
            writer.add_scalar("Val/delta2", threshold2 / total_examples, e)
            writer.add_scalar("Val/delta3", threshold3 / total_examples, e)

            # Save model if it's the best one yet.
            if val_loss / num_batches_processed < best_val_loss:
                best_val_loss = val_loss / num_batches_processed
                filename = f'{args.save_path}/{args.experiment}/{model.__class__.__name__}_best_val.checkpoint'
                model_utils.save_model(model, filename)
                print(f'Model saved!')
                print(f'Best validation loss yet: {best_val_loss}')
            # Save model on checkpoints.
            if e % args.checkpoint_freq == 0:
                filename = f'{args.save_path}/{args.experiment}/{model.__class__.__name__}_epoch_{e}.checkpoint'
                model_utils.save_model(model, filename)
                print(f'Model checkpoint reached!')
                saved_checkpoints.append(filename)
                # Delete checkpoints if there are too many
                while len(saved_checkpoints) > args.num_checkpoints:
                    os.remove(saved_checkpoints.pop(0))

    return model
Example #10
0
def train_model(dataloader, rmodel, model, optimizer, start_epoch, epochs,
                output_dir):

    #     # initialize grid for point selection
    #     step = 5
    #     grid = torch.zeros([114,152],dtype=torch.uint8)
    #     x = np.arange(0,114,step)
    #     y = np.arange(0,152,step)
    #     X,Y = np.meshgrid(x,y)
    #     grid[X.ravel(),Y.ravel()]=1
    #     grid = grid.view(-1).cuda()

    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    best_acc = np.inf

    valfile = open(output_dir + 'validation.log', 'w')
    trainfile = open(output_dir + 'training.log', 'w')
    resultsfile = open(output_dir + 'results.log', 'w')

    #     d1 = 114
    #     d2 = 152
    #     xx, yy = torch.meshgrid([torch.arange(d1), torch.arange(d2)])
    #     xx = xx.cuda()
    #     yy = yy.cuda()

    for epoch in range(start_epoch, epochs):

        #         adjust_learning_rate(optimizer, epoch)

        for phase in ['train', 'val']:
            if phase == 'train':
                rmodel.train()  # Set model to training mode
                model.eval()  # Set model to training mode
            else:
                continue
                rmodel.eval()  # Set model to evaluate mode
                model.eval()  # Set model to evaluate mode

            since = time.time()

            threshold_percent = AverageMeter()
            batch_time = AverageMeter()
            losses = AverageMeter()
            totalNumber = 0
            acc = AverageMeter()
            errorSum = {
                'MSE': 0,
                'RMSE': 0,
                'ABS_REL': 0,
                'LG10': 0,
                'MAE': 0,
                'DELTA1': 0,
                'DELTA2': 0,
                'DELTA3': 0
            }

            print('Epoch {}/{}'.format(epoch, epochs - 1))
            print('-' * 10)

            cos = nn.CosineSimilarity(dim=1, eps=0)
            get_gradient = sobel.Sobel().cuda()
            mu = 1
            lamda = 1
            alpha = 0.5

            # Iterate over data.
            end = time.time()
            for i, sample_batched in enumerate(dataloader[phase]):

                image, depth, mask, imagedepth, imagemask = \
                    sample_batched['image'].cuda(), sample_batched['depth'].cuda(), sample_batched['mask'].cuda(), sample_batched['imagedepth'].cuda(), sample_batched['imagemask'].cuda()

                bs = image.size(0)

                depth_mean = 0  #1.8698
                depth_std = 10  #1.6716

                #                 mi, _ = depth.view(bs,-1).min(1)
                #                 mi = mi.view(-1,1,1,1)
                #                 ma, _ = depth.view(bs,-1).max(1)
                #                 ma = ma.view(-1,1,1,1)
                #                 depth = (depth - mi)/(ma-mi)

                depth = (depth - depth_mean) / depth_std

                # zero the parameter gradients
                optimizer.zero_grad()

                zero_points = torch.zeros_like(imagemask)
                base_input = image  #torch.cat((image,imagemask, zero_points),dim=1)

                with torch.set_grad_enabled(False):
                    output = model(base_input)
                    #                     output2x = nn.functional.interpolate(output, size=None, scale_factor=2)
                    #                     output = output.squeeze().view(114,152).data.cpu().float().numpy()
                    #                     matplotlib.image.imsave(output_dir+'base'+'.png', output)

                    #                     # normalize
                    #                     mi, _ = output.view(bs,-1).min(1)
                    #                     mi = mi.view(-1,1,1,1)
                    #                     ma, _ = output.view(bs,-1).max(1)
                    #                     ma = ma.view(-1,1,1,1)
                    #                     output = (output - mi)/(ma-mi)

                    output = (output - depth_mean) / depth_std

                    # #                     imagemask = image[:,3,:,:].unsqueeze(1)
                    P = torch.zeros_like(output)

                    #                     diff_map = (output/depth - 1)*mask # < 0 if output point is relatively farther
                    #                     adj_diff_map = torch.abs(diff_map)>0.5
                    #                     # 3 levels of ordinal relatinos
                    # #                     abs_diff_map = torch.abs(diff_map)
                    # #                     K = 3

                    diff_map = (output / depth - 1) * mask
                    diff_map_reverse = (depth / output - 1) * mask
                    adj_diff_map = torch.max(
                        torch.abs(diff_map),
                        torch.abs(diff_map_reverse)) > 0.25

                    threshold_percent.update(adj_diff_map.sum() / mask.sum(),
                                             1)

                    # #                     diff_map = output - depth
                    # #                     adj_diff_map = torch.zeros_like(diff_map).byte()
                    # #                     for j in range(bs):
                    # #                         subdiff = diff_map[j,:,:,:]
                    # #                         adj_diff_map[j,:,:,:] = torch.abs(subdiff)>0.1*(subdiff.max())

                    #                     selection_percent = 0.25
                    #                     r = (torch.rand_like(mask) <= selection_percent) * adj_diff_map
                    #                     P = torch.sign(diff_map) * mask * r.float()

                    #                     m = r.view(bs,-1).data.nonzero()
                    #                     sig = 5
                    #                     d1 = r.size(2)
                    #                     d2 = r.size(3)
                    # #                     xx, yy = torch.meshgrid([torch.arange(d1), torch.arange(d2)])
                    # #                     xx = xx.cuda()
                    # #                     yy = yy.cuda()
                    #                     F = torch.zeros_like(r).float()
                    #                     g = F[0,0,:,:]
                    #                     old_idx = 0
                    #                     for idx in m:
                    #                         mask_idx = idx[0]
                    #                         if (mask_idx != old_idx):
                    #                             F[mask_idx-1,0,:,:] = g/g.max()
                    #                             g = F[mask_idx,0,:,:]
                    #                         one_idx = idx[1]
                    #                         x0 = one_idx // d2
                    #                         y0 = one_idx % d2
                    #                         t = -0.5 * ((xx-x0)**2 + (yy-y0)**2).float() / sig**2
                    #                         kernel = torch.exp(t)
                    #                         g += kernel
                    #                     F[mask_idx,0,:,:] = g/g.max()
                    #                     r = F

                    D = diff_map.view(bs, -1)
                    m = torch.max(torch.abs(D),
                                  torch.abs(diff_map_reverse).view(
                                      bs, -1)).argmax(1).view(-1, 1)

                    # P is -1 at point where
                    updates = torch.sign(D.gather(1, m))
                    P.view(bs, -1).scatter_(1, m, updates)

                    #                     new_input = torch.cat((image, P),dim=1)

                    #                     d = torch.abs(diff_map[0,:,:,:])
                    #                     depth = d.squeeze().view(228,304).data.cpu().float().numpy()
                    #                     implot = plt.imshow(depth)
                    #                     d2 = diff_map.size(3)

                    #                     indices = torch.cat((m // d2, m % d2), dim=1).data.cpu()

                    #                     plt.scatter(indices[0,1],indices[0,0],c='r')
                    #                     plt.savefig(output_dir+'point'+'.png')

                    #                     mask = mask[0,:,:,:]
                    #                     mask = mask.squeeze().view(114,152).data.cpu().float().numpy()
                    #                     matplotlib.image.imsave(output_dir+str(i)+'mask'+'.png', mask)

                    #                     for j in range(bs): # batch size
                    # #                         submask = mask[j,:,:,:].view(-1).byte()
                    #                         submask = mask[j,:,:,:].view(-1).byte()
                    #                         z = output[j,:,:,:].view(-1)
                    #                         gt_depth = depth[j,:,:,:].view(-1)
                    #                         subP = P[j,:,:,:].view(-1)

                    #                         num_sampled = 1 # number of randomly sample points pairs in mask
                    #                         NZ = submask.nonzero()
                    #                         sample_idx = torch.multinomial(torch.ones(submask.nonzero().size(0)),num_sampled*2)
                    #                         randomly_sampled = NZ[sample_idx,:]
                    #                         J = randomly_sampled.view(num_sampled,2)
                    # #                         # choose
                    # #                         for ik in randomly_sampled:
                    # #                             diff = gt_depth[ik]-z[i]

                    #                         # select point-pair with greatest discrepancy
                    #                         best_pair = None
                    #                         max_diff = 0
                    #                         for (ik,jk) in J: #combinations(randomly_sampled, 2):
                    #                             gt_diff = gt_depth[ik]/gt_depth[jk]
                    #                             z_diff = z[ik]/z[jk]
                    #                             diff = gt_diff - z_diff
                    #                             if torch.abs(diff) > max_diff:
                    #                                 best_pair = (ik,jk)
                    #                                 max_diff = torch.abs(diff)

                    #                         ik = best_pair[0]
                    #                         jk = best_pair[1]
                    #                         if max_diff<0: # predicted P1 should be relatively closer, P2 relatively further
                    #                             subP[ik] = 1
                    #                             subP[jk] = -1
                    #                         else:
                    #                             subP[ik] = -1
                    #                             subP[jk] = 1

                    new_input = torch.cat((output, mask, P), dim=1)

                # forward
                # track history if only in train
                with torch.set_grad_enabled(phase == 'train'):

                    #                     output = model(image).detach()
                    #                     P = torch.zeros_like(output).cuda()

                    refined_output = rmodel(new_input)

                    #                     P.zero_()

                    #                     diff_map = (refined_output.detach()/depth - 1)*mask # < 0 if output point is relatively farther

                    #                     D = diff_map.view(bs, -1)
                    #                     m = torch.abs(D).argmax(1).view(-1,1)

                    #                     updates = torch.sign(D.gather(1,m))
                    #                     P.view(bs,-1).scatter_(1,m,updates)

                    #                     new_input = torch.cat((refined_output, mask, P),dim=1)

                    #                     refined_output = rmodel(new_input)

                    #                     P.zero_()

                    #                     diff_map = (refined_output.detach()/depth - 1)*mask # < 0 if output point is relatively farther

                    #                     D = diff_map.view(bs, -1)
                    #                     m = torch.abs(D).argmax(1).view(-1,1)

                    #                     updates = torch.sign(D.gather(1,m))
                    #                     P.view(bs,-1).scatter_(1,m,updates)

                    #                     new_input = torch.cat((refined_output, mask, P),dim=1)

                    #                     refined_output = rmodel(new_input)

                    #                     routput_im = refined_output.squeeze().view(114,152).data.cpu().float().numpy()
                    #                     matplotlib.image.imsave(output_dir+'refined'+'.png', routput_im)

                    #                     output_im = refined_output.squeeze().view(114,152).data.cpu().float().numpy()
                    #                     matplotlib.image.imsave(output_dir+'output'+'.png', output_im)

                    byte_mask = mask.byte()
                    masked_depth = depth[byte_mask]
                    masked_output = output[byte_mask]
                    masked_refined_output = refined_output[byte_mask]

                    depth_ = depth
                    output_ = refined_output

                    ones = torch.ones(depth_.size(0), 1, depth_.size(2),
                                      depth_.size(3)).float().cuda()
                    depth_grad = get_gradient(depth_)
                    output_grad = get_gradient(output_)
                    depth_grad_dx = depth_grad[:,
                                               0, :, :].contiguous().view_as(
                                                   depth_)
                    depth_grad_dy = depth_grad[:,
                                               1, :, :].contiguous().view_as(
                                                   depth_)
                    output_grad_dx = output_grad[:,
                                                 0, :, :].contiguous().view_as(
                                                     depth_)
                    output_grad_dy = output_grad[:,
                                                 1, :, :].contiguous().view_as(
                                                     depth_)

                    depth_normal = torch.cat(
                        (-depth_grad_dx, -depth_grad_dy, ones), 1)
                    output_normal = torch.cat(
                        (-output_grad_dx, -output_grad_dy, ones), 1)

                    loss_depth = torch.log(torch.abs(output_ - depth_) + alpha)
                    loss_dx = torch.log(
                        torch.abs(output_grad_dx - depth_grad_dx) + alpha)
                    loss_dy = torch.log(
                        torch.abs(output_grad_dy - depth_grad_dy) + alpha)
                    loss_grad = loss_dx + loss_dy
                    loss_normal = torch.abs(1 -
                                            cos(output_normal, depth_normal))

                    loss_normal.unsqueeze_(1)
                    loss_depth_masked = loss_depth[byte_mask].mean()
                    loss_grad_masked = loss_grad[byte_mask].mean()
                    loss_normal_masked = loss_normal[byte_mask].mean()

                    loss = loss_depth_masked + mu * loss_normal_masked + lamda * loss_grad_masked

                    #                     loss_point_depth_masked = loss_depth.view(bs,-1).gather(1,m).mean()
                    #                     loss_point_grad_masked = loss_grad.view(bs,-1).gather(1,m).mean()
                    #                     loss_point_normal_masked = loss_normal.view(bs,-1).gather(1,m).mean()

                    #                     loss_point_depth_masked = (loss_depth)[byte_mask*r].mean()
                    #                     loss_point_grad_masked = (loss_grad)[byte_mask* r].mean()
                    #                     loss_point_normal_masked = (loss_normal)[byte_mask* r].mean()

                    #                     point_loss = loss_point_depth_masked + mu*loss_point_grad_masked + lamda*loss_point_normal_masked

                    #                     loss += 0.5*point_loss

                    # #                     #berHu loss (Deeper Depth Prediction with Fully Convolutional Residual Networks)
                    #                     diff = torch.abs(masked_refined_output - masked_depth)
                    #                     c = torch.max(diff)/5
                    #                     bh = diff.where(diff<=c, (diff**2+c**2)/(2*c))
                    #                     bh_loss = bh.sum()/mask.sum()

                    #                     # point loss
                    #                     diff_map = torch.abs((refined_output/depth - 1)*mask)
                    #                     D = diff_map.view(bs, -1)
                    #                     point_loss = torch.sum(D.gather(1,m))/bs

                    #                     loss = bh_loss + 3*point_loss

                    #                     loss = diff[diff<=c] + ((diff[diff>c])**2)/(2*c)

                    #                     # loss function
                    #                     rankingloss = 0
                    #                     for j in range(bs): # batch size
                    #                         submask = mask[j,:,:,:].view(-1).byte()
                    #                         z = refined_output[j,:,:,:].view(-1)
                    #                         gt_depth = depth[j,:,:,:].view(-1)
                    # #                         selection_points = torch.mul(submask,grid)

                    # #                         NZ = selection_points.nonzero()
                    #                         NZ = submask.nonzero()

                    #                         M = 10 # number of pairs of points selected k = 1..M-1
                    #                         sample_idx = torch.multinomial(torch.ones(NZ.size(0)),2*M)

                    # #                         if NZ.size(0) < 2*M:
                    # #                             sample_idx = torch.multinomial(torch.ones(submask.nonzero().size(0)),2*M)
                    # # #                             M = NZ.size(0)//2
                    # #                         else:
                    # #                             sample_idx = torch.multinomial(torch.ones(NZ.size(0)),2*M)
                    #                         J = NZ[sample_idx,:]
                    #                         J = J.view(M,2)

                    # #                         r = torch.zeros(M,).cuda()
                    # #                         k = 0
                    #                         tau = 0.02
                    #                         rloss = 0
                    #                         for ik, jk in J: # M*(M-1)/2 loop iterations (so keep M small!)
                    #                             if (gt_depth[ik]/gt_depth[jk] > 1 + tau):
                    #                                 rloss += torch.log(1+torch.exp(-z[ik]+z[jk])) # jk closer than ik
                    #     #                             r[k] = 1
                    #                             elif (gt_depth[jk]/gt_depth[ik] > 1 + tau): # ik closer than jk
                    #                                 rloss += torch.log(1+torch.exp(z[ik]-z[jk]))
                    #     #                             r[k] = -1
                    #                             else: # equal
                    #                                 rloss += (z[ik]-z[jk])**2
                    #     #                             r[k] = 0
                    #     #                         k = k + 1

                    #                         rankingloss += rloss/M
                    #                     rl = rankingloss/bs

                    #                     loss += 2*rl

                    losses.update(loss.item(), bs)

                    if phase == 'train':
                        loss.backward()
                        optimizer.step()

#                 masked_depth = depth[mask.byte()]
#                 masked_output = output[mask.byte()]
#                 if phase == 'val':
#                     depth_val = masked_depth.data.cpu().numpy()
#                     output_val = masked_output.data.cpu().numpy()
#                     indices = np.argsort(depth_val,kind='stable')
#                     idx = np.argsort(output_val[indices],kind='stable')
#                     n = idx.size
#                     num_swaps = countSwaps(idx, n)
#                     acc.update(num_swaps/n)

# statistics
                batch_time.update(time.time() - end)
                end = time.time()

                errors = util.evaluateError(masked_refined_output,
                                            masked_output)
                errorSum = util.addErrors(errorSum, errors, bs)
                totalNumber = totalNumber + bs
                averageError = util.averageErrors(errorSum, totalNumber)

                if i % 100 == 0:
                    out_str = (
                        'Epoch: [{0}][{1}/{2}]\t'
                        'Time {batch_time.val:.3f} ({batch_time.sum:.3f})\t'
                        'Loss {loss.val:.4f} ({loss.avg:.4f})'.format(
                            epoch,
                            i,
                            len(dataloader[phase]),
                            batch_time=batch_time,
                            loss=losses))
                    print(out_str)
                    trainfile.write(out_str + '\n')

            # get accuracy as RMSE
#             epoch_acc = np.sqrt(averageError['MSE'])
#             epoch_acc = acc.avg

# deep copy the model
            if phase == 'val':
                epoch_acc = np.sqrt(averageError['MSE'])
                valfile.write('epoch: ' + str(epoch) + ', rmse: ' +
                              str(epoch_acc) + '\n')
                if epoch_acc < best_acc:
                    best_acc = epoch_acc
                    is_best = True
                else:
                    is_best = False
            save_checkpoint(rmodel, optimizer, loss, False, epoch, output_dir)

            time_elapsed = time.time() - since
            s1 = 'Testing complete in {:.0f}m {:.0f}s'.format(
                time_elapsed // 60, time_elapsed % 60)
            s2 = 'rmse:' + str(np.sqrt(averageError['MSE']))
            s3 = 'abs_rel:' + str(averageError['ABS_REL'])
            s4 = 'mae:' + str(averageError['MAE'])
            print(s1)
            print(s2)
            print(s3)
            print(s4)
            resultsfile.write(phase + '\n')
            resultsfile.write(s1 + '\n')
            resultsfile.write(s2 + '\n')
            resultsfile.write(s3 + '\n')
            resultsfile.write(s4 + '\n')

            print(threshold_percent.avg)

            valfile.write('\n')
            trainfile.write('\n')
            resultsfile.write('\n')


#             print('avg. num swaps:',epoch_acc)

        print()

    print('errors: ', averageError)