forked from crocodoyle/deep-mri-qc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcustom_loss.py
95 lines (70 loc) · 2.54 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
# Author: Alexandre Hutton ([email protected])
from keras import backend as K
import numpy as np
import tensorflow as tf
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 + K.epsilon()) / (total + K.epsilon())
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_positives(y_true, y_pred):
"""Return number of true positives"""
return tf.multiply(y_true, y_pred)
def true_negatives(y_true, y_pred):
"""Return number of true negatives"""
return tf.multiply(1 - y_pred, 1 - y_true)
def false_positives(y_true, y_pred):
"""Return number of false positives"""
return (y_pred) * (1 - y_true)
def false_negatives(y_true, y_pred):
"""Return number of false negatives"""
return (1 - y_pred) * (y_true)
def sensitivity(y_true, y_pred):
"""Return sensitivity (how many of the positives were detected?)"""
tp = true_positives(y_true, y_pred)
fn = false_negatives(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 = true_negatives(y_true, y_pred)
fp = false_positives(y_true, y_pred)
return tn / (tn + fp + K.epsilon())