Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The training and validation loss that is only zero throughout the training #28

Open
yvonneng996 opened this issue Aug 20, 2023 · 6 comments

Comments

@yvonneng996
Copy link

Hi all,
Could anyone help in this issue. Why when i use this cldice loss for training my vessel segmentation the loss is all zero throughout the training. What could have happened to this?
the cldice loss (1)

@yvonneng996
Copy link
Author

I use other loss function but it works well but why when i wanted to use this it shows zero for the training and validation loss.

@QuantumLuckin
Copy link

image
the same question for me.

@QuantumLuckin
Copy link

I use other loss function but it works well but why when i wanted to use this it shows zero for the training and validation loss.

I have found the problem, maybe it should be solved this way?

def soft_dice(y_true, y_pred):
    smooth = 1e-5
    intersection = torch.sum((y_true * y_pred))
    coeff = (2. * intersection + smooth) / (torch.sum(y_true) + torch.sum(y_pred) + smooth)
    return 1. - coeff


class soft_dice_cldice(nn.Module):
    def __init__(self, iter_=3, alpha=0.5, smooth=1e-5):
        super(soft_dice_cldice, self).__init__()
        self.iter = iter_
        self.smooth = smooth
        self.alpha = alpha

    def forward(self, y_true, y_pred):
        dice = soft_dice(y_true, y_pred)
        skel_pred = soft_skel(y_pred, self.iter)
        skel_true = soft_skel(y_true, self.iter)
        tprec = (torch.sum(torch.multiply(skel_pred, y_true)) + self.smooth) / (
                    torch.sum(skel_pred) + self.smooth)
        tsens = (torch.sum(torch.multiply(skel_true, y_pred)) + self.smooth) / (
                    torch.sum(skel_true) + self.smooth)
        cl_dice = 1. - 2.0 * (tprec * tsens) / (tprec + tsens)
        return (1.0 - self.alpha) * dice + self.alpha * cl_dice

Before the modification, the code restricted the channels from the second to the last, and usually the output only contained one channel, resulting in a loss of 0. However, after such modifications, the cldice still did not work well for my code.

@steveyoung30
Copy link

I use other loss function but it works well but why when i wanted to use this it shows zero for the training and validation loss.

I have found the problem, maybe it should be solved this way?

def soft_dice(y_true, y_pred):
    smooth = 1e-5
    intersection = torch.sum((y_true * y_pred))
    coeff = (2. * intersection + smooth) / (torch.sum(y_true) + torch.sum(y_pred) + smooth)
    return 1. - coeff


class soft_dice_cldice(nn.Module):
    def __init__(self, iter_=3, alpha=0.5, smooth=1e-5):
        super(soft_dice_cldice, self).__init__()
        self.iter = iter_
        self.smooth = smooth
        self.alpha = alpha

    def forward(self, y_true, y_pred):
        dice = soft_dice(y_true, y_pred)
        skel_pred = soft_skel(y_pred, self.iter)
        skel_true = soft_skel(y_true, self.iter)
        tprec = (torch.sum(torch.multiply(skel_pred, y_true)) + self.smooth) / (
                    torch.sum(skel_pred) + self.smooth)
        tsens = (torch.sum(torch.multiply(skel_true, y_pred)) + self.smooth) / (
                    torch.sum(skel_true) + self.smooth)
        cl_dice = 1. - 2.0 * (tprec * tsens) / (tprec + tsens)
        return (1.0 - self.alpha) * dice + self.alpha * cl_dice

Before the modification, the code restricted the channels from the second to the last, and usually the output only contained one channel, resulting in a loss of 0. However, after such modifications, the cldice still did not work well for my code.

Same doubt about operation of discarding the first channel. By the way, may I ask how you choose the num of iters for soft skeleton, program a new algorithm to calculate diameter of each data or just empirically choose one?

@QuantumLuckin
Copy link

I use other loss function but it works well but why when i wanted to use this it shows zero for the training and validation loss.

I have found the problem, maybe it should be solved this way?

def soft_dice(y_true, y_pred):
    smooth = 1e-5
    intersection = torch.sum((y_true * y_pred))
    coeff = (2. * intersection + smooth) / (torch.sum(y_true) + torch.sum(y_pred) + smooth)
    return 1. - coeff


class soft_dice_cldice(nn.Module):
    def __init__(self, iter_=3, alpha=0.5, smooth=1e-5):
        super(soft_dice_cldice, self).__init__()
        self.iter = iter_
        self.smooth = smooth
        self.alpha = alpha

    def forward(self, y_true, y_pred):
        dice = soft_dice(y_true, y_pred)
        skel_pred = soft_skel(y_pred, self.iter)
        skel_true = soft_skel(y_true, self.iter)
        tprec = (torch.sum(torch.multiply(skel_pred, y_true)) + self.smooth) / (
                    torch.sum(skel_pred) + self.smooth)
        tsens = (torch.sum(torch.multiply(skel_true, y_pred)) + self.smooth) / (
                    torch.sum(skel_true) + self.smooth)
        cl_dice = 1. - 2.0 * (tprec * tsens) / (tprec + tsens)
        return (1.0 - self.alpha) * dice + self.alpha * cl_dice

Before the modification, the code restricted the channels from the second to the last, and usually the output only contained one channel, resulting in a loss of 0. However, after such modifications, the cldice still did not work well for my code.

Same doubt about operation of discarding the first channel. By the way, may I ask how you choose the num of iters for soft skeleton, program a new algorithm to calculate diameter of each data or just empirically choose one?

Just empirically choose one.

@steveyoung30
Copy link

I use other loss function but it works well but why when i wanted to use this it shows zero for the training and validation loss.

I have found the problem, maybe it should be solved this way?

def soft_dice(y_true, y_pred):
    smooth = 1e-5
    intersection = torch.sum((y_true * y_pred))
    coeff = (2. * intersection + smooth) / (torch.sum(y_true) + torch.sum(y_pred) + smooth)
    return 1. - coeff


class soft_dice_cldice(nn.Module):
    def __init__(self, iter_=3, alpha=0.5, smooth=1e-5):
        super(soft_dice_cldice, self).__init__()
        self.iter = iter_
        self.smooth = smooth
        self.alpha = alpha

    def forward(self, y_true, y_pred):
        dice = soft_dice(y_true, y_pred)
        skel_pred = soft_skel(y_pred, self.iter)
        skel_true = soft_skel(y_true, self.iter)
        tprec = (torch.sum(torch.multiply(skel_pred, y_true)) + self.smooth) / (
                    torch.sum(skel_pred) + self.smooth)
        tsens = (torch.sum(torch.multiply(skel_true, y_pred)) + self.smooth) / (
                    torch.sum(skel_true) + self.smooth)
        cl_dice = 1. - 2.0 * (tprec * tsens) / (tprec + tsens)
        return (1.0 - self.alpha) * dice + self.alpha * cl_dice

Before the modification, the code restricted the channels from the second to the last, and usually the output only contained one channel, resulting in a loss of 0. However, after such modifications, the cldice still did not work well for my code.

Same doubt about operation of discarding the first channel. By the way, may I ask how you choose the num of iters for soft skeleton, program a new algorithm to calculate diameter of each data or just empirically choose one?

Just empirically choose one.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants