-
Notifications
You must be signed in to change notification settings - Fork 19.4k
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
Dice score function #3611
Comments
I suggest averaging across batch axis, 0-dimension:
|
Don't you think it should be? def dice_coef_loss(y_true, y_pred):
return 1-dice_coef(y_true, y_pred) With your code a correct prediction get -1 and a wrong one gets -0.25, I think this is the opposite of what a loss function should be. # not matched
dice_coef_loss(
K.theano.shared(np.array([[0,0,0]])),
K.theano.shared(np.array([[1,1,1]]))
).eval() # -0.25
# match
dice_coef_loss(
K.theano.shared(np.array([[0,0,0]])),
K.theano.shared(np.array([[0,0,0]]))
).eval() # -1.0 Here's suggestion which uses vector operations and averages across the batch axis. def dice_coef(y_true, y_pred, smooth=1):
y_true_f = K.flatten(y_true)
y_pred_f = K.flatten(y_pred)
intersection = K.dot(y_true, K.transpose(y_pred))
union = K.dot(y_true,K.transpose(y_true))+K.dot(y_pred,K.transpose(y_pred))
return (2. * intersection + smooth) / (union + smooth)
def dice_coef_loss(y_true, y_pred):
return K.mean(1-dice_coef(y_true, y_pred),axis=-1)
# test
dice_coef_loss(
K.theano.shared(np.array([[0,0,0],[0,0,0]])),
K.theano.shared(np.array([[1,1,1],[1,1,1]]))
).eval()
# array([ 0.99999997, 0.99999997])
dice_coef_loss(
K.theano.shared(np.array([[0,0,0],[0,0,0]])),
K.theano.shared(np.array([[0,0,0],[0,0,0]]))
).eval() # array([ 0., 0.]) |
Hi @wassname, could you clarify your statement?
I'm quite new to ML but isn't a loss function supposed to output a lower value for a correct prediction and a higher value for a wrong one? isn't that exactly what @hadim version of the function is doing? |
@cicobalico yeah sure EDIT: I was wrong about that sorry
When I used OP's loss function my CNN converged on the exact opposite answer and made an inverse mask instead of a mask. That makes sense if it was working backwards towards -0.25.
(its not just hadim, it's written that way in [a](https://github.com/jocicmarko/ultrasound-nerve-segmentation/blob/master/train.py#L26) [couple](https://github.com/EdwardTyantov/ultrasound-nerve-segmentation/blob/master/metric.py#L19) of repos which makes me think I'm missing something) |
1-dice_coef |
but for -dice_coef it converges on y_pred!=y_true, doesn't it. I gave specific examples above. I think the ranges [0,1] and [0,-1] would be interchangeable but not [0,1] and [-1,0] as in this case. |
It shouldn't. Back propagation must minimize loss as low as it can, -1 in case of (-dice_coef) loss |
Ah that makes sense then, thanks for clarifying that! |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs, but feel free to re-open it if needed. |
Hello everybody, Thanks for answering in advance! |
if you are using dice coefficient as a loss, should you not specify the derivative of the dice coefficient w.r.t. to the output layer so that back propagation can work? |
hi, |
I suppose white means it is considering all the images as foreground. Can you post more about how did you made training set and is it binary level segmentation or multi label segmentation. |
I use the code from the first floor: def dice_coef_loss(y_true, y_pred): ...model.compile(optimizer=optimizer, loss=dice_coef_loss, metrics=[dice_coef]) ...` |
@alexander-rakhlin i've seen that some implementations of the dice-coefficient use |
@tinalegre this was 3 years ago and I can't remember where this |
@alexander-rakhlin thank you! It doesn't make any difference you mean, because for both |
lease,what is the correct implementation of the dice coefficient def dice_coef1(y_true, y_pred, smooth=1):
intersection = K.sum(y_true * y_pred, axis=[1,2,3])
union = K.sum(y_true, axis=[1,2,3]) + K.sum(y_pred, axis=[1,2,3])
dice = K.mean((2. * intersection + smooth)/(union + smooth), axis=0)
return dice Gives me the following result = 0.85 or def dice_coef2(target, prediction, smooth=1):
numerator = 2.0 * K.sum(target * prediction) + smooth
denominator = K.sum(target) + K.sum(prediction) + smooth
coef = numerator / denominator
return coef Gives me the following result : 0.94 |
I am using the following score function :
It works pretty well for me training a fully DCNN to segment images.
Would you be interested in a PR in order to implement this in Keras ?
Note that the original implementation comes from the Kaggle post https://www.kaggle.com/c/ultrasound-nerve-segmentation/forums/t/21358/0-57-deep-learning-keras-tutorial
The text was updated successfully, but these errors were encountered: