def __init__(self, exp_dict, labelset, writer=None):
     """ Constructor
     Args:
         model: architecture to train
         self.exp_dict: reference to dictionary with the global state of the application
     """
     super().__init__()
     self.model = get_backbone(exp_dict).cuda()
     self.exp_dict = exp_dict
     self.ngpu = self.exp_dict["ngpu"]
     self.devices = list(range(self.ngpu))
     self.beta = self.exp_dict["beta"]
     self.writer = writer
     self.labelset = labelset
     self.is_categorical = {}
     self.classifiers = {}
     self.optimizers = {}
     if self.exp_dict["hierarchical"]:
         z_dim = 2 * exp_dict["z_dim"]
     else:
         z_dim = exp_dict["z_dim"]
     for attribute in labelset.keys():
         categorical = len(labelset[attribute]) > 1
         self.is_categorical[attribute] = categorical
         if categorical:
             nclasses = len(labelset[attribute])
         else:
             nclasses = 1
         linear = torch.nn.Linear(z_dim, nclasses).cuda()
         mlp = MLP(z_dim, nclasses, 2 * z_dim, 3).cuda()
         optimizer_linear = torch.optim.Adam(linear.parameters(),
                                             lr=exp_dict["lr"])
         optimizer_mlp = torch.optim.Adam(mlp.parameters(),
                                          lr=exp_dict["lr"])
         self.classifiers["%s_linear" % attribute] = linear
         self.optimizers["%s_linear" % attribute] = optimizer_linear
         self.classifiers["%s_mlp" % attribute] = mlp
         self.optimizers["%s_mlp" % attribute] = optimizer_mlp
     self.optimizer = torch.optim.Adam(self.model.parameters(),
                                       betas=(0.9, 0.999),
                                       lr=self.exp_dict["lr"])
     if self.exp_dict["amp"] > 0:
         self.model, self.optimizer = amp.initialize(self.model,
                                                     self.optimizer,
                                                     opt_level="O%d" %
                                                     exp_dict["amp"])
    def __init__(self, exp_dict):
        super().__init__()
        self.exp_dict = exp_dict
        self.backbone = get_backbone(exp_dict)
        self.backbone.cuda()
        self.min_lr = exp_dict["lr"] * exp_dict["min_lr_decay"]
        self.optimizer = torch.optim.Adam(self.backbone.parameters(),
                                          lr=exp_dict['lr'],
                                          weight_decay=1e-4)
        self.scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(
            self.optimizer,
            mode='min',
            factor=0.1,
            patience=10,
            min_lr=self.min_lr / 100,
            verbose=True)
        if self.exp_dict["amp"] > 0:
            self.scaler = amp.GradScaler()

        pretrained_weights_folder = self.exp_dict.get(
            "pretrained_weights_folder", None)
        if pretrained_weights_folder is not None:
            loaded = False
            all_exps = os.listdir(pretrained_weights_folder)
            for exp in all_exps:
                if exp == "deleted":
                    continue
                exp_dict = hu.load_json(
                    join(pretrained_weights_folder, exp, 'exp_dict.json'))
                if exp_dict["seed"] == self.exp_dict["seed"] and \
                        exp_dict["dataset"]["augmentation"] == self.exp_dict["dataset"]["augmentation"] and \
                        exp_dict["dataset"]["task"] == self.exp_dict["dataset"]["task"] and \
                        exp_dict["backbone"]["name"] == self.exp_dict["backbone"]["name"]:
                    try:
                        state = torch.load(
                            join(pretrained_weights_folder, exp, 'model.pth'))
                        self.set_state_dict(state)
                        loaded = True
                        break
                    except Exception as e:
                        print(e)
            if not loaded:
                raise RuntimeError(
                    "No matching pre-trained weights were found")
