Esempio n. 1
0
def train_hold_out(model,
                   criterion,
                   optimizer,
                   args,
                   train_set,
                   val_set,
                   test_set,
                   single_view=False):
    """
    Perform a train with validation train split on the given model.  Use args.val_split_size to set the percentage of
    data for the validation set. Keep in mind the two validation sets are genereted. One for early stopping and one to
    evaluate the model.

    All the data are sent to wandb or logged on a text file

    Parameters
    ----------
    model : RotaitonNet model
    criterion : Pytorch criterion (CrossEntropy for RotationNet)
    optimizer : Pytorch optimizer (e.g. SGD)
    args : Input args from the parser

    Returns
    -------
    Nothing
    """

    # Generate loaders
    test_loader = DataLoader(test_set,
                             batch_size=args.batch_size,
                             shuffle=single_view,
                             num_workers=args.workers,
                             pin_memory=True,
                             drop_last=True)
    val_loader = DataLoader(val_set,
                            batch_size=args.batch_size,
                            shuffle=single_view,
                            num_workers=args.workers,
                            pin_memory=True,
                            drop_last=True)
    train_loader = DataLoader(train_set,
                              batch_size=args.batch_size,
                              shuffle=single_view,
                              num_workers=args.workers,
                              pin_memory=True,
                              drop_last=True)

    # Track model in wandb
    #wandb.init(project="MVCNN", config=args, reinit=True)

    # wandb.watch(model)

    train(model, criterion, optimizer, train_loader, val_loader, args,
          single_view)

    load_model(model, args.fname_best)

    val_statistics = validate(test_loader, model, criterion, args, single_view)

    log_summary(val_statistics, "val", test_loader.dataset.dataset.classes)
Esempio n. 2
0
def train_hold_out(model, criterion, optimizer, args):
    """
    Perform a train with validation train split on the given model.  Use args.val_split_size to set the percentage of
    data for the validation set. Keep in mind the two validation sets are genereted. One for early stopping and one to
    evaluate the model.

    All the data are sent to wandb or logged on a text file

    Parameters
    ----------
    model : RotaitonNet model
    criterion : Pytorch criterion (CrossEntropy for RotationNet)
    optimizer : Pytorch optimizer (e.g. SGD)
    args : Input args from the parser

    Returns
    -------
    Nothing
    """

    trans = []

    if args.flip:
        # flip is with 0.5 probability
        trans.append(transforms.RandomHorizontalFlip())
        trans.append(transforms.RandomVerticalFlip())
    if args.rotation:
        trans.append(transforms.RandomRotation((0, 90), expand=args.rotation_expand))
    # if expand is true then resize the image to the right size
    if args.rotation_expand:
        trans.append(transforms.Resize(224))

    # Get full train dataset
    # Create two different sets but one with and one without transformations (random rotation and flip)
    if args.depth:
        # create one element tuple to be consistent with ImageFolder dataset of Pytorch
        full_set_train = (DepthDataset(args.data, 'train', trans),)
        full_set_val = (DepthDataset(args.data, 'train'),)
    else:
        full_set_train = generate_dataset(args.data, 'train', trans)
        full_set_val = generate_dataset(args.data, 'train',[])

    # Get test train split. The test set here is intended as validation set but because we need also a validation set
    # for the early stopping we call it test
    test_idx, train_idx = train_test_split(full_set_train[0].samples, range(len(full_set_train[0].samples)),
                                           args.nview,
                                           args.val_split_size, True)
    # Get val train split
    val_idx, train_idx = train_test_split([full_set_train[0].samples[i] for i in train_idx], train_idx, args.nview,
                                          args.val_split_size, True)

    if args.nelements != 0:
        train_idx = under_sampler_to([full_set_train[0].samples[i] for i in train_idx], train_idx, args.nview,
                                     args.nelements)

    _, classes = zip(*[full_set_train[0].samples[i] for i in train_idx])

    if args.sampling == "oversampling":
        train_idx = random_over_sampler(classes, train_idx, args.nview)
    elif args.sampling == "undersampling":
        train_idx = random_under_sampler(classes, train_idx, args.nview)

    # Get subsets
    test_set = torch.utils.data.Subset(full_set_val[0], test_idx)
    val_set = torch.utils.data.Subset(full_set_val[0], val_idx)
    train_set = torch.utils.data.Subset(full_set_train[0], train_idx)

    # Generate loaders
    test_loader = generate_loader(test_set, args.batch_size, args.workers)
    val_loader = generate_loader(val_set, args.batch_size, args.workers)
    train_loader = generate_loader(train_set, args.batch_size, args.workers)

    # load already trained model from single image classification
    # load_model(model, "for_rotation_net.pth.tar")

    # Track model in wandb
    wandb.init(project="RotationNet", config=args)

    # wandb.watch(model)

    train(model, criterion, optimizer, train_loader, val_loader, args)

    # Load best model before validating
    load_model(model, args.fname_best)

    # permute indices
    # indices = test_loader.dataset.indices
    # inds = random_permute_indices(np.array(indices), args.nview, True)
    # test_loader.dataset.indices = np.asarray(inds)
    # del indices
    # del inds

    val_statistics = validate(test_loader, model, criterion, args)

    log_summary(val_statistics, "val", test_loader.dataset.dataset.classes)
