def main(args):
    # 1. prepare data & models
    train_transforms = transforms.Compose([
        ScaleMinSideToSize((CROP_SIZE, CROP_SIZE)),
        CropCenter(CROP_SIZE),
        TransformByKeys(transforms.ToPILImage(), ("image", )),
        TransformByKeys(transforms.ToTensor(), ("image", )),
        TransformByKeys(
            transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                 std=[0.229, 0.224, 0.225]),
            ("image", ),
        ),
    ])

    print("Creating model...")
    device = torch.device("cuda: 0") if args.gpu else torch.device("cpu")
    model = models.resnet50(pretrained=False)
    model.fc = nn.Linear(model.fc.in_features, 2 * NUM_PTS, bias=True)
    model.to(device)

    test_dataset = ThousandLandmarksDataset(
        os.path.join(args.data, "test"),
        train_transforms,
        split="test",
        debug=args.debug,
    )
    test_dataloader = data.DataLoader(
        test_dataset,
        batch_size=args.batch_size,
        num_workers=4,
        pin_memory=True,
        shuffle=False,
        drop_last=False,
    )

    with open(f"{args.name}_best.pth", "rb") as fp:
        best_state_dict = torch.load(fp, map_location="cpu")
        model.load_state_dict(best_state_dict)

    test_predictions = predict(model, test_dataloader, device)

    with open(f"{args.name}_test_predictions.pkl", "wb") as fp:
        pickle.dump(
            {
                "image_names": test_dataset.image_names,
                "landmarks": test_predictions
            }, fp)

    create_submission(args.data, test_predictions, f"{args.name}_submit.csv")
Example #2
0
def main(args):
    # 1. Prepare data & models

    # individual transformations for validation and test data did not give not reduce MSE-loss
    train_transforms = transforms.Compose([
        ScaleMinSideToSize((SCALE_SIZE, SCALE_SIZE)),
        CropCenter(CROP_SIZE),
        TransformByKeys(transforms.ToPILImage(), ("image", )),
        TransformByKeys(transforms.Grayscale(3),
                        ("image", )),  # grayscale image for best score
        TransformByKeys(transforms.ColorJitter(brightness=[0.8, 1.2]),
                        ("image", )),  # random choose brightness in range
        TransformByKeys(transforms.ToTensor(), ("image", )),
        TransformByKeys(
            transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]),
            ("image", )),
    ])

    print('----------------------------------------------------------')
    print('Script for Kaggle competition "Thousand Facial Landmarks"')
    print('----------------------------------------------------------')

    print('Reading data...')
    train_dataset = ThousandLandmarksDataset(os.path.join(args.data, 'train'),
                                             train_transforms,
                                             split="train")
    train_dataloader = data.DataLoader(train_dataset,
                                       batch_size=args.batch_size,
                                       num_workers=0,
                                       pin_memory=True,
                                       shuffle=True,
                                       drop_last=True)
    val_dataset = ThousandLandmarksDataset(os.path.join(args.data, 'train'),
                                           train_transforms,
                                           split="val")
    val_dataloader = data.DataLoader(val_dataset,
                                     batch_size=args.batch_size,
                                     num_workers=0,
                                     pin_memory=True,
                                     shuffle=False,
                                     drop_last=False)

    print("Creating model...")
    device = torch.device(
        "cuda: 0"
    )  # default GPU device, because train this net on CPU is eternity :)

    # this network was selected through experimentation from the list: resnet18, resnet34, resnext50, resnext101, alexnet, InceptionV3, InceptionV4 etc
    model = models.resnext50_32x4d(pretrained=True)

    # adding new layers with regularization (dropout or batchnorm) did not give effect
    model.fc = nn.Linear(model.fc.in_features, 2 * NUM_PTS, bias=True)
    model.to(device)

    optimizer = optim.Adam(model.parameters(),
                           lr=args.learning_rate,
                           amsgrad=True)
    loss_fn = fnn.mse_loss

    # 2. Train & validate
    print("Ready for training...")
    best_val_loss = np.inf
    for epoch in range(args.epochs):
        train_loss = train(model,
                           train_dataloader,
                           loss_fn,
                           optimizer,
                           device=device)
        val_loss = validate(model, val_dataloader, loss_fn, device=device)
        print("Epoch #{:2}:\ttrain loss: {:5.2}\tval loss: {:5.2}".format(
            epoch, train_loss, val_loss))
        if val_loss < best_val_loss:
            best_val_loss = val_loss
            with open(f"{args.name}_best.pth", "wb") as fp:
                torch.save(model.state_dict(), fp)

    # 3. Predict
    test_dataset = ThousandLandmarksDataset(os.path.join(args.data, 'test'),
                                            train_transforms,
                                            split="test")
    test_dataloader = data.DataLoader(test_dataset,
                                      batch_size=args.batch_size,
                                      num_workers=0,
                                      pin_memory=True,
                                      shuffle=False,
                                      drop_last=False)

    with open(f"{args.name}_best.pth", "rb") as fp:
        best_state_dict = torch.load(fp, map_location="cpu")
        model.load_state_dict(best_state_dict)

    test_predictions = predict(model, test_dataloader, device)
    with open(f"{args.name}_test_predictions.pkl", "wb") as fp:
        pickle.dump(
            {
                "image_names": test_dataset.image_names,
                "landmarks": test_predictions
            }, fp)

    create_submission(args.data, test_predictions, f"{args.name}_submit.csv")
