riow1983 / vesuvius-challenge-ink-detection

0 stars 0 forks source link

Overview

https://www.kaggle.com/competitions/vesuvius-challenge-ink-detection

Results

552nd / 1249

Ideas

CV Folds

https://www.kaggle.com/code/yururoi/pytorch-unet-baseline-with-train-code?scriptVersionId=122620610&cellId=22

data_set = []
data_set.append(
    {
        "train_img": [img1, img2],
        "train_label": [img1_label, img2_label],
        "valid_img": [img3],
        "valid_label": [img3_label],
        "valid_mask": [img3_mask],
    }
)

data_set.append(
    {
        "train_img": [img1, img3],
        "train_label": [img1_label, img3_label],
        "valid_img": [img2],
        "valid_label": [img2_label],
        "valid_mask": [img2_mask],
    }
)

data_set.append(
    {
        "train_img": [img2, img3],
        "train_label": [img2_label, img3_label],
        "valid_img": [img1],
        "valid_label": [img1_label],
        "valid_mask": [img1_mask],
    }
)

2023-06-15

src/2-5d-segmentaion-baseline-trainingのEXP1とEXP2の結果比較:

[EXP 1]
-------- exp_info -----------------
best_th: 0.5, fbeta: 0.5089870965985367
Epoch 15 - avg_train_loss: 0.3655  avg_val_loss: 0.4501  time: 72s
Epoch 15 - avgScore: 0.5090
-------- exp_info -----------------
Epoch 15 - avg_train_loss: 0.3254  avg_val_loss: 0.6164  time: 62s
Epoch 15 - avgScore: 0.3941
best_th: 0.1, fbeta: 0.4037166002688188
-------- exp_info -----------------
Epoch 15 - avg_train_loss: 0.3638  avg_val_loss: 0.3804  time: 74s
Epoch 15 - avgScore: 0.4535
best_th: 0.5, fbeta: 0.5139692463216654

[EXP 2]
-------- exp_info -----------------
Epoch 45 - avg_train_loss: 0.1141  avg_val_loss: 0.5670  time: 70s
Epoch 45 - avgScore: 0.4945
best_th: 0.5, fbeta: 0.5518652693152954
-------- exp_info -----------------
Epoch 45 - avg_train_loss: 0.1026  avg_val_loss: 0.8426  time: 64s
Epoch 45 - avgScore: 0.3234
best_th: 0.15, fbeta: 0.40391082025522707
-------- exp_info -----------------
Epoch 45 - avg_train_loss: 0.1221  avg_val_loss: 0.4019  time: 70s
Epoch 45 - avgScore: 0.5515
best_th: 0.5, fbeta: 0.5769704817882036

反省点

Top solutions

[1] https://www.kaggle.com/competitions/vesuvius-challenge-ink-detection/discussion/417496
[2] https://www.kaggle.com/competitions/vesuvius-challenge-ink-detection/discussion/417255
[3] https://www.kaggle.com/competitions/vesuvius-challenge-ink-detection/discussion/417536
[4] https://www.kaggle.com/competitions/vesuvius-challenge-ink-detection/discussion/417779
[5] https://www.kaggle.com/competitions/vesuvius-challenge-ink-detection/discussion/417642
[6] https://www.kaggle.com/competitions/vesuvius-challenge-ink-detection/discussion/417274
[7] https://www.kaggle.com/competitions/vesuvius-challenge-ink-detection/discussion/417430
[8] https://www.kaggle.com/competitions/vesuvius-challenge-ink-detection/discussion/417383
[9] https://www.kaggle.com/competitions/vesuvius-challenge-ink-detection/discussion/417361
[10] https://www.kaggle.com/competitions/vesuvius-challenge-ink-detection/discussion/417363
[11] https://www.kaggle.com/competitions/vesuvius-challenge-ink-detection/discussion/417281

Q&A

https://www.kaggle.com/competitions/vesuvius-challenge-ink-detection/data

W&B