Esempio n. 3
0
def train_k_fold(model, criterion, optimizer, args):
    """
    Perform a k-fold cross validation on the given model.  Use args.fold to set the number of total folds and
    args.ntest_fold to set the number of folds dedicated for the validation. Keep in mind that each training step uses
    also an extra validation set for early stopping (the size of this subset is set via args.val_split_size).

    All the data are sent to wandb or logged on a text file

    Parameters
    ----------
    model : RotaitonNet model
    criterion : Pytorch criterion (CrossEntropy for RotationNet)
    optimizer : Pytorch optimizer (e.g. SGD)
    args : Input args from the parser

    Returns
    -------
    Nothing
    """
    # Save clean model to reload at each fold
    save_model(args.arch, model, optimizer, args.fname)

    # Get full train dataset
    full_set = generate_dataset(args.data, 'train')

    # Get folds
    folds = k_fold(full_set[0].samples, args.nview, True, args.fold)

    # List of top1 and top5 accuracies to get the average and std of the model performance
    top1 = []
    top5 = []

    # K-fold cross validation
    for i in range(args.fold):
        test_idx = []
        # Use ntest_folds folds for the test set
        for j in range(args.ntest_folds):
            test_idx.extend(folds[i])
            folds = np.delete(folds, i, 0)

        # Use rest of the data for the train set
        train_idx = np.hstack(folds)
        val_idx, train_idx = train_test_split([full_set[0].samples[i] for i in train_idx], train_idx, args.nview,
                                              args.val_split_size, True)

        # Get subsets
        test_set = torch.utils.data.Subset(full_set[0], test_idx)
        val_set = torch.utils.data.Subset(full_set[0], val_idx)
        train_set = torch.utils.data.Subset(full_set[0], train_idx)

        # Generate loaders
        test_loader = generate_loader(test_set, args.batch_size, args.workers)
        val_loader = generate_loader(val_set, args.batch_size, args.workers)
        train_loader = generate_loader(train_set, args.batch_size, args.workers)

        logger.debug("Start train on fold {}/{}".format(i, args.fold))

        # Track model in wandb
        wandb.init(project="RotationNet", name="Fold " + str(i), config=args, reinit=True)

        # The model can be analyzed only once
        # if i == 0:
        #    wandb.watch(model)

        train(model, criterion, optimizer, train_loader, val_loader, args)

        # Load best model before validating
        load_model(model, args.fname_best)

        val_statistics = validate(test_loader, model, criterion, args)
        log_summary(val_statistics, "val", test_loader.dataset.dataset.classes)

        # Load fresh model for next train
        load_model(model, args.fname)

    logger.info('Val prec@1 {top1:.3f} +- {std1:.3f} \t'
                'Val prec@5 {top5:.3f} +- {std5:.3f} \t'.format(top1=np.mean(top1), std1=np.std(top1),
                                                                top5=np.mean(top5), std5=np.std(top5)))
Esempio n. 4
0
def train_hold_out_aligned(model, criterion, optimizer, args):
    """
    Perform a train with validation train split on the given model.  Use args.val_split_size to set the percentage of
    data for the validation set. Keep in mind the two validation sets are genereted. One for early stopping and one to
    evaluate the model.

    All the data are sent to wandb or logged on a text file

    Parameters
    ----------
    model : RotaitonNet model
    criterion : Pytorch criterion (CrossEntropy for RotationNet)
    optimizer : Pytorch optimizer (e.g. SGD)
    args : Input args from the parser

    Returns
    -------
    Nothing
    """

    # create one element tuple to be consistent with ImageFolder dataset of Pytorch
    full_set_train = (AlignedDataset(args.data_aligned, 'train', []),)
    # validation data is on normal dataset

    full_set_val = generate_dataset(args.data, 'train')
    # full_set_val = (AlignedDataset(args.data_aligned, 'train', []),)
    # Get test train split. The test set here is intended as validation set but because we need also a validation set
    # for the early stopping we call it test
    test_idx, train_idx = train_test_split(full_set_train[0].samples, range(len(full_set_train[0].samples)),
                                           args.nview,
                                           args.val_split_size, True)
    # Get val train split
    val_idx, train_idx = train_test_split([full_set_train[0].samples[i] for i in train_idx], train_idx, args.nview,
                                          args.val_split_size, True)

    _, classes = zip(*[full_set_train[0].samples[i] for i in train_idx])

    # Get subsets
    test_set = torch.utils.data.Subset(full_set_val[0], test_idx)
    val_set = torch.utils.data.Subset(full_set_val[0], val_idx)
    train_set = torch.utils.data.Subset(full_set_train[0], train_idx)

    # Generate loaders
    test_loader = generate_loader(test_set, args.batch_size, args.workers)
    val_loader = generate_loader(val_set, args.batch_size, args.workers)
    train_loader = generate_loader(train_set, args.batch_size, args.workers)

    # load already trained model from single image classification
    # load_model(model, "for_rotation_net.pth.tar")

    # Track model in wandb
    wandb.init(project="RotationNet", config=args)

    # wandb.watch(model)

    train(model, criterion, optimizer, train_loader, val_loader, args)

    # Load best model before validating
    load_model(model, args.fname_best)

    # permute indices
    # indices = test_loader.dataset.indices
    # inds = random_permute_indices(np.array(indices), args.nview, True)
    # test_loader.dataset.indices = np.asarray(inds)
    # del indices
    # del inds

    val_statistics = validate(test_loader, model, criterion, args)

    log_summary(val_statistics, "val", test_loader.dataset.dataset.classes)