Example #3
0
def main(args):
    os.makedirs("runs", exist_ok=True)

    # 1. prepare data & models
    train_transforms = transforms.Compose([
        ScaleMinSideToSize((CROP_SIZE, CROP_SIZE)),
        CropCenter(CROP_SIZE),
        TransformByKeys(transforms.ToPILImage(), ("image", )),
        TransformByKeys(transforms.ToTensor(), ("image", )),
        TransformByKeys(
            transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.25, 0.25, 0.25]),
            ("image", )),
    ])

    print("Reading data...")
    train_dataset = ThousandLandmarksDataset(os.path.join(args.data, "train"),
                                             train_transforms,
                                             split="train")
    train_dataloader = DataLoader(train_dataset,
                                  batch_size=args.batch_size,
                                  num_workers=4,
                                  pin_memory=True,
                                  shuffle=True,
                                  drop_last=True)
    val_dataset = ThousandLandmarksDataset(os.path.join(args.data, "train"),
                                           train_transforms,
                                           split="val")
    val_dataloader = DataLoader(val_dataset,
                                batch_size=args.batch_size,
                                num_workers=4,
                                pin_memory=True,
                                shuffle=False,
                                drop_last=False)

    device = torch.device(
        "cuda:0"
    )  # if args.gpu and torch.cuda.is_available() else torch.device("cpu")
    print("Creating model...")
    model = models.resnet18(pretrained=True)
    model.requires_grad_(False)

    model.fc = nn.Linear(model.fc.in_features, 2 * NUM_PTS, bias=True)
    model.fc.requires_grad_(True)

    model.to(device)

    optimizer = optim.Adam(model.parameters(),
                           lr=args.learning_rate,
                           amsgrad=True)
    loss_fn = fnn.mse_loss
    time.sleep(60)
    # 2. train & validate
    print("Ready for training...")
    best_val_loss = np.inf
    for epoch in range(args.epochs):
        train_loss = train(model,
                           train_dataloader,
                           loss_fn,
                           optimizer,
                           device=device)
        val_loss = validate(model, val_dataloader, loss_fn, device=device)
        print("Epoch #{:2}:\ttrain loss: {:5.2}\tval loss: {:5.2}".format(
            epoch, train_loss, val_loss))
        if val_loss < best_val_loss:
            best_val_loss = val_loss
            with open(os.path.join("runs", f"{args.name}_best.pth"),
                      "wb") as fp:
                torch.save(model.state_dict(), fp)

    # 3. predict
    test_dataset = ThousandLandmarksDataset(os.path.join(args.data, "test"),
                                            train_transforms,
                                            split="test")
    test_dataloader = DataLoader(test_dataset,
                                 batch_size=args.batch_size,
                                 num_workers=4,
                                 pin_memory=True,
                                 shuffle=False,
                                 drop_last=False)

    with open(os.path.join("runs", f"{args.name}_best.pth"), "rb") as fp:
        best_state_dict = torch.load(fp, map_location="cpu")
        model.load_state_dict(best_state_dict)

    test_predictions = predict(model, test_dataloader, device)
    with open(os.path.join("runs", f"{args.name}_test_predictions.pkl"),
              "wb") as fp:
        pickle.dump(
            {
                "image_names": test_dataset.image_names,
                "landmarks": test_predictions
            }, fp)

    create_submission(args.data, test_predictions,
                      os.path.join("runs", f"{args.name}_submit.csv"))