Esempio n. 3
0
 def __init__(self, num_class, base_net='resnet50', transfer_loss='mmd', use_bottleneck=True, bottleneck_width=256, max_iter=1000, **kwargs):
     super(TransferNet, self).__init__()
     self.num_class = num_class
     self.base_network = backbones.get_backbone(base_net)
     self.use_bottleneck = use_bottleneck
     self.transfer_loss = transfer_loss
     if self.use_bottleneck:
         bottleneck_list = [
             nn.Linear(self.base_network.output_num(), bottleneck_width),
             nn.ReLU()
         ]
         self.bottleneck_layer = nn.Sequential(*bottleneck_list)
         feature_dim = bottleneck_width
     else:
         feature_dim = self.base_network.output_num()
     
     self.classifier_layer = nn.Linear(feature_dim, num_class)
     transfer_loss_args = {
         "loss_type": self.transfer_loss,
         "max_iter": max_iter,
         "num_class": num_class
     }
     self.adapt_loss = TransferLoss(**transfer_loss_args)
     self.criterion = torch.nn.CrossEntropyLoss()
Esempio n. 4
0
def main(**kwargs):
    test_path = kwargs.get('test_data_path')
    submission_file_path = kwargs.get('submission_file_path')
    idlookup_file_path = kwargs.get('idlookup_file_path')
    checkpoint_path = kwargs.get('checkpoint_path')

    backbone_name = kwargs.get('backbone')

    num_classes = kwargs.get('num_classes')
    device = kwargs.get('device')

    batch_size = kwargs.get('batch_size')

    # TODO give trained mean and std
    mean = 0
    std = 1

    original_img_size = 96
    submission_df = pd.read_csv(submission_file_path)
    idlookup_df = pd.read_csv(idlookup_file_path)

    backbone = get_backbone(backbone_name)

    model = FacialKeypointsDetector(backbone,
                                    device=device,
                                    num_classes=num_classes)

    transform = transforms.Compose([
        transforms.ToPILImage(),
        transforms.Resize(model.get_input_size()),
        transforms.ToTensor(),
        transforms.Normalize(mean, std)
    ])

    dataset = get_test_dataset(root_path=test_path, transform=transform)

    dl = torch.utils.data.DataLoader(dataset,
                                     num_workers=4,
                                     batch_size=batch_size,
                                     pin_memory=True,
                                     collate_fn=custom_collate_fn)

    load_model(model, checkpoint_path)

    predictions = {}
    for imgs, img_ids in tqdm(dl, total=len(dl.dataset) // batch_size):
        # {img_id:{'loc1':pred}}
        preds = model.predict(imgs) * original_img_size
        preds = torch.clamp(preds, min=0, max=original_img_size)
        for img_idx, pred in zip(img_ids, preds.cpu().numpy().tolist()):
            predictions[img_idx] = {}
            for label, location in zip(labels, pred):
                predictions[img_idx][label] = location

    locations = []
    row_ids = []
    for s, lookup in zip(submission_df.iterrows(), idlookup_df.iterrows()):
        s = s[1]
        lookup = lookup[1]
        # RowId,Location
        s = json.loads(s.to_json())
        # RowId,ImageId,FeatureName,Location
        lookup = json.loads(lookup.to_json())
        img_idx = lookup['ImageId']
        feature = lookup['FeatureName']
        row_id = s['RowId']
        location = predictions[img_idx][feature]
        locations.append(location)
        row_ids.append(row_id)
    new_submission_df = pd.DataFrame(data={
        'RowId': row_ids,
        'Location': locations
    })
    submissin_dir_path = os.path.dirname(submission_file_path)
    new_submission_file_path = os.path.join(submissin_dir_path,
                                            'submission.csv')
    print(new_submission_df.head())
    new_submission_df.to_csv(new_submission_file_path, index=False, header=1)
Esempio n. 5
0
def Xnet(backbone_name='vgg16',
         input_shape=(None, None, 3),
         input_tensor=None,
         encoder_weights='imagenet',
         freeze_encoder=False,
         skip_connections='default',
         decoder_block_type='upsampling',
         decoder_filters=(256, 128, 64, 32, 16),
         decoder_use_batchnorm=True,
         n_upsample_blocks=5,
         upsample_rates=(2, 2, 2, 2, 2),
         classes=1,
         activation='sigmoid'):
    """
    Args:
        backbone_name: (str) look at list of available backbones.
        input_shape:  (tuple) dimensions of input data (H, W, C)
        input_tensor: keras tensor
        encoder_weights: one of `None` (random initialization),
            'imagenet' (pre-training on ImageNet),
            'dof' (pre-training on DoF)
        freeze_encoder: (bool) Set encoder layers weights as non-trainable. Useful for fine-tuning
        skip_connections: if 'default' is used take default skip connections,
            else provide a list of layer numbers or names starting from top of model
        decoder_block_type: (str) one of 'upsampling' and 'transpose' (look at blocks.py)
        decoder_filters: (int) number of convolution layer filters in decoder blocks
        decoder_use_batchnorm: (bool) if True add batch normalisation layer between `Conv2D` ad `Activation` layers
        n_upsample_blocks: (int) a number of upsampling blocks
        upsample_rates: (tuple of int) upsampling rates decoder blocks
        classes: (int) a number of classes for output
        activation: (str) one of keras activations for last model layer
    Returns:
        keras.models.Model instance
    """

    backbone = get_backbone(backbone_name,
                            input_shape=input_shape,
                            input_tensor=input_tensor,
                            weights=encoder_weights,
                            include_top=False)

    if skip_connections == 'default':
        skip_connections = DEFAULT_SKIP_CONNECTIONS[backbone_name]
    # n_upsample_blocks = len(skip_connections)

    model = build_xnet(backbone,
                       classes,
                       skip_connections,
                       decoder_filters=decoder_filters,
                       block_type=decoder_block_type,
                       activation=activation,
                       n_upsample_blocks=n_upsample_blocks,
                       upsample_rates=upsample_rates,
                       use_batchnorm=decoder_use_batchnorm)

    # lock encoder weights for fine-tuning
    if freeze_encoder:
        freeze_model(backbone)

    model.name = 'x-{}'.format(backbone_name)

    return model
def main(**kwargs):
    training_path = kwargs.get('training_data_path')
    checkpoint_path = kwargs.get('checkpoint_path')
    tensorboard_log_dir = kwargs.get('tensorboard_log_dir')
    if not os.path.isdir(checkpoint_path):
        os.mkdir(checkpoint_path)

    backbone_name = kwargs.get('backbone')
    criterion_name = kwargs.get('criterion').upper()
    optimizer_name = kwargs.get('optimizer').upper()
    scheduler = kwargs.get('scheduler',None)

    pretrained = kwargs.get('pretrained')
    num_classes = kwargs.get('num_classes')
    device = kwargs.get('device')

    batch_size = kwargs.get('batch_size')
    epochs = kwargs.get('epochs')
    hyperparameters = kwargs.get('hyperparameters',{})
    augmentations = kwargs.get('augmentations',{})
    verbose = kwargs.get('verbose')

    train_split = kwargs.get('train_split')
    nfolds = kwargs.get('nfolds')

    val_splits = [(1-train_split) / nfolds] * nfolds

    resume = kwargs.get('resume')
    only_weights = kwargs.get('only_weights')

    seed = hyperparameters.get('seed')

    random_jitter = augmentations.get('jitter',{})
    random_horizontal_flip = augmentations.get('horizontal_flip', 0.5)
    random_rotation = augmentations.get('rotation', 20)

    writer = SummaryWriter(log_dir=tensorboard_log_dir, flush_secs=20)

    if seed: seed_everything(seed)

    # TODO calculate mean and std
    mean = hyperparameters.get('mean',0)
    std = hyperparameters.get('std',1)

    splits = [train_split]+val_splits
    assert sum(splits) <= 1,"given splits must be lower or equal than 1"

    original_img_size = 96

    criterion = get_criterion(criterion_name)

    backbone = get_backbone(backbone_name, pretrained=pretrained)

    model = FacialKeypointsDetector(backbone, criterion=criterion,
        device=device, num_classes=num_classes)

    optimizer = get_optimizer(optimizer_name, model.parameters(),
        kwargs=hyperparameters.get('optimizer',{}))

    scaler = GradScaler()

    val_transforms = None
    val_target_transform = TargetTransform(original_img_size)

    train_transform = train_target_transform = None
    train_transforms = transforms.TrainTransforms(model.get_input_size(), original_img_size, 
        mean=mean, std=std, brightness=random_jitter.get('brightness'),
        contrast=random_jitter.get('contrast'), saturation=random_jitter.get('saturation'),
        hue=random_jitter.get('hue'), rotation_degree=random_rotation,
        hflip=random_horizontal_flip)

    val_transform = transforms.Compose([
        transforms.ToPILImage(),
        transforms.Resize(model.get_input_size()),
        transforms.ToTensor(),
        transforms.Normalize(mean,std)])

    train_dataset,*val_datasets = get_training_datasets(root_path=training_path,
        train_transforms=(train_transforms,train_transform,train_target_transform),
        val_transforms=(val_transforms,val_transform,val_target_transform),
        split_ratios=splits)

    val_dls = []
    train_dl = torch.utils.data.DataLoader(train_dataset,
        num_workers=4, batch_size=batch_size,
        pin_memory=True, collate_fn=custom_collate_fn, shuffle=True)

    for val_ds in val_datasets:
        val_dls.append( torch.utils.data.DataLoader(
            val_ds, batch_size=batch_size, num_workers=2) )

    current_epoch = 0
    best_loss = math.inf
    if resume:
        print(Fore.CYAN, f"loading checkpoint from {checkpoint_path}",Style.RESET_ALL)
        best_loss,current_epoch = load_checkpoint(model, optimizer, scheduler=scheduler,
            save_path=checkpoint_path, suffix='last', only_weights=only_weights)

    try:
        for epoch in range(current_epoch,epochs):
            training_loop(train_dl, model, epoch, epochs, optimizer, writer,scaler,
                scheduler=scheduler, verbose=verbose)

            val_losses = []
            for i,val_dl in enumerate(val_dls):
                val_loss = validation_loop(val_dl, model)
                val_losses.append(val_loss)
                print(Fore.LIGHTBLUE_EX, f"validation [{i+1}] loss:  {val_loss:.07f}",Style.RESET_ALL)
                writer.add_scalar(f'Loss/val_{i+1}', val_loss, epoch)

            mean_val_loss = sum(val_losses) / len(val_losses)
            print(Fore.LIGHTBLUE_EX, f"validation [mean] loss:  {mean_val_loss:.07f}",Style.RESET_ALL)
            writer.add_scalar(f'Loss/val_mean', mean_val_loss, epoch)
            writer.flush()
            if mean_val_loss < best_loss:
                best_loss = mean_val_loss
                print(Fore.CYAN, "saving best checkpoint...",Style.RESET_ALL)
                save_checkpoint(model,optimizer,epoch,best_loss,
                    scheduler=scheduler, suffix='best', save_path=checkpoint_path)

            print(Fore.CYAN, "saving last checkpoint...",Style.RESET_ALL)
            save_checkpoint(model,optimizer,epoch,best_loss,
                scheduler=scheduler, suffix='last', save_path=checkpoint_path)

    except KeyboardInterrupt:
        print(Fore.RED, "training interrupted with ctrl+c saving current state of the model",Style.RESET_ALL)
        save_checkpoint(model,optimizer,epoch,best_loss,
            scheduler=scheduler, suffix='last', save_path=checkpoint_path)
    writer.close()