-
Notifications
You must be signed in to change notification settings - Fork 44
/
Copy pathutils.py
158 lines (118 loc) · 4.84 KB
/
utils.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import random
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#%matplotlib inline
import tensorflow as tf
import keras.backend as K
from keras.models import Model, load_model
from keras.layers import Input, BatchNormalization, Activation, Dense, Dropout,Maximum
from keras.layers.core import Lambda, RepeatVector, Reshape
from keras.layers.convolutional import Conv2D, Conv2DTranspose,Conv3D,Conv3DTranspose
from keras.layers.pooling import MaxPooling2D, GlobalMaxPool2D,MaxPooling3D
from keras.layers.merge import concatenate, add
from keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau
from keras.optimizers import Adam
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
from skimage.io import imread, imshow, concatenate_images
from skimage.transform import resize
import os
from skimage.io import imread, imshow, concatenate_images
from skimage.transform import resize
from medpy.io import load
import numpy as np
import cv2
from sklearn import metrics
def f1_score(y_true, y_pred):
# Count positive samples.
c1 = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
c2 = K.sum(K.round(K.clip(y_true, 0, 1)))
c3 = K.sum(K.round(K.clip(y_pred, 0, 1)))
# If there are no true samples, fix the F1 score at 0.
if c3 == 0:
return 0
# How many selected items are relevant?
precision = c1 / c2
# How many relevant items are selected?
recall = c1 / c3
# Calculate f1_score
f1_score = 2 * (precision * recall) / (precision + recall)
return f1_score
def one_hot_encode(a):
m = (np.arange(4) == a[...,None]).astype(int)
return m
def dice_coef(y_true, y_pred, epsilon=0.00001):
"""
Dice = (2*|X & Y|)/ (|X|+ |Y|)
= 2*sum(|A*B|)/(sum(A^2)+sum(B^2))
ref: https://arxiv.org/pdf/1606.04797v1.pdf
"""
axis = (0,1,2,3)
dice_numerator = 2. * K.sum(y_true * y_pred, axis=axis) + epsilon
dice_denominator = K.sum(y_true*y_true, axis=axis) + K.sum(y_pred*y_pred, axis=axis) + epsilon
return K.mean((dice_numerator)/(dice_denominator))
def dice_coef_loss(y_true, y_pred):
return 1-dice_coef(y_true, y_pred)
def standardize(image):
standardized_image = np.zeros(image.shape)
#
# iterate over the `z` dimension
for z in range(image.shape[2]):
# get a slice of the image
# at channel c and z-th dimension `z`
image_slice = image[:,:,z]
# subtract the mean from image_slice
centered = image_slice - np.mean(image_slice)
# divide by the standard deviation (only if it is different from zero)
if(np.std(centered)!=0):
centered = centered/np.std(centered)
# update the slice of standardized image
# with the scaled centered and scaled image
standardized_image[:, :, z] = centered
### END CODE HERE ###
return standardized_image
def compute_class_sens_spec(pred, label, class_num):
"""
Compute sensitivity and specificity for a particular example
for a given class.
Args:
pred (np.array): binary arrary of predictions, shape is
(num classes, height, width, depth).
label (np.array): binary array of labels, shape is
(num classes, height, width, depth).
class_num (int): number between 0 - (num_classes -1) which says
which prediction class to compute statistics
for.
Returns:
sensitivity (float): precision for given class_num.
specificity (float): recall for given class_num
"""
# extract sub-array for specified class
class_pred = pred[:,:,:,class_num]
class_label = label[:,:,:,class_num]
### START CODE HERE (REPLACE INSTANCES OF 'None' with your code) ###
# compute true positives, false positives,
# true negatives, false negatives
tp = np.sum((class_pred == 1) & (class_label == 1))
tn = np.sum((class_pred == 0) & (class_label == 1))
fp = np.sum((class_pred == 1) & (class_label == 0))
fn = np.sum((class_pred == 0) & (class_label == 0))
print(tp,tn,fp,fn)
# compute sensitivity and specificity
sensitivity = tp / (tp + fn)
specificity = tn / (tn + fp)
### END CODE HERE ###
return sensitivity, specificity
def get_sens_spec_df(pred, label):
patch_metrics = pd.DataFrame(
columns = ['Nothing',
'Edema',
'Non-Enhancing Tumor',
'Enhancing Tumor'],
index = ['Sensitivity',
'Specificity'])
for i, class_name in enumerate(patch_metrics.columns):
sens, spec = compute_class_sens_spec(pred, label, i)
patch_metrics.loc['Sensitivity', class_name] = round(sens,4)
patch_metrics.loc['Specificity', class_name] = round(spec,4)
return patch_metrics