Example #4
0
def main(args):
    os.makedirs("runs", exist_ok=True)

    # 1. prepare data & models
    train_transforms = transforms.Compose([
        ScaleMinSideToSize((CROP_SIZE, CROP_SIZE)),
        CropCenter(CROP_SIZE),
        TransformByKeys(transforms.ToPILImage(), ("image", )),
        TransformByKeys(transforms.ToTensor(), ("image", )),
        TransformByKeys(
            transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.25, 0.25, 0.25]),
            ("image", )),
    ])

    print("Reading data...")
    train_dataset = ThousandLandmarksDataset(os.path.join(args.data, "train"),
                                             train_transforms,
                                             split="train")
    train_dataloader = DataLoader(train_dataset,
                                  batch_size=args.batch_size,
                                  num_workers=4,
                                  pin_memory=True,
                                  shuffle=True,
                                  drop_last=True)
    val_dataset = ThousandLandmarksDataset(os.path.join(args.data, "train"),
                                           train_transforms,
                                           split="val")
    val_dataloader = DataLoader(val_dataset,
                                batch_size=args.batch_size,
                                num_workers=4,
                                pin_memory=True,
                                shuffle=False,
                                drop_last=False)

    device = torch.device("cuda") if args.gpu and torch.cuda.is_available(
    ) else torch.device("cpu")

    print("Creating model...")
    model = models.resnet50(pretrained=True)
    model.requires_grad_(False)

    model.fc = nn.Linear(model.fc.in_features, 2 * NUM_PTS, bias=True)
    model.fc.requires_grad_(True)

    model.to(device)

    optimizer = optim.Adam(model.parameters(),
                           lr=args.learning_rate,
                           amsgrad=True)
    loss_fn = fnn.mse_loss

    name = './runs/resnet50_ep14_loss17.76.pth'
    with open(f"{name}", "rb") as fp:
        best_state_dict = torch.load(fp, map_location="cpu")
        model.load_state_dict(best_state_dict)

    for param in model.parameters():
        param.requires_grad = False
        #
        # train only head
        model.fc.weight.requires_grad = True
        model.fc.bias.requires_grad = True
        #
        # train layer4
    for param in model.layer4.parameters():
        param.requires_grad = True

    trainer = Trainer(model, train_dataloader, val_dataloader)
    trainer.start(5, 11)
    '''
Example #5
0
def main(args):
    os.makedirs("runs", exist_ok=True)

    # 1. prepare data & models
    # train_transforms = transforms.Compose([
    #     ScaleMinSideToSize((CROP_SIZE, CROP_SIZE)),
    #     CropCenter(CROP_SIZE),
    #     TransformByKeys(transforms.ToPILImage(), ("image",)),
    #     TransformByKeys(transforms.ToTensor(), ("image",)),
    #     TransformByKeys(transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ("image",)), # (0.485, 0.456, 0.406), (0.229, 0.224, 0.225)
    # ])

    crop_size = (224, 224)
    train_transforms = transforms.Compose([
        CropFrame(9),
        ScaleMinSideToSize((CROP_SIZE, CROP_SIZE)),
        CropCenter(CROP_SIZE),
        FlipHorizontal(),
        Rotator(30),
        # CropRectangle(crop_size),
        ChangeBrightnessContrast(alpha_std=0.05, beta_std=10),
        TransformByKeys(transforms.ToPILImage(), ("image", )),
        TransformByKeys(transforms.ToTensor(), ("image", )),
        TransformByKeys(
            transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                 std=[0.229, 0.224, 0.225]), ("image", )),
    ])

    valid_transforms = transforms.Compose([
        CropFrame(9),
        ScaleMinSideToSize((CROP_SIZE, CROP_SIZE)),
        CropCenter(CROP_SIZE),
        # CropRectangle(crop_size),
        TransformByKeys(transforms.ToPILImage(), ("image", )),
        TransformByKeys(transforms.ToTensor(), ("image", )),
        TransformByKeys(
            transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                 std=[0.229, 0.224, 0.225]), ("image", )),
    ])
    print("Reading data...")
    train_dataset = ThousandLandmarksDataset(os.path.join(args.data, "train"),
                                             train_transforms,
                                             split="train")
    train_dataloader = DataLoader(train_dataset,
                                  batch_size=args.batch_size,
                                  num_workers=4,
                                  pin_memory=True,
                                  shuffle=True,
                                  drop_last=True)
    val_dataset = ThousandLandmarksDataset(os.path.join(args.data, "train"),
                                           valid_transforms,
                                           split="val")
    val_dataloader = DataLoader(val_dataset,
                                batch_size=args.batch_size,
                                num_workers=4,
                                pin_memory=True,
                                shuffle=False,
                                drop_last=False)

    device = torch.device("cuda:0") if args.gpu and torch.cuda.is_available(
    ) else torch.device("cpu")

    print("Creating model...")
    # model = models.resnext50_32x4d(pretrained=True)
    # model.fc = nn.Linear(model.fc.in_features, 2 * NUM_PTS, bias=True)
    # checkpoint = torch.load("./runs/baseline_full3_best.pth", map_location='cpu')
    # model.load_state_dict(checkpoint, strict=True)
    model = RESNEXT_steroid()
    model.to(device)
    for p in model.base_net.parameters():
        p.requires_grad = False
    # model.base_net[8].requires_grad = True
    for p in model.fc.parameters():
        p.requires_grad = True
    for p in model.linear7.parameters():
        p.requires_grad = True
    for p in model.attention.parameters():
        p.requires_grad = True
    for p in model.linear1.parameters():
        p.requires_grad = True
    # model.to(device)

    optimizer = optim.Adam(model.parameters(),
                           lr=args.learning_rate,
                           amsgrad=True)
    # criterion = AdaptiveWingLoss()
    # criterion = torch.nn.MSELoss(size_average=True)
    # loss_fn = fnn.mse_loss
    criterion = fnn.l1_loss
    lr_scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer,
                                                        mode='min',
                                                        factor=1 / np.sqrt(10),
                                                        patience=4,
                                                        verbose=True,
                                                        threshold=0.01,
                                                        threshold_mode='abs',
                                                        cooldown=0,
                                                        min_lr=1e-6,
                                                        eps=1e-08)

    # 2. train & validate
    print("Ready for training...")
    best_val_loss = np.inf
    for epoch in range(args.epochs):
        train_loss = train(model,
                           train_dataloader,
                           criterion,
                           optimizer,
                           device=device)
        val_loss, mse_loss = validate(model,
                                      val_dataloader,
                                      criterion,
                                      device=device)
        lr_scheduler.step(val_loss)
        print(
            "Epoch #{:2}:\ttrain loss: {:5.2}\tval loss: {:5.2}\tmse loss: {:5.2}"
            .format(epoch, train_loss, val_loss, mse_loss))
        if val_loss < best_val_loss:
            best_val_loss = val_loss
            with open(os.path.join("runs", f"{args.name}_best.pth"),
                      "wb") as fp:
                torch.save(model.state_dict(), fp)

    # 3. predict
    test_dataset = ThousandLandmarksDataset(os.path.join(args.data, "test"),
                                            train_transforms,
                                            split="test")
    test_dataloader = DataLoader(test_dataset,
                                 batch_size=args.batch_size,
                                 num_workers=4,
                                 pin_memory=True,
                                 shuffle=False,
                                 drop_last=False)

    with open(os.path.join("runs", f"{args.name}_best.pth"), "rb") as fp:
        best_state_dict = torch.load(fp, map_location="cpu")
        model.load_state_dict(best_state_dict)

    test_predictions = predict(model, test_dataloader, device)
    with open(os.path.join("runs", f"{args.name}_test_predictions.pkl"),
              "wb") as fp:
        pickle.dump(
            {
                "image_names": test_dataset.image_names,
                "landmarks": test_predictions
            }, fp)

    create_submission(args.data, test_predictions,
                      os.path.join("runs", f"{args.name}_submit.csv"))
Example #6
0
def main(args):
    # 1. prepare data & models
    train_transforms = transforms.Compose([
        ScaleMinSideToSize((CROP_SIZE, CROP_SIZE)),
        CropCenter(CROP_SIZE),
        TransformByKeys(transforms.ToPILImage(), ("image", )),
        TransformByKeys(transforms.ToTensor(), ("image", )),
        TransformByKeys(
            transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                 std=[0.229, 0.224, 0.225]),
            ("image", ),
        ),
    ])

    print("Reading data...")
    train_dataset = ThousandLandmarksDataset(
        os.path.join(args.data, "train"),
        train_transforms,
        split="train",
        debug=args.debug,
    )
    train_dataloader = data.DataLoader(
        train_dataset,
        batch_size=args.batch_size,
        num_workers=4,
        pin_memory=True,
        shuffle=True,
        drop_last=True,
    )
    val_dataset = ThousandLandmarksDataset(
        os.path.join(args.data, "train"),
        train_transforms,
        split="val",
        debug=args.debug,
    )
    val_dataloader = data.DataLoader(
        val_dataset,
        batch_size=args.batch_size,
        num_workers=4,
        pin_memory=True,
        shuffle=False,
        drop_last=False,
    )

    print("Creating model...")
    device = torch.device("cuda: 0") if args.gpu else torch.device("cpu")
    model = models.resnet50(pretrained=True)
    model.fc = nn.Linear(model.fc.in_features, 2 * NUM_PTS, bias=True)
    model.to(device)

    for name, child in model.named_children():
        if name in ["fc"]:
            for param in child.parameters():
                param.requires_grad = True
        else:
            for param in child.parameters():
                param.requires_grad = False

    optimizer = optim.SGD(
        filter(lambda p: p.requires_grad, model.parameters()),
        lr=args.learning_rate,
        momentum=0.9,
        weight_decay=1e-04,
    )
    scheduler = optim.lr_scheduler.OneCycleLR(
        optimizer,
        max_lr=0.1,
        steps_per_epoch=len(train_dataloader),
        epochs=args.epochs)
    loss = L.WingLoss(width=10, curvature=2, reduction="mean")

    # 2. train & validate
    print("Ready for training...")
    for epoch in range(args.epochs):
        train_loss = train(model,
                           train_dataloader,
                           loss,
                           optimizer,
                           device=device,
                           scheduler=scheduler)
        val_loss = validate(model, val_dataloader, loss, device=device)
        print("Epoch #{:2}:\ttrain loss: {:6.3}\tval loss: {:6.3}".format(
            epoch, train_loss, val_loss))

    # 2.1. train continued

    for p in model.parameters():
        p.requires_grad = True

    optimizer = optim.AdamW(
        [
            {
                "params": model.conv1.parameters(),
                "lr": 1e-6
            },
            {
                "params": model.bn1.parameters(),
                "lr": 1e-6
            },
            {
                "params": model.relu.parameters(),
                "lr": 1e-5
            },
            {
                "params": model.maxpool.parameters(),
                "lr": 1e-5
            },
            {
                "params": model.layer1.parameters(),
                "lr": 1e-4
            },
            {
                "params": model.layer2.parameters(),
                "lr": 1e-4
            },
            {
                "params": model.layer3.parameters(),
                "lr": 1e-3
            },
            {
                "params": model.layer4.parameters(),
                "lr": 1e-3
            },
            {
                "params": model.avgpool.parameters(),
                "lr": 1e-2
            },
            {
                "params": model.fc.parameters(),
                "lr": 1e-2
            },
        ],
        lr=args.learning_rate,
        weight_decay=1e-06,
        amsgrad=True,
    )

    scheduler = optim.lr_scheduler.CosineAnnealingWarmRestarts(optimizer,
                                                               T_0=10,
                                                               T_mult=2)

    print("Ready for training again...")
    best_val_loss = np.inf
    for epoch in range(args.epochs):
        train_loss = train(model,
                           train_dataloader,
                           loss,
                           optimizer,
                           device=device,
                           scheduler=scheduler)
        val_loss = validate(model, val_dataloader, loss, device=device)
        print("Epoch #{:2}:\ttrain loss: {:6.3}\tval loss: {:6.3}".format(
            epoch, train_loss, val_loss))
        if val_loss < best_val_loss:
            best_val_loss = val_loss
            with open(f"{args.name}_best.pth", "wb") as fp:
                torch.save(model.state_dict(), fp)

    # 3. predict
    if not args.debug:
        test_dataset = ThousandLandmarksDataset(
            os.path.join(args.data, "test"),
            train_transforms,
            split="test",
            debug=args.debug,
        )
        test_dataloader = data.DataLoader(
            test_dataset,
            batch_size=args.batch_size,
            num_workers=4,
            pin_memory=True,
            shuffle=False,
            drop_last=False,
        )

        with open(f"submit/{args.name}_best.pth", "rb") as fp:
            best_state_dict = torch.load(fp, map_location="cpu")
            model.load_state_dict(best_state_dict)

        test_predictions = predict(model, test_dataloader, device)

        with open(f"submit/{args.name}_test_predictions.pkl", "wb") as fp:
            pickle.dump(
                {
                    "image_names": test_dataset.image_names,
                    "landmarks": test_predictions,
                },
                fp,
            )

        create_submission(args.data, test_predictions,
                          f"submit/{args.name}_submit.csv")