a b/prediction-and-accuracy-measures.ipynb
1
{
2
 "cells": [
3
  {
4
   "cell_type": "markdown",
5
   "metadata": {},
6
   "source": [
7
    "# What this notebook is for\n",
8
    "\n",
9
    "This notebook aids the process of evaluating accuracy measures and predicting class outputs of already trained models."
10
   ]
11
  },
12
  {
13
   "cell_type": "code",
14
   "execution_count": null,
15
   "metadata": {},
16
   "outputs": [],
17
   "source": [
18
    "import tensorflow as tf\n",
19
    "import numpy as np\n",
20
    "import h5py as h5"
21
   ]
22
  },
23
  {
24
   "cell_type": "markdown",
25
   "metadata": {},
26
   "source": [
27
    "## Reading data\n",
28
    "\n",
29
    "Throughout this project we've used these functions in order to read the processed data."
30
   ]
31
  },
32
  {
33
   "cell_type": "code",
34
   "execution_count": null,
35
   "metadata": {},
36
   "outputs": [],
37
   "source": [
38
    "def make_dimensions_compatible(arr):\n",
39
    "    \n",
40
    "    return arr.reshape(arr.shape[0],-1,1)"
41
   ]
42
  },
43
  {
44
   "cell_type": "markdown",
45
   "metadata": {},
46
   "source": [
47
    "<blockquote>\n",
48
    "    <b>Note:</b> We're using Python <b>global variables</b> in the load_dataset method. They'll be available throughout this notebook.\n",
49
    "    </blockquote>"
50
   ]
51
  },
52
  {
53
   "cell_type": "markdown",
54
   "metadata": {},
55
   "source": [
56
    "<blockquote>\n",
57
    "    <b>Important:</b> This method uses default folder names, prefixes and suffixes (herd-coded) as chosen by the author. If you've not changed anything these names in other files, it should work without any issues.\n",
58
    "</blockquote>"
59
   ]
60
  },
61
  {
62
   "cell_type": "code",
63
   "execution_count": null,
64
   "metadata": {},
65
   "outputs": [],
66
   "source": [
67
    "def load_dataset(dataset_iter=1, window_size=512):\n",
68
    "    global X_train, Y_train, X_dev, Y_dev, X_test, Y_test\n",
69
    "    \n",
70
    "    dataset_relative_path = 'dataset/random-iter-%d/' % dataset_iter\n",
71
    "    \n",
72
    "    datafile = dataset_relative_path + 'datafile%d.h5' % window_size\n",
73
    "\n",
74
    "    with h5.File(datafile, 'r') as datafile:\n",
75
    "        X_train = np.array(datafile['X_train'])\n",
76
    "        Y_train = np.array(datafile['Y_train'])\n",
77
    "\n",
78
    "        X_dev = np.array(datafile['X_dev'])\n",
79
    "        Y_dev = np.array(datafile['Y_dev'])\n",
80
    "\n",
81
    "        X_test = np.array(datafile['X_test'])\n",
82
    "        Y_test = np.array(datafile['Y_test'])\n",
83
    "        \n",
84
    "        # setting the rank of the data to be compatible with 1d convolution functions\n",
85
    "        # defined in tensorflow\n",
86
    "        X_train = make_dimensions_compatible(X_train)\n",
87
    "        X_dev = make_dimensions_compatible(X_dev)\n",
88
    "        X_test = make_dimensions_compatible(X_test)\n",
89
    "        \n",
90
    "        # normalization\n",
91
    "        X_train = X_train / 1000\n",
92
    "        X_dev = X_dev / 1000\n",
93
    "        X_test = X_test / 1000"
94
   ]
95
  },
96
  {
97
   "cell_type": "code",
98
   "execution_count": null,
99
   "metadata": {},
100
   "outputs": [],
101
   "source": [
102
    "def get_session_path(dataset_iter=1, window_size=512, model_num=1, model_prefix='cnn', model_suffix='_lr-0.00002_mbs-128'):\n",
103
    "    return ('train/dataset-%d-%d/' + model_prefix + '%d' + model_suffix + '/') % (window_size, dataset_iter, model_num)\n",
104
    "\n"
105
   ]
106
  },
107
  {
108
   "cell_type": "markdown",
109
   "metadata": {},
110
   "source": [
111
    "## Prediction"
112
   ]
113
  },
114
  {
115
   "cell_type": "code",
116
   "execution_count": null,
117
   "metadata": {},
118
   "outputs": [],
119
   "source": [
120
    "def predict(X_test, session_path, model_file, Y_test_onehot=None):\n",
121
    "\n",
122
    "    tf.reset_default_graph()\n",
123
    "\n",
124
    "    checkpoint_path = session_path\n",
125
    "    model_path = session_path + model_file\n",
126
    "\n",
127
    "    with tf.Session() as sess:\n",
128
    "        loader = tf.train.import_meta_graph(model_path)\n",
129
    "        loader.restore(sess, tf.train.latest_checkpoint(checkpoint_path))\n",
130
    "\n",
131
    "        graph = tf.get_default_graph()\n",
132
    "\n",
133
    "        X = graph.get_tensor_by_name('X:0')\n",
134
    "        Y = graph.get_tensor_by_name('Y:0')\n",
135
    "        is_train = graph.get_tensor_by_name('is_train:0')\n",
136
    "        \n",
137
    "#         epoch_counter = graph.get_tensor_by_name('epoch_counter:0')\n",
138
    "#         print(epoch_counter.eval())\n",
139
    "\n",
140
    "        Y_hat = graph.get_tensor_by_name('softmax_output:0')\n",
141
    "\n",
142
    "        predict_op = tf.argmax(Y_hat, 1)\n",
143
    "\n",
144
    "        y_hat_test = predict_op.eval({X: X_test, is_train: False})\n",
145
    "        \n",
146
    "        # print the accuracy of the test set if the labels are provided\n",
147
    "        if (Y_test_onehot is not None):\n",
148
    "            y_test = np.argmax(Y_test_onehot, 1)\n",
149
    "            acc = (y_hat_test == y_test).mean()\n",
150
    "        \n",
151
    "\n",
152
    "    return y_hat_test, acc\n"
153
   ]
154
  },
155
  {
156
   "cell_type": "markdown",
157
   "metadata": {},
158
   "source": [
159
    "## Prediction with majority voting on ensemble network"
160
   ]
161
  },
162
  {
163
   "cell_type": "code",
164
   "execution_count": null,
165
   "metadata": {},
166
   "outputs": [],
167
   "source": [
168
    "def predict_voting(X_test_voting, session_path, model_file):\n",
169
    "\n",
170
    "    tf.reset_default_graph()\n",
171
    "\n",
172
    "    checkpoint_path = session_path\n",
173
    "    model_path = session_path + model_file\n",
174
    "    \n",
175
    "    y_hat_test_voting = []\n",
176
    "\n",
177
    "    with tf.Session() as sess:\n",
178
    "        loader = tf.train.import_meta_graph(model_path)\n",
179
    "        loader.restore(sess, tf.train.latest_checkpoint(checkpoint_path))\n",
180
    "\n",
181
    "        graph = tf.get_default_graph()\n",
182
    "\n",
183
    "        X = graph.get_tensor_by_name('X:0')\n",
184
    "        is_train = graph.get_tensor_by_name('is_train:0')\n",
185
    "\n",
186
    "        Y_hat = graph.get_tensor_by_name('softmax_output:0')\n",
187
    "\n",
188
    "        predict_op = tf.argmax(Y_hat, 1)\n",
189
    "        \n",
190
    "        classname, idx, counts = tf.unique_with_counts(predict_op)\n",
191
    "        predict_voting_op = tf.gather(classname, tf.argmax(counts))\n",
192
    "\n",
193
    "        # no. of training examples with the original feature size\n",
194
    "        m = X_test_voting.shape[0]\n",
195
    "        \n",
196
    "        # no. of split training examples of each original example\n",
197
    "        m_each = X_test_voting.shape[1]\n",
198
    "        \n",
199
    "        for ex in range(m):\n",
200
    "            x_test_voting = make_dimensions_compatible(X_test_voting[ex])\n",
201
    "            pred = predict_voting_op.eval({X: x_test_voting, is_train: False})\n",
202
    "            \n",
203
    "            y_hat_test_voting.append(pred)\n",
204
    "\n",
205
    "    return y_hat_test_voting"
206
   ]
207
  },
208
  {
209
   "cell_type": "markdown",
210
   "metadata": {},
211
   "source": [
212
    "### Accuracy measure\n",
213
    "\n",
214
    "Change the values of `model_num`, `window_size`, and `dataset_iters` to test on the different models (cnn1, cnn2, and so on... as described in the literature) you've trained on. If you've generated multiple datasets for k-fold cross validation use `dataset_iters`. In the literature, we've used window sizes of 512 and 1024."
215
   ]
216
  },
217
  {
218
   "cell_type": "code",
219
   "execution_count": null,
220
   "metadata": {
221
    "scrolled": false
222
   },
223
   "outputs": [],
224
   "source": [
225
    "# Run the following code to call the above define predict method and check accuracy of the models\n",
226
    "\n",
227
    "model_num = 8\n",
228
    "window_size = 1024\n",
229
    "dataset_iters = (1, 2, 3, 4, 5, 6, 7, 8)\n",
230
    "\n",
231
    "accuracies = np.array([])\n",
232
    "\n",
233
    "for dataset_iter in dataset_iters:\n",
234
    "    load_dataset(dataset_iter=dataset_iter, window_size=window_size)\n",
235
    "    predictions, acc = predict(X_test, get_session_path(dataset_iter=dataset_iter, window_size=window_size, model_num=model_num), 'model.meta', Y_test_onehot=Y_test)\n",
236
    "    accuracies = np.append(accuracies, acc)\n",
237
    "\n",
238
    "accuracies = accuracies * 100\n",
239
    "print(accuracies)\n",
240
    "\n",
241
    "print(\"Mean accuracy: %f\" % accuracies.mean())"
242
   ]
243
  },
244
  {
245
   "cell_type": "markdown",
246
   "metadata": {},
247
   "source": [
248
    "### Single model accuracy with voting measure"
249
   ]
250
  },
251
  {
252
   "cell_type": "markdown",
253
   "metadata": {},
254
   "source": [
255
    "<blockquote>\n",
256
    "    <b>Note:</b> This method uses default folder names and suffixes chosen by the author.\n",
257
    "</blockquote>\n",
258
    "\n",
259
    "Calculate accuracy with voting, F-score, and other relevant measures. Change the values of `model_num`, `window_size`, and `dataset_iters` to try on different models and random permuations (random-iter-) of dataset."
260
   ]
261
  },
262
  {
263
   "cell_type": "code",
264
   "execution_count": null,
265
   "metadata": {},
266
   "outputs": [],
267
   "source": [
268
    "model_num = 8\n",
269
    "window_size = 1024\n",
270
    "dataset_iters = (1, 2, 3, 4, 5, 6, 7, 8)\n",
271
    "\n",
272
    "accuracies_voting = np.array([])\n",
273
    "sensitivities_voting = np.array([])\n",
274
    "specificities_voting = np.array([])\n",
275
    "precisions_voting = np.array([])\n",
276
    "\n",
277
    "for dataset_iter in dataset_iters:\n",
278
    "    dataset_relative_path = 'dataset/random-iter-%d/' % dataset_iter\n",
279
    "    testfile = (dataset_relative_path + 'testset_voting_%d.h5') % window_size\n",
280
    "    session_path = get_session_path(dataset_iter=dataset_iter, window_size=window_size, model_num=model_num)\n",
281
    "    model_file = 'model.meta'\n",
282
    "\n",
283
    "    with h5.File(testfile, 'r') as testfile:\n",
284
    "        X_test_voting = testfile['X']\n",
285
    "        X_test_voting = np.array(X_test_voting) / 1000\n",
286
    "        y_test_voting = np.array(testfile['Y'])\n",
287
    "        \n",
288
    "        no_of_classes = 3\n",
289
    "\n",
290
    "        y_hat_test_voting = np.array(predict_voting(X_test_voting, session_path, model_file))\n",
291
    "\n",
292
    "        acc_voting_model = (y_test_voting == y_hat_test_voting).mean()\n",
293
    "        accuracies_voting = np.append(accuracies_voting, acc_voting_model)\n",
294
    "        \n",
295
    "        # specificity and sensitivity\n",
296
    "        specificity = 0\n",
297
    "        sensitivity = 0\n",
298
    "        precision = 0\n",
299
    "        for i in range(no_of_classes):\n",
300
    "            specificity_vector = ((y_hat_test_voting != i) == (y_test_voting != i))[y_test_voting != i]\n",
301
    "            sensitivity_vector = ((y_hat_test_voting == i) == (y_test_voting == i))[y_test_voting == i]\n",
302
    "            precision_vector = ((y_hat_test_voting == i) == (y_test_voting == i))[y_hat_test_voting == i]\n",
303
    "            \n",
304
    "            specificity = specificity + specificity_vector.sum() / len(specificity_vector)\n",
305
    "            sensitivity = sensitivity + sensitivity_vector.sum() / len(sensitivity_vector)\n",
306
    "            precision = precision + precision_vector.sum() / len(precision_vector)\n",
307
    "        \n",
308
    "        specificity = specificity / no_of_classes\n",
309
    "        sensitivity = sensitivity / no_of_classes\n",
310
    "        precision = precision / no_of_classes\n",
311
    "        \n",
312
    "        specificities_voting = np.append(specificities_voting, specificity)\n",
313
    "        sensitivities_voting = np.append(sensitivities_voting, sensitivity)\n",
314
    "        precisions_voting = np.append(precisions_voting, precision)\n",
315
    "\n",
316
    "\n",
317
    "# Computing F-Score\n",
318
    "Pre = precisions_voting.mean()\n",
319
    "Sen = sensitivities_voting.mean()\n",
320
    "F_Score = (2 * Pre * Sen) / (Pre + Sen)\n",
321
    "        \n",
322
    "accuracies_voting = accuracies_voting * 100\n",
323
    "print(\"Accuracy with voting: \", accuracies_voting)\n",
324
    "print(\"Mean accuracy with voting: %f\" % accuracies_voting.mean())\n",
325
    "print(\"\\n\\n\")\n",
326
    "print(\"Specifities: \", specificities_voting)\n",
327
    "print(\"Mean specificity with voting: %f\" % specificities_voting.mean())\n",
328
    "print(\"\\n\\n\")\n",
329
    "print(\"Sensitivities: \", sensitivities_voting)\n",
330
    "print(\"Mean sensitivity with voting: %f\" % sensitivities_voting.mean())\n",
331
    "# print(\"Mean precision with voting: %f\" % Pre)\n",
332
    "print(\"Mean F-Score with voting: %f\" % F_Score)\n",
333
    "print(\"Standard deviation: %f\" % accuracies_voting.std())\n",
334
    "\n",
335
    "# print(\"Actual labels:\\n\", y_test_voting)\n",
336
    "# print(\"\\n\\nPredictions:\\n\", y_hat_test_voting)\n"
337
   ]
338
  },
339
  {
340
   "cell_type": "code",
341
   "execution_count": null,
342
   "metadata": {},
343
   "outputs": [],
344
   "source": []
345
  }
346
 ],
347
 "metadata": {
348
  "kernelspec": {
349
   "display_name": "Python 3",
350
   "language": "python",
351
   "name": "python3"
352
  },
353
  "language_info": {
354
   "codemirror_mode": {
355
    "name": "ipython",
356
    "version": 3
357
   },
358
   "file_extension": ".py",
359
   "mimetype": "text/x-python",
360
   "name": "python",
361
   "nbconvert_exporter": "python",
362
   "pygments_lexer": "ipython3",
363
   "version": "3.6.8"
364
  }
365
 },
366
 "nbformat": 4,
367
 "nbformat_minor": 2
368
}