forked from crocodoyle/deep-mri-qc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcustom_loss.py
108 lines (79 loc) · 3.03 KB
/
custom_loss.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# Author: Alexandre Hutton ([email protected])
from keras import backend as K
import numpy as np
def dice_loss(y_true, y_pred):
"""
Computes approximate DICE coefficient as a loss by using the negative, computed with the Keras backend. The overlap\
and total are offset to prevent 0/0, and the values are not rounded in order to keep the gradient information.
Args:
:arg y_true: Ground truth
:arg y_pred: Predicted value for some input
Returns
:return: Approximate DICE coefficient.
"""
ytf = K.flatten(y_true)
ypf = K.flatten(y_pred)
overlap = K.sum(ytf*ypf)
total = K.sum(ytf*ytf) + K.sum(ypf * ypf)
return -(2*overlap +1e-10) / (total + 1e-10)
def dice_metric(y_true, y_pred):
"""
Computes DICE coefficient, computed with the Keras backend.
Args:
:arg y_true: Ground truth
:arg y_pred: Predicted value for some input
Returns
:return: DICE coefficient
"""
ytf = K.round(K.flatten(y_true))
ypf = K.round(K.flatten(y_pred))
overlap = 2*K.sum(ytf*ypf)
total = K.sum(ytf*ytf) + K.sum(ypf * ypf)
return overlap / total
def dice_np(im1, im2):
"""
Computes DICE coefficient, computed with the Numpy
Args:
:arg im1: First image
:arg im2: Second image
Returns
:return: DICE coefficient
:rtype: float
"""
im3 = np.round(np.ndarray.flatten(im1))
im4 = np.round(np.ndarray.flatten(im2))
overlap = 2*np.dot(im3, im4)
total = np.dot(im3, im3) + np.dot(im4, im4)
return overlap / total
def true_positive(y_true, y_pred):
"""Return number of true positives"""
return y_true * K.round(y_pred)
def true_negative(y_true, y_pred):
"""Return number of true negatives"""
return (1-y_true) * (1-K.round(y_pred))
def false_positive(y_true, y_pred):
"""Return number of false positives"""
return (1-y_true) * K.round(y_pred)
def false_negative(y_true, y_pred):
"""Return number of false negatives"""
return y_true * (1-K.round(y_pred))
def sensitivity(y_true, y_pred):
"""Return sensitivity (how many of the positives were detected?)"""
tp = K.sum(true_positive(y_true, y_pred))
fn = K.sum(false_negative(y_true, y_pred))
return tp / (tp + fn + K.epsilon())
def specificity(y_true, y_pred):
"""Return specificity (how many of the negatives were detected?)"""
tn = K.sum( true_negative(y_true, y_pred))
fp = K.sum( false_positive(y_true, y_pred))
return tn / (tn+fp + K.epsilon())
def precision(y_true, y_pred):
"""Return precision (how many of the predicted positives are correct?)"""
tp = K.sum(true_positive(y_true, y_pred))
fp = K.sum(false_positive(y_true, y_pred))
return tp / (tp+fp + K.epsilon())
def negative_predictive_value(y_true, y_pred):
"""Return negative predictive value (how many of the predicted negatives are correct?)"""
tn = K.sum(true_negative(y_true, y_pred))
fn = K.sum(false_negative(y_true, y_pred))
return tn / (tn+fn + K.epsilon())