https://wandb.ai/riow1983/vesuvius-challenge-ink-detection/table?workspace=user-riow1983

Discussions

Notebooks

Documentations

GitHub

Papers

Snipets

[Ensemble models w/ TTA on parallel processing]

# Credit to https://www.kaggle.com/code/riow1983/2-5d-segmentaion-model-with-rotate-tta/notebook?scriptVersionId=133522169
class CustomModel(nn.Module):
    def __init__(self, cfg, weight=None):
        super().__init__()
        self.cfg = cfg

        self.encoder = smp.Unet(
            encoder_name=cfg.backbone, 
            encoder_weights=weight,
            in_channels=cfg.in_chans,
            classes=cfg.target_size,
            activation=None,
        )

    def forward(self, image):
        output = self.encoder(image)
        output = output.squeeze(-1)
        return output

def build_model(cfg, weight="imagenet"):
    print('model_name', cfg.model_name)
    print('backbone', cfg.backbone)

    model = CustomModel(cfg, weight)
    return model

class EnsembleModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.model = nn.ModuleList()
        for fold in [1, 2, 3]:
            _model = build_model(CFG, weight=None)
            model_path = f'/kaggle/input/{CFG.exp_name}/vesuvius-challenge-ink-detection-models/Unet_fold{fold}_best.pth'
            state = torch.load(model_path)['model']
            state = torch.load(model_path)['model']
            _model.load_state_dict(state)
            _model.eval()

            self.model.append(_model)

    def forward(self,x):
        output=[]
        for m in self.model:
            output.append(m(x))
        output=torch.stack(output, dim=0).mean(0)
        return output

model = EnsembleModel()
model = nn.DataParallel(model, device_ids=[0, 1])
model = model.cuda()

def TTA(x:tc.Tensor, model:nn.Module):
    #x.shape=(batch,c,h,w)
    if CFG.TTA:
        shape=x.shape
        x=[x,*[tc.rot90(x,k=i,dims=(-2,-1)) for i in range(1,4)]]
        x=tc.cat(x,dim=0)
        x=model(x)
        x=torch.sigmoid(x)
        x=x.reshape(4,shape[0],*shape[2:])
        x=[tc.rot90(x[i],k=-i,dims=(-2,-1)) for i in range(4)]
        x=tc.stack(x,dim=0)
        return x.mean(0)
    else :
        x=model(x)
        x=torch.sigmoid(x)
        return x

# Under an inference iteration:
    for step, (images) in tqdm(enumerate(test_loader), total=len(test_loader)):
        images = images.cuda()
        batch_size = images.size(0)

        with torch.no_grad():
            y_preds = TTA(images,model).cpu().numpy()

[Early stopping]

# Credit to: https://www.kaggle.com/code/yururoi/pytorch-unet-baseline-with-train-code?scriptVersionId=122620610&cellId=20
class EarlyStopping:
    def __init__(self, patience=7, verbose=False, delta=0, fold=""):
        self.patience = patience
        self.verbose = verbose
        self.counter = 0
        self.best_score = None
        self.early_stop = False
        self.val_loss_min = np.Inf
        self.delta = delta

    def __call__(self, val_loss, model):

        score = -val_loss

        if self.best_score is None:
            self.best_score = score
            self.save_checkpoint(val_loss, model)
        elif score < self.best_score + self.delta:
            self.counter += 1
            logger.info(f"EarlyStopping counter: {self.counter} out of {self.patience}")
            if self.counter >= self.patience:
                self.early_stop = True
        else:
            self.best_score = score
            self.save_checkpoint(val_loss, model)
            self.counter = 0

    def save_checkpoint(self, val_loss, model):
        """Saves model when validation loss decrease."""
        if self.verbose:
            logger.info(
                f"Validation loss decreased ({self.val_loss_min:.6f} --> {val_loss:.6f}).  Saving model ..."
            )
        torch.save(model.state_dict(), CP_DIR / f"{HOST}_{NB}_checkpoint_{fold}.pt")
        self.val_loss_min = val_loss