havakv / pycox

Survival analysis with PyTorch
BSD 2-Clause "Simplified" License
781 stars 180 forks source link

How to provide the rank_mat for training deepHit model using the fit_dataloader()? #79

Open Rajshreed opened 3 years ago

Rajshreed commented 3 years ago

Hi, I am trying to use the deephit model from pycox with img as input and I get following error regarding rank_mat, with in the fit_dataloader()

File "train.py", line 210, in main log = model.fit_dataloader(train_loader, epochs, callbacks, verbose, val_dataloader=val_loader) File "/opt/conda/envs/env/lib/python3.6/site-packages/torchtuples/base.py", line 229, in fit_dataloader self.batch_metrics = self.compute_metrics(data, self.metrics) File "/opt/conda/envs/env/lib/python3.6/site-packages/torchtuples/base.py", line 180, in compute_metrics return {name: metric(out, target) for name, metric in metrics.items()} File "/opt/conda/envs/env/lib/python3.6/site-packages/torchtuples/base.py", line 180, in return {name: metric(out, target) for name, metric in metrics.items()} File "/opt/conda/envs/env/lib/python3.6/site-packages/torch/nn/modules/module.py", line 727, in _call_impl result = self.forward(*input, **kwargs) TypeError: forward() missing 1 required positional argument: 'rank_mat'

havakv commented 3 years ago

You can take a look here at the pair_rank_mat function. For each batch, you need to call that function on your target (duration and event) as numpy arrays.

If you have problems making this work, you can post a code example and I'll try to help you from there

chingheng113 commented 2 years ago

Hi havakv, I encounter the same issue. Can you explain in more detail or provide an example code? Here is part of my code for your review:

def collate_fn(batch):
    """Stacks the entries of a nested tuple"""
    return tt.tuplefy(batch).stack()

model = DeepHitSingle(net, tt.optim.Adam(lr=1e-3, betas=(0.9, 0.999), eps=1e-08, weight_decay=5e-4, amsgrad=False),
                           duration_index=12)
dl_train = DataLoader(dataset_train, batch_size=12, shuffle=True, collate_fn=collate_fn)
model_log = model.fit_dataloader(dl_train, epochs=1)

Thank you!

pengcheng-wang2001 commented 1 year ago

Hi, I encounter the same issue with Rajshreed. The lack of rank_mat results in the error.

from pycox.models import loss as pycox_loss
from pycox.models.data import pair_rank_mat

def deephit_loss(scores, labels, censors):
    rank_mat = pair_rank_mat(labels.cpu().numpy(), censors.cpu().numpy())
    rank_mat = torch.from_numpy(rank_mat)
    rank_mat = rank_mat.to('cuda')
    loss_single = pycox_loss.DeepHitSingleLoss(0.2, 0.1)
    loss = loss_single(scores, labels, censors, rank_mat)
    return loss

I use a new loss function based on DeepHitSingleLoss and pair_rank_mat to solve this error. And also, I added loss=deephit_loss when creating the model.

model = DeepHitSingle(net, tt.optim.Adam, alpha=0.2, sigma=0.1, duration_index=labtrans.cuts, loss=deephit_loss)