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")
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()
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)
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()