|
a |
|
b/Models/Evaluation_Metrics/Metrics.py |
|
|
1 |
#!/usr/bin/env python |
|
|
2 |
# -*- coding: utf-8 -*- |
|
|
3 |
|
|
|
4 |
# Import useful packages |
|
|
5 |
import tensorflow as tf |
|
|
6 |
|
|
|
7 |
def evaluation(y, prediction): |
|
|
8 |
''' |
|
|
9 |
|
|
|
10 |
This is the evaluation metrics. |
|
|
11 |
Here, we provide a four-class classification evaluation codes |
|
|
12 |
The files will be updated to adapt multiply classes soon. |
|
|
13 |
|
|
|
14 |
Notice: All the evaluations during training will be saved in the TensorBoard. |
|
|
15 |
|
|
|
16 |
Use |
|
|
17 |
tensorboard --logdir="Your_Checkpoint_File_Address" --host=127.0.0.1 |
|
|
18 |
to view and download the evaluation files. |
|
|
19 |
|
|
|
20 |
BTW, you can definitely edit the following codes to adapt your own classes, |
|
|
21 |
e.g., if Two classes, u can just delete the three and four class. |
|
|
22 |
|
|
|
23 |
Args: |
|
|
24 |
y: The True Labels (with One-hot representation) |
|
|
25 |
prediction: The predicted output probability |
|
|
26 |
|
|
|
27 |
Returns: |
|
|
28 |
Single class evaluation: T1_accuracy, T1_Precision, T1_Recall, T1_F_Score, |
|
|
29 |
T2_accuracy, T2_Precision, T2_Recall, T2_F_Score, |
|
|
30 |
T3_accuracy, T3_Precision, T3_Recall, T3_F_Score, |
|
|
31 |
T4_accuracy, T4_Precision, T4_Recall, T4_F_Score, |
|
|
32 |
|
|
|
33 |
Global model evaluation: Global_Average_Accuracy, |
|
|
34 |
Kappa_Metric, |
|
|
35 |
Macro_Global_Precision, |
|
|
36 |
Macro_Global_Recall, |
|
|
37 |
Macro_Global_F1_Score |
|
|
38 |
|
|
|
39 |
''' |
|
|
40 |
|
|
|
41 |
# Calculate Accuracy |
|
|
42 |
# Add metrics to TensorBoard. |
|
|
43 |
with tf.name_scope('Evalution'): |
|
|
44 |
# Calculate Each Task Accuracy |
|
|
45 |
with tf.name_scope('Each_Class_accuracy'): |
|
|
46 |
# Task 1 Accuracy |
|
|
47 |
with tf.name_scope('T1_accuracy'): |
|
|
48 |
# Number of Classified Correctly |
|
|
49 |
y_T1 = tf.equal(tf.argmax(y, 1), 0) |
|
|
50 |
prediction_T1 = tf.equal(tf.argmax(prediction, 1), 0) |
|
|
51 |
T1_Corrected_Num = tf.reduce_sum(tf.cast(tf.math.logical_and(y_T1, prediction_T1), tf.float32)) |
|
|
52 |
|
|
|
53 |
# Number of All the Test Samples |
|
|
54 |
T1_all_Num = tf.reduce_sum(tf.cast(y_T1, tf.float32)) |
|
|
55 |
|
|
|
56 |
# Task 1 Accuracy |
|
|
57 |
T1_accuracy = tf.divide(T1_Corrected_Num, T1_all_Num) |
|
|
58 |
tf.summary.scalar('T1_accuracy', T1_accuracy) |
|
|
59 |
|
|
|
60 |
T1_TP = T1_Corrected_Num |
|
|
61 |
T1_TN = tf.reduce_sum( |
|
|
62 |
tf.cast(tf.math.logical_and(tf.math.logical_not(y_T1), tf.math.logical_not(prediction_T1)), |
|
|
63 |
tf.float32)) |
|
|
64 |
T1_FP = tf.reduce_sum( |
|
|
65 |
tf.cast(tf.math.logical_and(tf.math.logical_not(y_T1), prediction_T1), tf.float32)) |
|
|
66 |
T1_FN = tf.reduce_sum( |
|
|
67 |
tf.cast(tf.math.logical_and(y_T1, tf.math.logical_not(prediction_T1)), tf.float32)) |
|
|
68 |
|
|
|
69 |
with tf.name_scope("T1_Precision"): |
|
|
70 |
T1_Precision = T1_TP / (T1_TP + T1_FP) |
|
|
71 |
tf.summary.scalar('T1_Precision', T1_Precision) |
|
|
72 |
|
|
|
73 |
with tf.name_scope("T1_Recall"): |
|
|
74 |
T1_Recall = T1_TP / (T1_TP + T1_FN) |
|
|
75 |
tf.summary.scalar('T1_Recall', T1_Recall) |
|
|
76 |
|
|
|
77 |
with tf.name_scope("T1_F_Score"): |
|
|
78 |
T1_F_Score = (2 * T1_Precision * T1_Recall) / (T1_Precision + T1_Recall) |
|
|
79 |
tf.summary.scalar('T1_F_Score', T1_F_Score) |
|
|
80 |
|
|
|
81 |
# Task 2 Accuracy |
|
|
82 |
with tf.name_scope('T2_accuracy'): |
|
|
83 |
# Number of Classified Correctly |
|
|
84 |
y_T2 = tf.equal(tf.argmax(y, 1), 1) |
|
|
85 |
prediction_T2 = tf.equal(tf.argmax(prediction, 1), 1) |
|
|
86 |
T2_Corrected_Num = tf.reduce_sum(tf.cast(tf.math.logical_and(y_T2, prediction_T2), tf.float32)) |
|
|
87 |
|
|
|
88 |
# Number of All the Test Samples |
|
|
89 |
T2_all_Num = tf.reduce_sum(tf.cast(y_T2, tf.float32)) |
|
|
90 |
|
|
|
91 |
# Task 2 Accuracy |
|
|
92 |
T2_accuracy = tf.divide(T2_Corrected_Num, T2_all_Num) |
|
|
93 |
tf.summary.scalar('T2_accuracy', T2_accuracy) |
|
|
94 |
|
|
|
95 |
T2_TP = T2_Corrected_Num |
|
|
96 |
T2_TN = tf.reduce_sum( |
|
|
97 |
tf.cast(tf.math.logical_and(tf.math.logical_not(y_T2), tf.math.logical_not(prediction_T2)), |
|
|
98 |
tf.float32)) |
|
|
99 |
T2_FP = tf.reduce_sum( |
|
|
100 |
tf.cast(tf.math.logical_and(tf.math.logical_not(y_T2), prediction_T2), tf.float32)) |
|
|
101 |
T2_FN = tf.reduce_sum( |
|
|
102 |
tf.cast(tf.math.logical_and(y_T2, tf.math.logical_not(prediction_T2)), tf.float32)) |
|
|
103 |
|
|
|
104 |
with tf.name_scope("T2_Precision"): |
|
|
105 |
T2_Precision = T2_TP / (T2_TP + T2_FP) |
|
|
106 |
tf.summary.scalar('T2_Precision', T2_Precision) |
|
|
107 |
|
|
|
108 |
with tf.name_scope("T2_Recall"): |
|
|
109 |
T2_Recall = T2_TP / (T2_TP + T2_FN) |
|
|
110 |
tf.summary.scalar('T2_Recall', T2_Recall) |
|
|
111 |
|
|
|
112 |
with tf.name_scope("T2_F_Score"): |
|
|
113 |
T2_F_Score = (2 * T2_Precision * T2_Recall) / (T2_Precision + T2_Recall) |
|
|
114 |
tf.summary.scalar('T2_F_Score', T2_F_Score) |
|
|
115 |
|
|
|
116 |
# Task 3 Accuracy |
|
|
117 |
with tf.name_scope('T3_accuracy'): |
|
|
118 |
# Number of Classified Correctly |
|
|
119 |
y_T3 = tf.equal(tf.argmax(y, 1), 2) |
|
|
120 |
prediction_T3 = tf.equal(tf.argmax(prediction, 1), 2) |
|
|
121 |
T3_Corrected_Num = tf.reduce_sum(tf.cast(tf.math.logical_and(y_T3, prediction_T3), tf.float32)) |
|
|
122 |
|
|
|
123 |
# Number of All the Test Samples |
|
|
124 |
T3_all_Num = tf.reduce_sum(tf.cast(y_T3, tf.float32)) |
|
|
125 |
|
|
|
126 |
# Task 3 Accuracy |
|
|
127 |
T3_accuracy = tf.divide(T3_Corrected_Num, T3_all_Num) |
|
|
128 |
tf.summary.scalar('T3_accuracy', T3_accuracy) |
|
|
129 |
|
|
|
130 |
T3_TP = T3_Corrected_Num |
|
|
131 |
T3_TN = tf.reduce_sum( |
|
|
132 |
tf.cast(tf.math.logical_and(tf.math.logical_not(y_T3), tf.math.logical_not(prediction_T3)), |
|
|
133 |
tf.float32)) |
|
|
134 |
T3_FP = tf.reduce_sum( |
|
|
135 |
tf.cast(tf.math.logical_and(tf.math.logical_not(y_T3), prediction_T3), tf.float32)) |
|
|
136 |
T3_FN = tf.reduce_sum( |
|
|
137 |
tf.cast(tf.math.logical_and(y_T3, tf.math.logical_not(prediction_T3)), tf.float32)) |
|
|
138 |
|
|
|
139 |
with tf.name_scope("T3_Precision"): |
|
|
140 |
T3_Precision = T3_TP / (T3_TP + T3_FP) |
|
|
141 |
tf.summary.scalar('T3_Precision', T3_Precision) |
|
|
142 |
|
|
|
143 |
with tf.name_scope("T3_Recall"): |
|
|
144 |
T3_Recall = T3_TP / (T3_TP + T3_FN) |
|
|
145 |
tf.summary.scalar('T3_Recall', T3_Recall) |
|
|
146 |
|
|
|
147 |
with tf.name_scope("T3_F_Score"): |
|
|
148 |
T3_F_Score = (2 * T3_Precision * T3_Recall) / (T3_Precision + T3_Recall) |
|
|
149 |
tf.summary.scalar('T3_F_Score', T3_F_Score) |
|
|
150 |
|
|
|
151 |
# Task 4 Accuracy |
|
|
152 |
with tf.name_scope('T4_accuracy'): |
|
|
153 |
# Number of Classified Correctly |
|
|
154 |
y_T4 = tf.equal(tf.argmax(y, 1), 3) |
|
|
155 |
prediction_T4 = tf.equal(tf.argmax(prediction, 1), 3) |
|
|
156 |
T4_Corrected_Num = tf.reduce_sum(tf.cast(tf.math.logical_and(y_T4, prediction_T4), tf.float32)) |
|
|
157 |
|
|
|
158 |
# Number of All the Test Samples |
|
|
159 |
T4_all_Num = tf.reduce_sum(tf.cast(y_T4, tf.float32)) |
|
|
160 |
|
|
|
161 |
# Task 4 Accuracy |
|
|
162 |
T4_accuracy = tf.divide(T4_Corrected_Num, T4_all_Num) |
|
|
163 |
tf.summary.scalar('T4_accuracy', T4_accuracy) |
|
|
164 |
|
|
|
165 |
T4_TP = T4_Corrected_Num |
|
|
166 |
T4_TN = tf.reduce_sum( |
|
|
167 |
tf.cast(tf.math.logical_and(tf.math.logical_not(y_T4), tf.math.logical_not(prediction_T4)), |
|
|
168 |
tf.float32)) |
|
|
169 |
T4_FP = tf.reduce_sum( |
|
|
170 |
tf.cast(tf.math.logical_and(tf.math.logical_not(y_T4), prediction_T4), tf.float32)) |
|
|
171 |
T4_FN = tf.reduce_sum( |
|
|
172 |
tf.cast(tf.math.logical_and(y_T4, tf.math.logical_not(prediction_T4)), tf.float32)) |
|
|
173 |
|
|
|
174 |
with tf.name_scope("T4_Precision"): |
|
|
175 |
T4_Precision = T4_TP / (T4_TP + T4_FP) |
|
|
176 |
tf.summary.scalar('T4_Precision', T4_Precision) |
|
|
177 |
|
|
|
178 |
with tf.name_scope("T4_Recall"): |
|
|
179 |
T4_Recall = T4_TP / (T4_TP + T4_FN) |
|
|
180 |
tf.summary.scalar('T4_Recall', T4_Recall) |
|
|
181 |
|
|
|
182 |
with tf.name_scope("T4_F_Score"): |
|
|
183 |
T4_F_Score = (2 * T4_Precision * T4_Recall) / (T4_Precision + T4_Recall) |
|
|
184 |
tf.summary.scalar('T4_F_Score', T4_F_Score) |
|
|
185 |
|
|
|
186 |
# Calculate the Confusion Matrix |
|
|
187 |
with tf.name_scope("Confusion_Matrix"): |
|
|
188 |
with tf.name_scope("T1_Label"): |
|
|
189 |
T1_T1 = T1_Corrected_Num |
|
|
190 |
T1_T2 = tf.reduce_sum(tf.cast(tf.math.logical_and(y_T1, prediction_T2), tf.float32)) |
|
|
191 |
T1_T3 = tf.reduce_sum(tf.cast(tf.math.logical_and(y_T1, prediction_T3), tf.float32)) |
|
|
192 |
T1_T4 = tf.reduce_sum(tf.cast(tf.math.logical_and(y_T1, prediction_T4), tf.float32)) |
|
|
193 |
|
|
|
194 |
T1_T1_percent = tf.divide(T1_T1, T1_all_Num) |
|
|
195 |
T1_T2_percent = tf.divide(T1_T2, T1_all_Num) |
|
|
196 |
T1_T3_percent = tf.divide(T1_T3, T1_all_Num) |
|
|
197 |
T1_T4_percent = tf.divide(T1_T4, T1_all_Num) |
|
|
198 |
|
|
|
199 |
tf.summary.scalar('T1_T1_percent', T1_T1_percent) |
|
|
200 |
tf.summary.scalar('T1_T2_percent', T1_T2_percent) |
|
|
201 |
tf.summary.scalar('T1_T3_percent', T1_T3_percent) |
|
|
202 |
tf.summary.scalar('T1_T4_percent', T1_T4_percent) |
|
|
203 |
|
|
|
204 |
with tf.name_scope("T2_Label"): |
|
|
205 |
T2_T1 = tf.reduce_sum(tf.cast(tf.math.logical_and(y_T2, prediction_T1), tf.float32)) |
|
|
206 |
T2_T2 = T2_Corrected_Num |
|
|
207 |
T2_T3 = tf.reduce_sum(tf.cast(tf.math.logical_and(y_T2, prediction_T3), tf.float32)) |
|
|
208 |
T2_T4 = tf.reduce_sum(tf.cast(tf.math.logical_and(y_T2, prediction_T4), tf.float32)) |
|
|
209 |
|
|
|
210 |
T2_T1_percent = tf.divide(T2_T1, T2_all_Num) |
|
|
211 |
T2_T2_percent = tf.divide(T2_T2, T2_all_Num) |
|
|
212 |
T2_T3_percent = tf.divide(T2_T3, T2_all_Num) |
|
|
213 |
T2_T4_percent = tf.divide(T2_T4, T2_all_Num) |
|
|
214 |
|
|
|
215 |
tf.summary.scalar('T2_T1_percent', T2_T1_percent) |
|
|
216 |
tf.summary.scalar('T2_T2_percent', T2_T2_percent) |
|
|
217 |
tf.summary.scalar('T2_T3_percent', T2_T3_percent) |
|
|
218 |
tf.summary.scalar('T2_T4_percent', T2_T4_percent) |
|
|
219 |
|
|
|
220 |
with tf.name_scope("T3_Label"): |
|
|
221 |
T3_T1 = tf.reduce_sum(tf.cast(tf.math.logical_and(y_T3, prediction_T1), tf.float32)) |
|
|
222 |
T3_T2 = tf.reduce_sum(tf.cast(tf.math.logical_and(y_T3, prediction_T2), tf.float32)) |
|
|
223 |
T3_T3 = T3_Corrected_Num |
|
|
224 |
T3_T4 = tf.reduce_sum(tf.cast(tf.math.logical_and(y_T3, prediction_T4), tf.float32)) |
|
|
225 |
|
|
|
226 |
T3_T1_percent = tf.divide(T3_T1, T3_all_Num) |
|
|
227 |
T3_T2_percent = tf.divide(T3_T2, T3_all_Num) |
|
|
228 |
T3_T3_percent = tf.divide(T3_T3, T3_all_Num) |
|
|
229 |
T3_T4_percent = tf.divide(T3_T4, T3_all_Num) |
|
|
230 |
|
|
|
231 |
tf.summary.scalar('T3_T1_percent', T3_T1_percent) |
|
|
232 |
tf.summary.scalar('T3_T2_percent', T3_T2_percent) |
|
|
233 |
tf.summary.scalar('T3_T3_percent', T3_T3_percent) |
|
|
234 |
tf.summary.scalar('T3_T4_percent', T3_T4_percent) |
|
|
235 |
|
|
|
236 |
with tf.name_scope("T4_Label"): |
|
|
237 |
T4_T1 = tf.reduce_sum(tf.cast(tf.math.logical_and(y_T4, prediction_T1), tf.float32)) |
|
|
238 |
T4_T2 = tf.reduce_sum(tf.cast(tf.math.logical_and(y_T4, prediction_T2), tf.float32)) |
|
|
239 |
T4_T3 = tf.reduce_sum(tf.cast(tf.math.logical_and(y_T4, prediction_T3), tf.float32)) |
|
|
240 |
T4_T4 = T4_Corrected_Num |
|
|
241 |
|
|
|
242 |
T4_T1_percent = tf.divide(T4_T1, T4_all_Num) |
|
|
243 |
T4_T2_percent = tf.divide(T4_T2, T4_all_Num) |
|
|
244 |
T4_T3_percent = tf.divide(T4_T3, T4_all_Num) |
|
|
245 |
T4_T4_percent = tf.divide(T4_T4, T4_all_Num) |
|
|
246 |
|
|
|
247 |
tf.summary.scalar('T4_T1_percent', T4_T1_percent) |
|
|
248 |
tf.summary.scalar('T4_T2_percent', T4_T2_percent) |
|
|
249 |
tf.summary.scalar('T4_T3_percent', T4_T3_percent) |
|
|
250 |
tf.summary.scalar('T4_T4_percent', T4_T4_percent) |
|
|
251 |
|
|
|
252 |
with tf.name_scope('Global_Evalution_Metrics'): |
|
|
253 |
# Global Average Accuracy - Simple Algorithm |
|
|
254 |
with tf.name_scope('Global_Average_Accuracy'): |
|
|
255 |
correct_prediction = tf.equal(tf.argmax(prediction, 1), tf.argmax(y, 1)) |
|
|
256 |
Global_Average_Accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) |
|
|
257 |
tf.summary.scalar('Global_Average_Accuracy', Global_Average_Accuracy) |
|
|
258 |
|
|
|
259 |
with tf.name_scope('Kappa_Metric'): |
|
|
260 |
Test_Set_Num = T1_all_Num + T2_all_Num + T3_all_Num + T4_all_Num |
|
|
261 |
|
|
|
262 |
Actual_T1 = T1_all_Num |
|
|
263 |
Actual_T2 = T2_all_Num |
|
|
264 |
Actual_T3 = T3_all_Num |
|
|
265 |
Actual_T4 = T4_all_Num |
|
|
266 |
|
|
|
267 |
Prediction_T1 = T1_T1 + T2_T1 + T3_T1 + T4_T1 |
|
|
268 |
Prediction_T2 = T1_T2 + T2_T2 + T3_T2 + T4_T2 |
|
|
269 |
Prediction_T3 = T1_T3 + T2_T3 + T3_T3 + T4_T3 |
|
|
270 |
Prediction_T4 = T1_T4 + T2_T4 + T3_T4 + T4_T4 |
|
|
271 |
|
|
|
272 |
p0 = (T1_T1 + T2_T2 + T3_T3 + T4_T4) / Test_Set_Num |
|
|
273 |
pe = (Actual_T1 * Prediction_T1 + Actual_T2 * Prediction_T2 + Actual_T3 * Prediction_T3 + Actual_T4 * Prediction_T4) / \ |
|
|
274 |
(Test_Set_Num * Test_Set_Num) |
|
|
275 |
|
|
|
276 |
Kappa_Metric = (p0 - pe) / (1 - pe) |
|
|
277 |
tf.summary.scalar('Kappa_Metric', Kappa_Metric) |
|
|
278 |
|
|
|
279 |
with tf.name_scope('Micro_Averaged_Evalution'): |
|
|
280 |
with tf.name_scope("Micro_Averaged_Confusion_Matrix"): |
|
|
281 |
TP_all = T1_TP + T2_TP + T3_TP + T4_TP |
|
|
282 |
TN_all = T1_TN + T2_TN + T3_TN + T4_TN |
|
|
283 |
FP_all = T1_FP + T2_FP + T3_FP + T4_FP |
|
|
284 |
FN_all = T1_FN + T2_FN + T3_FN + T4_FN |
|
|
285 |
|
|
|
286 |
with tf.name_scope("Micro_Global_Precision"): |
|
|
287 |
Micro_Global_Precision = TP_all / (TP_all + FP_all) |
|
|
288 |
tf.summary.scalar('Micro_Global_Precision', Micro_Global_Precision) |
|
|
289 |
|
|
|
290 |
with tf.name_scope("Micro_Global_Recall"): |
|
|
291 |
Micro_Global_Recall = TP_all / (TP_all + FN_all) |
|
|
292 |
tf.summary.scalar('Micro_Global_Recall', Micro_Global_Recall) |
|
|
293 |
|
|
|
294 |
with tf.name_scope("Micro_Global_F1_Score"): |
|
|
295 |
Micro_Global_F1_Score = (2 * Micro_Global_Precision * Micro_Global_Recall) / ( |
|
|
296 |
Micro_Global_Precision + Micro_Global_Recall) |
|
|
297 |
tf.summary.scalar('Micro_Global_F1_Score', Micro_Global_F1_Score) |
|
|
298 |
|
|
|
299 |
with tf.name_scope('Macro_Averaged_Evalution'): |
|
|
300 |
with tf.name_scope("Macro_Global_Precision"): |
|
|
301 |
Macro_Global_Precision = (T1_Precision + T2_Precision + T3_Precision + T4_Precision) / 4 |
|
|
302 |
tf.summary.scalar('Macro_Global_Precision', Macro_Global_Precision) |
|
|
303 |
|
|
|
304 |
with tf.name_scope("Macro_Global_Recall"): |
|
|
305 |
Macro_Global_Recall = (T1_Recall + T2_Recall + T3_Recall + T4_Recall) / 4 |
|
|
306 |
tf.summary.scalar('Macro_Global_Recall', Macro_Global_Recall) |
|
|
307 |
|
|
|
308 |
with tf.name_scope("Macro_Global_F1_Score"): |
|
|
309 |
Macro_Global_F1_Score = (T1_F_Score + T2_F_Score + T3_F_Score + T4_F_Score) / 4 |
|
|
310 |
tf.summary.scalar('Macro_Global_F1_Score', Macro_Global_F1_Score) |
|
|
311 |
|
|
|
312 |
# You DON'T have to return these because all the criterias have been saved in the TensorBoard |
|
|
313 |
# return T1_accuracy, T1_Precision, T1_Recall, T1_F_Score, \ |
|
|
314 |
# T2_accuracy, T2_Precision, T2_Recall, T2_F_Score, \ |
|
|
315 |
# T3_accuracy, T3_Precision, T3_Recall, T3_F_Score, \ |
|
|
316 |
# T4_accuracy, T4_Precision, T4_Recall, T4_F_Score, \ |
|
|
317 |
# Global_Average_Accuracy, Kappa_Metric, \ |
|
|
318 |
# Macro_Global_Precision, Macro_Global_Recall, Macro_Global_F1_Score |
|
|
319 |
|
|
|
320 |
# Instead, you can only return Accuracy Criteria to compare the capacity of your Model |
|
|
321 |
return Global_Average_Accuracy |