Esempio n. 5
0
def main():
    args = parser.parse_args()
    torch.manual_seed(0)
    np.random.seed(0)

    # Set the cuda device
    if torch.cuda.is_available():
        device = torch.device("cuda:0")
        torch.cuda.set_device(device)
    else:
        device = torch.device("cpu")

    if args.net_version == 1:
        from view_net import Model
    else:
        from view_net2 import Model
    # Initialize an OpenGL perspective camera.
    cameras = OpenGLPerspectiveCameras(device=device)

    # To blend the 100 faces we set a few parameters which control the opacity and the sharpness of
    # edges. Refer to blending.py for more details.
    # blend_params = BlendParams(sigma=1e-4, gamma=1e-4)
    # We will also create a phong renderer. This is simpler and only needs to render one face per pixel.
    raster_settings = RasterizationSettings(
        image_size=224,
        blur_radius=0.0,  # np.log(1. / 1e-4 - 1.) * blend_params.sigma,
        faces_per_pixel=args.faces_per_pixel,  # 100
    )

    # We can add a point light in front of the object.
    # lights = PointLights(device=device)
    # lights = DirectionalLights(device=device, direction=self.camera_position)
    phong_renderer = MeshRenderer(
        rasterizer=MeshRasterizer(cameras=cameras,
                                  raster_settings=raster_settings),
        shader=HardFlatShader(device=device,
                              cameras=cameras)  # , lights=lights)
    )

    dataset = ClassificationData(args.data, "train", device)

    test_idx, train_idx = dataset.train_test_split(dataset.paths,
                                                   range(len(dataset)), 20,
                                                   True)
    val_idx, train_idx = dataset.train_test_split(
        [dataset.paths[i] for i in train_idx], train_idx, 20, True)

    test_set = torch.utils.data.Subset(dataset, test_idx)
    val_set = torch.utils.data.Subset(dataset, val_idx)
    train_set = torch.utils.data.Subset(dataset, train_idx)

    train_loader = DataLoader(train_set,
                              batch_size=args.batch_size // args.nviews,
                              shuffle=False,
                              num_workers=0,
                              pin_memory=True,
                              drop_last=True,
                              collate_fn=my_collate)
    val_loader = DataLoader(val_set,
                            batch_size=args.batch_size // args.nviews,
                            shuffle=False,
                            num_workers=1,
                            pin_memory=True,
                            drop_last=True,
                            collate_fn=my_collate)
    test_loader = DataLoader(test_set,
                             batch_size=args.batch_size // args.nviews,
                             shuffle=False,
                             num_workers=1,
                             pin_memory=True,
                             drop_last=True,
                             collate_fn=my_collate)

    model = Model(device, phong_renderer, dataset.nclasses, args)
    args.num_classes = dataset.nclasses
    # Multi GPUs
    if torch.cuda.device_count() > 1:
        model = torch.nn.DataParallel(model)
    model = model.to(device=device)

    optimizer = Adam(
        [
            {
                'params': model.camera_position,
                'lr': args.learning_rate_camera
            },
            # {'params': model.light_position, 'lr': args.learning_rate_camera},
            {
                'params': model.net_1.parameters()
            },
            {
                'params': model.net_2.parameters()
            }
        ],
        lr=args.learning_rate,
        weight_decay=args.weight_decay)

    criterion = nn.CrossEntropyLoss().to(device=device)

    wandb.init(project="views_net", config=args)

    args.fname_best = 'views_net{}_model_best{}.pth.tar'.format(
        args.nviews,
        datetime.now().strftime("%d_%b_%Y_%H_%M_%S"))
    args.device = device

    args.obj_path = train_set.dataset.paths[0][0]

    train(model, criterion, optimizer, train_loader, val_loader, args)

    load_model(model, args.fname_best)

    val_statistics = validate(test_loader, model, criterion, device)

    log_summary(val_statistics, "val", test_loader.dataset.dataset.classes)
Esempio n. 6
0
 def plot_summary(self, phase, classes):
     #self.statistics.compute(self.num_classes)
     log_summary(self.statistics, phase, classes)