├── .gitignore
├── LICENSE
├── README.md
├── keystroke dynamics authentication.ipynb
├── model.h5
└── model.png
/.gitignore:
--------------------------------------------------------------------------------
1 | datasets
2 | .ipynb_checkpoints
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Piyush Malhotra
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Keystroke Dynamics Using LSTMs
2 | This repository is a demo for using a LSTM based model to predict whether the person trying to login is authentic or not using keystroke dynamics.
3 |
4 | ## Dependencies
5 | 1. Keras
6 | 2. TensorFlow
7 | 3. Numpy
8 | 4. Pandas
9 | 5. Jupyter
10 |
11 | ## Usage
12 | Run ```jupyter notebook keystroke dynamics authentication.ipynb``` to run the notebook
13 |
14 | ## Dataset
15 | ```Cs.cmu.edu. (2018). Keystroke Dynamics - Benchmark Data Set. [online] Available at: https://www.cs.cmu.edu/~keystroke/```
--------------------------------------------------------------------------------
/keystroke dynamics authentication.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Keystroke Dynamics Using RNNs\n",
8 | "This notebook goes from the process of cleaning and preparing data to train and test a RNN for the job of Keystroke Dynamics. The Authentication Procedure comprises of using the timing of key strike, key hold, key change and so on to reach a conclusion whether the subject under observation is authentic or not."
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "metadata": {},
14 | "source": [
15 | "## Data Preparation & Cleaning"
16 | ]
17 | },
18 | {
19 | "cell_type": "code",
20 | "execution_count": 1,
21 | "metadata": {},
22 | "outputs": [],
23 | "source": [
24 | "import pandas as pd\n",
25 | "import numpy as np\n",
26 | "import matplotlib.pyplot as plt\n",
27 | "\n",
28 | "%matplotlib inline"
29 | ]
30 | },
31 | {
32 | "cell_type": "code",
33 | "execution_count": 2,
34 | "metadata": {},
35 | "outputs": [
36 | {
37 | "data": {
38 | "text/html": [
39 | "
\n",
40 | "
\n",
41 | " \n",
42 | " \n",
43 | " | \n",
44 | " subject | \n",
45 | " sessionIndex | \n",
46 | " rep | \n",
47 | " H.period | \n",
48 | " DD.period.t | \n",
49 | " UD.period.t | \n",
50 | " H.t | \n",
51 | " DD.t.i | \n",
52 | " UD.t.i | \n",
53 | " H.i | \n",
54 | " ... | \n",
55 | " H.a | \n",
56 | " DD.a.n | \n",
57 | " UD.a.n | \n",
58 | " H.n | \n",
59 | " DD.n.l | \n",
60 | " UD.n.l | \n",
61 | " H.l | \n",
62 | " DD.l.Return | \n",
63 | " UD.l.Return | \n",
64 | " H.Return | \n",
65 | "
\n",
66 | " \n",
67 | " \n",
68 | " \n",
69 | " 0 | \n",
70 | " s002 | \n",
71 | " 1 | \n",
72 | " 1 | \n",
73 | " 0.1491 | \n",
74 | " 0.3979 | \n",
75 | " 0.2488 | \n",
76 | " 0.1069 | \n",
77 | " 0.1674 | \n",
78 | " 0.0605 | \n",
79 | " 0.1169 | \n",
80 | " ... | \n",
81 | " 0.1349 | \n",
82 | " 0.1484 | \n",
83 | " 0.0135 | \n",
84 | " 0.0932 | \n",
85 | " 0.3515 | \n",
86 | " 0.2583 | \n",
87 | " 0.1338 | \n",
88 | " 0.3509 | \n",
89 | " 0.2171 | \n",
90 | " 0.0742 | \n",
91 | "
\n",
92 | " \n",
93 | " 1 | \n",
94 | " s002 | \n",
95 | " 1 | \n",
96 | " 2 | \n",
97 | " 0.1111 | \n",
98 | " 0.3451 | \n",
99 | " 0.2340 | \n",
100 | " 0.0694 | \n",
101 | " 0.1283 | \n",
102 | " 0.0589 | \n",
103 | " 0.0908 | \n",
104 | " ... | \n",
105 | " 0.1412 | \n",
106 | " 0.2558 | \n",
107 | " 0.1146 | \n",
108 | " 0.1146 | \n",
109 | " 0.2642 | \n",
110 | " 0.1496 | \n",
111 | " 0.0839 | \n",
112 | " 0.2756 | \n",
113 | " 0.1917 | \n",
114 | " 0.0747 | \n",
115 | "
\n",
116 | " \n",
117 | " 2 | \n",
118 | " s002 | \n",
119 | " 1 | \n",
120 | " 3 | \n",
121 | " 0.1328 | \n",
122 | " 0.2072 | \n",
123 | " 0.0744 | \n",
124 | " 0.0731 | \n",
125 | " 0.1291 | \n",
126 | " 0.0560 | \n",
127 | " 0.0821 | \n",
128 | " ... | \n",
129 | " 0.1621 | \n",
130 | " 0.2332 | \n",
131 | " 0.0711 | \n",
132 | " 0.1172 | \n",
133 | " 0.2705 | \n",
134 | " 0.1533 | \n",
135 | " 0.1085 | \n",
136 | " 0.2847 | \n",
137 | " 0.1762 | \n",
138 | " 0.0945 | \n",
139 | "
\n",
140 | " \n",
141 | " 3 | \n",
142 | " s002 | \n",
143 | " 1 | \n",
144 | " 4 | \n",
145 | " 0.1291 | \n",
146 | " 0.2515 | \n",
147 | " 0.1224 | \n",
148 | " 0.1059 | \n",
149 | " 0.2495 | \n",
150 | " 0.1436 | \n",
151 | " 0.1040 | \n",
152 | " ... | \n",
153 | " 0.1457 | \n",
154 | " 0.1629 | \n",
155 | " 0.0172 | \n",
156 | " 0.0866 | \n",
157 | " 0.2341 | \n",
158 | " 0.1475 | \n",
159 | " 0.0845 | \n",
160 | " 0.3232 | \n",
161 | " 0.2387 | \n",
162 | " 0.0813 | \n",
163 | "
\n",
164 | " \n",
165 | " 4 | \n",
166 | " s002 | \n",
167 | " 1 | \n",
168 | " 5 | \n",
169 | " 0.1249 | \n",
170 | " 0.2317 | \n",
171 | " 0.1068 | \n",
172 | " 0.0895 | \n",
173 | " 0.1676 | \n",
174 | " 0.0781 | \n",
175 | " 0.0903 | \n",
176 | " ... | \n",
177 | " 0.1312 | \n",
178 | " 0.1582 | \n",
179 | " 0.0270 | \n",
180 | " 0.0884 | \n",
181 | " 0.2517 | \n",
182 | " 0.1633 | \n",
183 | " 0.0903 | \n",
184 | " 0.2517 | \n",
185 | " 0.1614 | \n",
186 | " 0.0818 | \n",
187 | "
\n",
188 | " \n",
189 | "
\n",
190 | "
5 rows × 34 columns
\n",
191 | "
"
192 | ],
193 | "text/plain": [
194 | " subject sessionIndex rep H.period DD.period.t UD.period.t H.t \\\n",
195 | "0 s002 1 1 0.1491 0.3979 0.2488 0.1069 \n",
196 | "1 s002 1 2 0.1111 0.3451 0.2340 0.0694 \n",
197 | "2 s002 1 3 0.1328 0.2072 0.0744 0.0731 \n",
198 | "3 s002 1 4 0.1291 0.2515 0.1224 0.1059 \n",
199 | "4 s002 1 5 0.1249 0.2317 0.1068 0.0895 \n",
200 | "\n",
201 | " DD.t.i UD.t.i H.i ... H.a DD.a.n UD.a.n H.n DD.n.l \\\n",
202 | "0 0.1674 0.0605 0.1169 ... 0.1349 0.1484 0.0135 0.0932 0.3515 \n",
203 | "1 0.1283 0.0589 0.0908 ... 0.1412 0.2558 0.1146 0.1146 0.2642 \n",
204 | "2 0.1291 0.0560 0.0821 ... 0.1621 0.2332 0.0711 0.1172 0.2705 \n",
205 | "3 0.2495 0.1436 0.1040 ... 0.1457 0.1629 0.0172 0.0866 0.2341 \n",
206 | "4 0.1676 0.0781 0.0903 ... 0.1312 0.1582 0.0270 0.0884 0.2517 \n",
207 | "\n",
208 | " UD.n.l H.l DD.l.Return UD.l.Return H.Return \n",
209 | "0 0.2583 0.1338 0.3509 0.2171 0.0742 \n",
210 | "1 0.1496 0.0839 0.2756 0.1917 0.0747 \n",
211 | "2 0.1533 0.1085 0.2847 0.1762 0.0945 \n",
212 | "3 0.1475 0.0845 0.3232 0.2387 0.0813 \n",
213 | "4 0.1633 0.0903 0.2517 0.1614 0.0818 \n",
214 | "\n",
215 | "[5 rows x 34 columns]"
216 | ]
217 | },
218 | "execution_count": 2,
219 | "metadata": {},
220 | "output_type": "execute_result"
221 | }
222 | ],
223 | "source": [
224 | "df = pd.read_csv('./datasets/data.csv')\n",
225 | "\n",
226 | "df.head()"
227 | ]
228 | },
229 | {
230 | "cell_type": "code",
231 | "execution_count": 3,
232 | "metadata": {},
233 | "outputs": [],
234 | "source": [
235 | "subjects = df['subject'].unique()"
236 | ]
237 | },
238 | {
239 | "cell_type": "code",
240 | "execution_count": 4,
241 | "metadata": {},
242 | "outputs": [],
243 | "source": [
244 | "subjects_to_int = {subject: i for i, subject in enumerate(subjects)}\n",
245 | "int_to_subjects = {i: subject for i, subject in enumerate(subjects)}"
246 | ]
247 | },
248 | {
249 | "cell_type": "code",
250 | "execution_count": 5,
251 | "metadata": {},
252 | "outputs": [],
253 | "source": [
254 | "df = df.replace(subjects_to_int)"
255 | ]
256 | },
257 | {
258 | "cell_type": "code",
259 | "execution_count": 6,
260 | "metadata": {},
261 | "outputs": [
262 | {
263 | "data": {
264 | "text/html": [
265 | "\n",
266 | "
\n",
267 | " \n",
268 | " \n",
269 | " | \n",
270 | " subject | \n",
271 | " sessionIndex | \n",
272 | " rep | \n",
273 | " H.period | \n",
274 | " DD.period.t | \n",
275 | " UD.period.t | \n",
276 | " H.t | \n",
277 | " DD.t.i | \n",
278 | " UD.t.i | \n",
279 | " H.i | \n",
280 | " ... | \n",
281 | " H.a | \n",
282 | " DD.a.n | \n",
283 | " UD.a.n | \n",
284 | " H.n | \n",
285 | " DD.n.l | \n",
286 | " UD.n.l | \n",
287 | " H.l | \n",
288 | " DD.l.Return | \n",
289 | " UD.l.Return | \n",
290 | " H.Return | \n",
291 | "
\n",
292 | " \n",
293 | " \n",
294 | " \n",
295 | " 0 | \n",
296 | " 0 | \n",
297 | " 1 | \n",
298 | " 1 | \n",
299 | " 0.1491 | \n",
300 | " 0.3979 | \n",
301 | " 0.2488 | \n",
302 | " 0.1069 | \n",
303 | " 0.1674 | \n",
304 | " 0.0605 | \n",
305 | " 0.1169 | \n",
306 | " ... | \n",
307 | " 0.1349 | \n",
308 | " 0.1484 | \n",
309 | " 0.0135 | \n",
310 | " 0.0932 | \n",
311 | " 0.3515 | \n",
312 | " 0.2583 | \n",
313 | " 0.1338 | \n",
314 | " 0.3509 | \n",
315 | " 0.2171 | \n",
316 | " 0.0742 | \n",
317 | "
\n",
318 | " \n",
319 | " 1 | \n",
320 | " 0 | \n",
321 | " 1 | \n",
322 | " 2 | \n",
323 | " 0.1111 | \n",
324 | " 0.3451 | \n",
325 | " 0.2340 | \n",
326 | " 0.0694 | \n",
327 | " 0.1283 | \n",
328 | " 0.0589 | \n",
329 | " 0.0908 | \n",
330 | " ... | \n",
331 | " 0.1412 | \n",
332 | " 0.2558 | \n",
333 | " 0.1146 | \n",
334 | " 0.1146 | \n",
335 | " 0.2642 | \n",
336 | " 0.1496 | \n",
337 | " 0.0839 | \n",
338 | " 0.2756 | \n",
339 | " 0.1917 | \n",
340 | " 0.0747 | \n",
341 | "
\n",
342 | " \n",
343 | " 2 | \n",
344 | " 0 | \n",
345 | " 1 | \n",
346 | " 3 | \n",
347 | " 0.1328 | \n",
348 | " 0.2072 | \n",
349 | " 0.0744 | \n",
350 | " 0.0731 | \n",
351 | " 0.1291 | \n",
352 | " 0.0560 | \n",
353 | " 0.0821 | \n",
354 | " ... | \n",
355 | " 0.1621 | \n",
356 | " 0.2332 | \n",
357 | " 0.0711 | \n",
358 | " 0.1172 | \n",
359 | " 0.2705 | \n",
360 | " 0.1533 | \n",
361 | " 0.1085 | \n",
362 | " 0.2847 | \n",
363 | " 0.1762 | \n",
364 | " 0.0945 | \n",
365 | "
\n",
366 | " \n",
367 | " 3 | \n",
368 | " 0 | \n",
369 | " 1 | \n",
370 | " 4 | \n",
371 | " 0.1291 | \n",
372 | " 0.2515 | \n",
373 | " 0.1224 | \n",
374 | " 0.1059 | \n",
375 | " 0.2495 | \n",
376 | " 0.1436 | \n",
377 | " 0.1040 | \n",
378 | " ... | \n",
379 | " 0.1457 | \n",
380 | " 0.1629 | \n",
381 | " 0.0172 | \n",
382 | " 0.0866 | \n",
383 | " 0.2341 | \n",
384 | " 0.1475 | \n",
385 | " 0.0845 | \n",
386 | " 0.3232 | \n",
387 | " 0.2387 | \n",
388 | " 0.0813 | \n",
389 | "
\n",
390 | " \n",
391 | " 4 | \n",
392 | " 0 | \n",
393 | " 1 | \n",
394 | " 5 | \n",
395 | " 0.1249 | \n",
396 | " 0.2317 | \n",
397 | " 0.1068 | \n",
398 | " 0.0895 | \n",
399 | " 0.1676 | \n",
400 | " 0.0781 | \n",
401 | " 0.0903 | \n",
402 | " ... | \n",
403 | " 0.1312 | \n",
404 | " 0.1582 | \n",
405 | " 0.0270 | \n",
406 | " 0.0884 | \n",
407 | " 0.2517 | \n",
408 | " 0.1633 | \n",
409 | " 0.0903 | \n",
410 | " 0.2517 | \n",
411 | " 0.1614 | \n",
412 | " 0.0818 | \n",
413 | "
\n",
414 | " \n",
415 | "
\n",
416 | "
5 rows × 34 columns
\n",
417 | "
"
418 | ],
419 | "text/plain": [
420 | " subject sessionIndex rep H.period DD.period.t UD.period.t H.t \\\n",
421 | "0 0 1 1 0.1491 0.3979 0.2488 0.1069 \n",
422 | "1 0 1 2 0.1111 0.3451 0.2340 0.0694 \n",
423 | "2 0 1 3 0.1328 0.2072 0.0744 0.0731 \n",
424 | "3 0 1 4 0.1291 0.2515 0.1224 0.1059 \n",
425 | "4 0 1 5 0.1249 0.2317 0.1068 0.0895 \n",
426 | "\n",
427 | " DD.t.i UD.t.i H.i ... H.a DD.a.n UD.a.n H.n DD.n.l \\\n",
428 | "0 0.1674 0.0605 0.1169 ... 0.1349 0.1484 0.0135 0.0932 0.3515 \n",
429 | "1 0.1283 0.0589 0.0908 ... 0.1412 0.2558 0.1146 0.1146 0.2642 \n",
430 | "2 0.1291 0.0560 0.0821 ... 0.1621 0.2332 0.0711 0.1172 0.2705 \n",
431 | "3 0.2495 0.1436 0.1040 ... 0.1457 0.1629 0.0172 0.0866 0.2341 \n",
432 | "4 0.1676 0.0781 0.0903 ... 0.1312 0.1582 0.0270 0.0884 0.2517 \n",
433 | "\n",
434 | " UD.n.l H.l DD.l.Return UD.l.Return H.Return \n",
435 | "0 0.2583 0.1338 0.3509 0.2171 0.0742 \n",
436 | "1 0.1496 0.0839 0.2756 0.1917 0.0747 \n",
437 | "2 0.1533 0.1085 0.2847 0.1762 0.0945 \n",
438 | "3 0.1475 0.0845 0.3232 0.2387 0.0813 \n",
439 | "4 0.1633 0.0903 0.2517 0.1614 0.0818 \n",
440 | "\n",
441 | "[5 rows x 34 columns]"
442 | ]
443 | },
444 | "execution_count": 6,
445 | "metadata": {},
446 | "output_type": "execute_result"
447 | }
448 | ],
449 | "source": [
450 | "df.head()"
451 | ]
452 | },
453 | {
454 | "cell_type": "code",
455 | "execution_count": 7,
456 | "metadata": {},
457 | "outputs": [],
458 | "source": [
459 | "data = df.as_matrix()"
460 | ]
461 | },
462 | {
463 | "cell_type": "code",
464 | "execution_count": 8,
465 | "metadata": {},
466 | "outputs": [],
467 | "source": [
468 | "def generate_positives(data, n_pos_per_subject=150):\n",
469 | " n_subjects = np.unique(data[:, 0]).shape[0]\n",
470 | " poss = []\n",
471 | " for i in range(n_subjects):\n",
472 | " temp_d = data[data[:, 0] == i]\n",
473 | " first_half = temp_d[np.random.choice(400, n_pos_per_subject), 3:-1]\n",
474 | " second_half = temp_d[np.random.choice(400, n_pos_per_subject), 3:-1]\n",
475 | " poss.append(np.hstack([first_half, second_half]))\n",
476 | " return np.vstack(poss)"
477 | ]
478 | },
479 | {
480 | "cell_type": "code",
481 | "execution_count": 9,
482 | "metadata": {},
483 | "outputs": [
484 | {
485 | "data": {
486 | "text/plain": [
487 | "(7650, 60)"
488 | ]
489 | },
490 | "execution_count": 9,
491 | "metadata": {},
492 | "output_type": "execute_result"
493 | }
494 | ],
495 | "source": [
496 | "poss = generate_positives(data)\n",
497 | "poss.shape"
498 | ]
499 | },
500 | {
501 | "cell_type": "code",
502 | "execution_count": 10,
503 | "metadata": {},
504 | "outputs": [],
505 | "source": [
506 | "def generate_negatives(data, n_neg_per_subject=150):\n",
507 | " n_subjects = np.unique(data[:, 0]).shape[0]\n",
508 | " negs = []\n",
509 | " for i in range(n_subjects):\n",
510 | " temp_d = data[data[:, 0] == i]\n",
511 | " temp_not_d = data[data[:, 0] != i]\n",
512 | " first_half = temp_d[np.random.choice(400, n_neg_per_subject), 3:-1]\n",
513 | " second_half = temp_not_d[np.random.choice(400, n_neg_per_subject), 3:-1]\n",
514 | " negs.append(np.hstack([first_half, second_half]))\n",
515 | " return np.vstack(negs)"
516 | ]
517 | },
518 | {
519 | "cell_type": "code",
520 | "execution_count": 11,
521 | "metadata": {},
522 | "outputs": [
523 | {
524 | "data": {
525 | "text/plain": [
526 | "(7650, 60)"
527 | ]
528 | },
529 | "execution_count": 11,
530 | "metadata": {},
531 | "output_type": "execute_result"
532 | }
533 | ],
534 | "source": [
535 | "negs = generate_negatives(data)\n",
536 | "negs.shape"
537 | ]
538 | },
539 | {
540 | "cell_type": "code",
541 | "execution_count": 12,
542 | "metadata": {},
543 | "outputs": [
544 | {
545 | "data": {
546 | "text/plain": [
547 | "(15300, 1)"
548 | ]
549 | },
550 | "execution_count": 12,
551 | "metadata": {},
552 | "output_type": "execute_result"
553 | }
554 | ],
555 | "source": [
556 | "labels = np.zeros(poss.shape[0] + negs.shape[0])\n",
557 | "labels[:poss.shape[0]] = 1\n",
558 | "labels = np.expand_dims(labels, axis=1)\n",
559 | "labels.shape"
560 | ]
561 | },
562 | {
563 | "cell_type": "code",
564 | "execution_count": 13,
565 | "metadata": {},
566 | "outputs": [
567 | {
568 | "data": {
569 | "text/plain": [
570 | "array([[ 0.1024, 0.1622, 0.0598, ..., 0.3598, 0.2524, 1. ],\n",
571 | " [ 0.1074, 0.1525, 0.0451, ..., 0.2532, 0.1466, 1. ],\n",
572 | " [ 0.0953, 0.1032, 0.0079, ..., 0.2263, 0.1413, 1. ],\n",
573 | " ..., \n",
574 | " [ 0.0765, 0.1231, 0.0466, ..., 0.192 , 0.1073, 0. ],\n",
575 | " [ 0.1031, 0.1049, 0.0018, ..., 0.2313, 0.1252, 0. ],\n",
576 | " [ 0.1055, 0.1089, 0.0034, ..., 0.2089, 0.1279, 0. ]])"
577 | ]
578 | },
579 | "execution_count": 13,
580 | "metadata": {},
581 | "output_type": "execute_result"
582 | }
583 | ],
584 | "source": [
585 | "all_data = np.hstack([np.vstack([poss, negs]), labels])\n",
586 | "all_data"
587 | ]
588 | },
589 | {
590 | "cell_type": "code",
591 | "execution_count": 14,
592 | "metadata": {},
593 | "outputs": [],
594 | "source": [
595 | "np.random.shuffle(all_data)"
596 | ]
597 | },
598 | {
599 | "cell_type": "code",
600 | "execution_count": 15,
601 | "metadata": {},
602 | "outputs": [],
603 | "source": [
604 | "all_data_t = np.zeros((all_data.shape[0], 15, 4))\n",
605 | "\n",
606 | "ctr = 0\n",
607 | "for i, j in zip(range(0, 30, 2), range(30, 60, 2)):\n",
608 | " all_data_t[:, ctr, :] = np.hstack([all_data[:, i:i+2], all_data[:, j:j+2]])\n",
609 | " ctr += 1"
610 | ]
611 | },
612 | {
613 | "cell_type": "code",
614 | "execution_count": 16,
615 | "metadata": {},
616 | "outputs": [],
617 | "source": [
618 | "X, y = all_data_t, all_data[:, -1]"
619 | ]
620 | },
621 | {
622 | "cell_type": "markdown",
623 | "metadata": {},
624 | "source": [
625 | "## Training Phase\n",
626 | "This Phase defines parameters of the model, the model itself along with its training to produce a simple RNN that can predict whether a person is the genuine holder of account or not."
627 | ]
628 | },
629 | {
630 | "cell_type": "markdown",
631 | "metadata": {},
632 | "source": [
633 | "### Some Params and HyperParams"
634 | ]
635 | },
636 | {
637 | "cell_type": "code",
638 | "execution_count": 17,
639 | "metadata": {},
640 | "outputs": [
641 | {
642 | "name": "stderr",
643 | "output_type": "stream",
644 | "text": [
645 | "Using TensorFlow backend.\n"
646 | ]
647 | }
648 | ],
649 | "source": [
650 | "from keras.layers import Dense, Activation, Dropout, Input, LSTM, Reshape, Lambda, RepeatVector, Concatenate\n",
651 | "from keras.initializers import glorot_uniform\n",
652 | "from keras.utils import to_categorical\n",
653 | "from keras.models import Model\n",
654 | "from keras.optimizers import Adam"
655 | ]
656 | },
657 | {
658 | "cell_type": "code",
659 | "execution_count": 18,
660 | "metadata": {},
661 | "outputs": [],
662 | "source": [
663 | "VALIDATION_SPLIT = 0.1\n",
664 | "\n",
665 | "INPUT_SHAPE = [None, 2]\n",
666 | "\n",
667 | "BATCH_SIZE = 32\n",
668 | "\n",
669 | "EPOCHS = 20"
670 | ]
671 | },
672 | {
673 | "cell_type": "code",
674 | "execution_count": 19,
675 | "metadata": {},
676 | "outputs": [],
677 | "source": [
678 | "def train_dev_split(x, y, val_split=0.1):\n",
679 | " m = x.shape[0]\n",
680 | " val_size = int(0.1 * m)\n",
681 | " return x[:-val_size], y[:, :-val_size, :], x[-val_size:], y[:, -val_size:, :]"
682 | ]
683 | },
684 | {
685 | "cell_type": "code",
686 | "execution_count": 20,
687 | "metadata": {},
688 | "outputs": [],
689 | "source": [
690 | "y = to_categorical(y)\n",
691 | "\n",
692 | "y_ = np.zeros((15, y.shape[0], y.shape[1]))\n",
693 | "\n",
694 | "for i in range(15):\n",
695 | " y_[i, :, :] = y"
696 | ]
697 | },
698 | {
699 | "cell_type": "code",
700 | "execution_count": 21,
701 | "metadata": {},
702 | "outputs": [
703 | {
704 | "data": {
705 | "text/plain": [
706 | "(array([ 0., 1.]), array([ 0., 1.]))"
707 | ]
708 | },
709 | "execution_count": 21,
710 | "metadata": {},
711 | "output_type": "execute_result"
712 | }
713 | ],
714 | "source": [
715 | "y_[0, 0, :], y[0]"
716 | ]
717 | },
718 | {
719 | "cell_type": "code",
720 | "execution_count": 22,
721 | "metadata": {},
722 | "outputs": [
723 | {
724 | "data": {
725 | "text/plain": [
726 | "((13770, 15, 4), (15, 13770, 2), (1530, 15, 4), (15, 1530, 2))"
727 | ]
728 | },
729 | "execution_count": 22,
730 | "metadata": {},
731 | "output_type": "execute_result"
732 | }
733 | ],
734 | "source": [
735 | "x_train, y_train, x_test, y_test = train_dev_split(X, y_)\n",
736 | "\n",
737 | "x_train.shape, y_train.shape, x_test.shape, y_test.shape"
738 | ]
739 | },
740 | {
741 | "cell_type": "code",
742 | "execution_count": 23,
743 | "metadata": {},
744 | "outputs": [],
745 | "source": [
746 | "n_a = 10\n",
747 | "n_out = 2"
748 | ]
749 | },
750 | {
751 | "cell_type": "code",
752 | "execution_count": 24,
753 | "metadata": {},
754 | "outputs": [],
755 | "source": [
756 | "reshapor = Reshape((1, 4))\n",
757 | "LSTM_cell = LSTM(n_a, return_state = True)\n",
758 | "densor = Dense(n_out, activation='softmax')"
759 | ]
760 | },
761 | {
762 | "cell_type": "code",
763 | "execution_count": 25,
764 | "metadata": {},
765 | "outputs": [],
766 | "source": [
767 | "def keystroke_model(Tx, n_in, n_a, n_out):\n",
768 | " X = Input(shape=(Tx, n_in))\n",
769 | " \n",
770 | " a0 = Input(shape=(n_a,), name='a0')\n",
771 | " c0 = Input(shape=(n_a,), name='c0')\n",
772 | " a = a0\n",
773 | " c = c0\n",
774 | " \n",
775 | " outputs = []\n",
776 | "\n",
777 | " for t in range(Tx):\n",
778 | " \n",
779 | " x = Lambda(lambda x: X[:, t, :])(X)\n",
780 | " x = reshapor(x)\n",
781 | "\n",
782 | " a, _, c = LSTM_cell(x, initial_state=[a, c])\n",
783 | "\n",
784 | " out = densor(a)\n",
785 | "\n",
786 | " outputs.append(out)\n",
787 | "\n",
788 | " model = Model(inputs=[X, a0, c0], outputs=outputs)\n",
789 | " \n",
790 | " return model"
791 | ]
792 | },
793 | {
794 | "cell_type": "code",
795 | "execution_count": 26,
796 | "metadata": {},
797 | "outputs": [],
798 | "source": [
799 | "model = keystroke_model(15, 4, n_a, n_out)"
800 | ]
801 | },
802 | {
803 | "cell_type": "code",
804 | "execution_count": 27,
805 | "metadata": {},
806 | "outputs": [],
807 | "source": [
808 | "opt = Adam(lr=0.01, beta_1=0.9, beta_2=0.999, decay=0.01)\n",
809 | "\n",
810 | "model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])"
811 | ]
812 | },
813 | {
814 | "cell_type": "code",
815 | "execution_count": 28,
816 | "metadata": {},
817 | "outputs": [
818 | {
819 | "name": "stdout",
820 | "output_type": "stream",
821 | "text": [
822 | "__________________________________________________________________________________________________\n",
823 | "Layer (type) Output Shape Param # Connected to \n",
824 | "==================================================================================================\n",
825 | "input_1 (InputLayer) (None, 15, 4) 0 \n",
826 | "__________________________________________________________________________________________________\n",
827 | "lambda_1 (Lambda) (None, 4) 0 input_1[0][0] \n",
828 | "__________________________________________________________________________________________________\n",
829 | "reshape_1 (Reshape) (None, 1, 4) 0 lambda_1[0][0] \n",
830 | " lambda_2[0][0] \n",
831 | " lambda_3[0][0] \n",
832 | " lambda_4[0][0] \n",
833 | " lambda_5[0][0] \n",
834 | " lambda_6[0][0] \n",
835 | " lambda_7[0][0] \n",
836 | " lambda_8[0][0] \n",
837 | " lambda_9[0][0] \n",
838 | " lambda_10[0][0] \n",
839 | " lambda_11[0][0] \n",
840 | " lambda_12[0][0] \n",
841 | " lambda_13[0][0] \n",
842 | " lambda_14[0][0] \n",
843 | " lambda_15[0][0] \n",
844 | "__________________________________________________________________________________________________\n",
845 | "a0 (InputLayer) (None, 10) 0 \n",
846 | "__________________________________________________________________________________________________\n",
847 | "c0 (InputLayer) (None, 10) 0 \n",
848 | "__________________________________________________________________________________________________\n",
849 | "lambda_2 (Lambda) (None, 4) 0 input_1[0][0] \n",
850 | "__________________________________________________________________________________________________\n",
851 | "lstm_1 (LSTM) [(None, 10), (None, 600 reshape_1[0][0] \n",
852 | " a0[0][0] \n",
853 | " c0[0][0] \n",
854 | " reshape_1[1][0] \n",
855 | " lstm_1[0][0] \n",
856 | " lstm_1[0][2] \n",
857 | " reshape_1[2][0] \n",
858 | " lstm_1[1][0] \n",
859 | " lstm_1[1][2] \n",
860 | " reshape_1[3][0] \n",
861 | " lstm_1[2][0] \n",
862 | " lstm_1[2][2] \n",
863 | " reshape_1[4][0] \n",
864 | " lstm_1[3][0] \n",
865 | " lstm_1[3][2] \n",
866 | " reshape_1[5][0] \n",
867 | " lstm_1[4][0] \n",
868 | " lstm_1[4][2] \n",
869 | " reshape_1[6][0] \n",
870 | " lstm_1[5][0] \n",
871 | " lstm_1[5][2] \n",
872 | " reshape_1[7][0] \n",
873 | " lstm_1[6][0] \n",
874 | " lstm_1[6][2] \n",
875 | " reshape_1[8][0] \n",
876 | " lstm_1[7][0] \n",
877 | " lstm_1[7][2] \n",
878 | " reshape_1[9][0] \n",
879 | " lstm_1[8][0] \n",
880 | " lstm_1[8][2] \n",
881 | " reshape_1[10][0] \n",
882 | " lstm_1[9][0] \n",
883 | " lstm_1[9][2] \n",
884 | " reshape_1[11][0] \n",
885 | " lstm_1[10][0] \n",
886 | " lstm_1[10][2] \n",
887 | " reshape_1[12][0] \n",
888 | " lstm_1[11][0] \n",
889 | " lstm_1[11][2] \n",
890 | " reshape_1[13][0] \n",
891 | " lstm_1[12][0] \n",
892 | " lstm_1[12][2] \n",
893 | " reshape_1[14][0] \n",
894 | " lstm_1[13][0] \n",
895 | " lstm_1[13][2] \n",
896 | "__________________________________________________________________________________________________\n",
897 | "lambda_3 (Lambda) (None, 4) 0 input_1[0][0] \n",
898 | "__________________________________________________________________________________________________\n",
899 | "lambda_4 (Lambda) (None, 4) 0 input_1[0][0] \n",
900 | "__________________________________________________________________________________________________\n",
901 | "lambda_5 (Lambda) (None, 4) 0 input_1[0][0] \n",
902 | "__________________________________________________________________________________________________\n",
903 | "lambda_6 (Lambda) (None, 4) 0 input_1[0][0] \n",
904 | "__________________________________________________________________________________________________\n",
905 | "lambda_7 (Lambda) (None, 4) 0 input_1[0][0] \n",
906 | "__________________________________________________________________________________________________\n",
907 | "lambda_8 (Lambda) (None, 4) 0 input_1[0][0] \n",
908 | "__________________________________________________________________________________________________\n",
909 | "lambda_9 (Lambda) (None, 4) 0 input_1[0][0] \n",
910 | "__________________________________________________________________________________________________\n",
911 | "lambda_10 (Lambda) (None, 4) 0 input_1[0][0] \n",
912 | "__________________________________________________________________________________________________\n",
913 | "lambda_11 (Lambda) (None, 4) 0 input_1[0][0] \n",
914 | "__________________________________________________________________________________________________\n",
915 | "lambda_12 (Lambda) (None, 4) 0 input_1[0][0] \n",
916 | "__________________________________________________________________________________________________\n",
917 | "lambda_13 (Lambda) (None, 4) 0 input_1[0][0] \n",
918 | "__________________________________________________________________________________________________\n",
919 | "lambda_14 (Lambda) (None, 4) 0 input_1[0][0] \n",
920 | "__________________________________________________________________________________________________\n",
921 | "lambda_15 (Lambda) (None, 4) 0 input_1[0][0] \n",
922 | "__________________________________________________________________________________________________\n",
923 | "dense_1 (Dense) (None, 2) 22 lstm_1[0][0] \n",
924 | " lstm_1[1][0] \n",
925 | " lstm_1[2][0] \n",
926 | " lstm_1[3][0] \n",
927 | " lstm_1[4][0] \n",
928 | " lstm_1[5][0] \n",
929 | " lstm_1[6][0] \n",
930 | " lstm_1[7][0] \n",
931 | " lstm_1[8][0] \n",
932 | " lstm_1[9][0] \n",
933 | " lstm_1[10][0] \n",
934 | " lstm_1[11][0] \n",
935 | " lstm_1[12][0] \n",
936 | " lstm_1[13][0] \n",
937 | " lstm_1[14][0] \n",
938 | "==================================================================================================\n",
939 | "Total params: 622\n",
940 | "Trainable params: 622\n",
941 | "Non-trainable params: 0\n",
942 | "__________________________________________________________________________________________________\n"
943 | ]
944 | }
945 | ],
946 | "source": [
947 | "model.summary()"
948 | ]
949 | },
950 | {
951 | "cell_type": "code",
952 | "execution_count": 29,
953 | "metadata": {},
954 | "outputs": [],
955 | "source": [
956 | "m = x_train.shape[0]\n",
957 | "a0 = np.zeros((m, n_a))\n",
958 | "c0 = np.zeros((m, n_a))"
959 | ]
960 | },
961 | {
962 | "cell_type": "code",
963 | "execution_count": 31,
964 | "metadata": {},
965 | "outputs": [
966 | {
967 | "name": "stdout",
968 | "output_type": "stream",
969 | "text": [
970 | "Epoch 1/10\n",
971 | "13770/13770 [==============================] - 56s 4ms/step - loss: 10.3848 - dense_1_loss_1: 0.6944 - dense_1_loss_2: 0.6916 - dense_1_loss_3: 0.6912 - dense_1_loss_4: 0.6914 - dense_1_loss_5: 0.6906 - dense_1_loss_6: 0.6920 - dense_1_loss_7: 0.6923 - dense_1_loss_8: 0.6927 - dense_1_loss_9: 0.6925 - dense_1_loss_10: 0.6931 - dense_1_loss_11: 0.6929 - dense_1_loss_12: 0.6928 - dense_1_loss_13: 0.6927 - dense_1_loss_14: 0.6927 - dense_1_loss_15: 0.6918 - dense_1_acc_1: 0.4810 - dense_1_acc_2: 0.5246 - dense_1_acc_3: 0.5251 - dense_1_acc_4: 0.5248 - dense_1_acc_5: 0.5301 - dense_1_acc_6: 0.5130 - dense_1_acc_7: 0.5113 - dense_1_acc_8: 0.5106 - dense_1_acc_9: 0.5076 - dense_1_acc_10: 0.5081 - dense_1_acc_11: 0.5081 - dense_1_acc_12: 0.5078 - dense_1_acc_13: 0.5093 - dense_1_acc_14: 0.5089 - dense_1_acc_15: 0.5086: 11s - loss: 10.3932 - dense_1_loss_1: 0.6946 - dense_1_loss_2: 0.6922 - dense_1_loss_3: 0.6920 - dense_1_loss_4: 0.6922 - dense_1_loss_5: 0.6916 - dense_1_loss_6: 0.6925 - dense_1_loss_7: 0.6928 - dense_1_loss_8: 0.6930 - dense_1_loss_9: 0.6932 - dense_1_loss_10: 0.6935 - dense_1_loss_11: 0.6933 - dense_1_loss_12: 0.6933 - dense_1_loss_13: 0.6932 - dense_1_loss_14: 0.6932 - dense_1_loss_15: 0.6927 - dense_1_acc_1: 0.4784 - dense_1_acc_2: 0.5163 - dense_1_acc_3: 0.5151 - dense_1_acc_4: 0.5158 - dense_1_acc_5: 0.5212 - dense_1_acc_6: 0.5150 - dense_1_acc_7: 0.5135 - dense_1_acc_8: 0.5130 - dense_1_acc_9: 0.5055 - dense_1_acc_10: 0.5064 - dense_1_acc_11: 0.50\n",
972 | "Epoch 2/10\n",
973 | "13770/13770 [==============================] - 49s 4ms/step - loss: 9.6077 - dense_1_loss_1: 0.6934 - dense_1_loss_2: 0.6853 - dense_1_loss_3: 0.6792 - dense_1_loss_4: 0.6721 - dense_1_loss_5: 0.6626 - dense_1_loss_6: 0.6462 - dense_1_loss_7: 0.6392 - dense_1_loss_8: 0.6265 - dense_1_loss_9: 0.6190 - dense_1_loss_10: 0.6149 - dense_1_loss_11: 0.6108 - dense_1_loss_12: 0.6105 - dense_1_loss_13: 0.6103 - dense_1_loss_14: 0.6139 - dense_1_loss_15: 0.6240 - dense_1_acc_1: 0.4833 - dense_1_acc_2: 0.5985 - dense_1_acc_3: 0.6121 - dense_1_acc_4: 0.6129 - dense_1_acc_5: 0.6158 - dense_1_acc_6: 0.6251 - dense_1_acc_7: 0.6381 - dense_1_acc_8: 0.6356 - dense_1_acc_9: 0.6411 - dense_1_acc_10: 0.6469 - dense_1_acc_11: 0.6493 - dense_1_acc_12: 0.6477 - dense_1_acc_13: 0.6486 - dense_1_acc_14: 0.6434 - dense_1_acc_15: 0.6433\n",
974 | "Epoch 3/10\n",
975 | "13770/13770 [==============================] - 49s 4ms/step - loss: 9.0376 - dense_1_loss_1: 0.6912 - dense_1_loss_2: 0.6796 - dense_1_loss_3: 0.6677 - dense_1_loss_4: 0.6541 - dense_1_loss_5: 0.6386 - dense_1_loss_6: 0.6075 - dense_1_loss_7: 0.5959 - dense_1_loss_8: 0.5776 - dense_1_loss_9: 0.5702 - dense_1_loss_10: 0.5629 - dense_1_loss_11: 0.5564 - dense_1_loss_12: 0.5562 - dense_1_loss_13: 0.5541 - dense_1_loss_14: 0.5566 - dense_1_loss_15: 0.5688 - dense_1_acc_1: 0.5065 - dense_1_acc_2: 0.6169 - dense_1_acc_3: 0.6268 - dense_1_acc_4: 0.6336 - dense_1_acc_5: 0.6393 - dense_1_acc_6: 0.6777 - dense_1_acc_7: 0.7076 - dense_1_acc_8: 0.7195 - dense_1_acc_9: 0.7211 - dense_1_acc_10: 0.7277 - dense_1_acc_11: 0.7283 - dense_1_acc_12: 0.7275 - dense_1_acc_13: 0.7284 - dense_1_acc_14: 0.7253 - dense_1_acc_15: 0.7248\n",
976 | "Epoch 4/10\n",
977 | "13770/13770 [==============================] - 53s 4ms/step - loss: 8.7896 - dense_1_loss_1: 0.6898 - dense_1_loss_2: 0.6765 - dense_1_loss_3: 0.6621 - dense_1_loss_4: 0.6466 - dense_1_loss_5: 0.6297 - dense_1_loss_6: 0.5935 - dense_1_loss_7: 0.5781 - dense_1_loss_8: 0.5577 - dense_1_loss_9: 0.5499 - dense_1_loss_10: 0.5406 - dense_1_loss_11: 0.5328 - dense_1_loss_12: 0.5324 - dense_1_loss_13: 0.5293 - dense_1_loss_14: 0.5303 - dense_1_loss_15: 0.5402 - dense_1_acc_1: 0.5075 - dense_1_acc_2: 0.6200 - dense_1_acc_3: 0.6325 - dense_1_acc_4: 0.6382 - dense_1_acc_5: 0.6402 - dense_1_acc_6: 0.6963 - dense_1_acc_7: 0.7275 - dense_1_acc_8: 0.7453 - dense_1_acc_9: 0.7449 - dense_1_acc_10: 0.7474 - dense_1_acc_11: 0.7522 - dense_1_acc_12: 0.7502 - dense_1_acc_13: 0.7530 - dense_1_acc_14: 0.7525 - dense_1_acc_15: 0.7527\n",
978 | "Epoch 5/10\n",
979 | "13770/13770 [==============================] - 50s 4ms/step - loss: 8.6522 - dense_1_loss_1: 0.6887 - dense_1_loss_2: 0.6739 - dense_1_loss_3: 0.6579 - dense_1_loss_4: 0.6412 - dense_1_loss_5: 0.6236 - dense_1_loss_6: 0.5845 - dense_1_loss_7: 0.5674 - dense_1_loss_8: 0.5466 - dense_1_loss_9: 0.5389 - dense_1_loss_10: 0.5292 - dense_1_loss_11: 0.5208 - dense_1_loss_12: 0.5201 - dense_1_loss_13: 0.5168 - dense_1_loss_14: 0.5172 - dense_1_loss_15: 0.5254 - dense_1_acc_1: 0.5094 - dense_1_acc_2: 0.6211 - dense_1_acc_3: 0.6336 - dense_1_acc_4: 0.6452 - dense_1_acc_5: 0.6438 - dense_1_acc_6: 0.7056 - dense_1_acc_7: 0.7328 - dense_1_acc_8: 0.7508 - dense_1_acc_9: 0.7524 - dense_1_acc_10: 0.7554 - dense_1_acc_11: 0.7601 - dense_1_acc_12: 0.7588 - dense_1_acc_13: 0.7614 - dense_1_acc_14: 0.7630 - dense_1_acc_15: 0.7628\n",
980 | "Epoch 6/10\n",
981 | "13770/13770 [==============================] - 50s 4ms/step - loss: 8.5593 - dense_1_loss_1: 0.6877 - dense_1_loss_2: 0.6717 - dense_1_loss_3: 0.6544 - dense_1_loss_4: 0.6365 - dense_1_loss_5: 0.6186 - dense_1_loss_6: 0.5780 - dense_1_loss_7: 0.5602 - dense_1_loss_8: 0.5397 - dense_1_loss_9: 0.5321 - dense_1_loss_10: 0.5218 - dense_1_loss_11: 0.5131 - dense_1_loss_12: 0.5124 - dense_1_loss_13: 0.5086 - dense_1_loss_14: 0.5085 - dense_1_loss_15: 0.5161 - dense_1_acc_1: 0.5081 - dense_1_acc_2: 0.6282 - dense_1_acc_3: 0.6383 - dense_1_acc_4: 0.6476 - dense_1_acc_5: 0.6470 - dense_1_acc_6: 0.7078 - dense_1_acc_7: 0.7378 - dense_1_acc_8: 0.7574 - dense_1_acc_9: 0.7574 - dense_1_acc_10: 0.7619 - dense_1_acc_11: 0.7644 - dense_1_acc_12: 0.7639 - dense_1_acc_13: 0.7658 - dense_1_acc_14: 0.7679 - dense_1_acc_15: 0.7676\n",
982 | "Epoch 7/10\n",
983 | "13770/13770 [==============================] - 51s 4ms/step - loss: 8.5034 - dense_1_loss_1: 0.6868 - dense_1_loss_2: 0.6698 - dense_1_loss_3: 0.6514 - dense_1_loss_4: 0.6328 - dense_1_loss_5: 0.6147 - dense_1_loss_6: 0.5735 - dense_1_loss_7: 0.5555 - dense_1_loss_8: 0.5358 - dense_1_loss_9: 0.5283 - dense_1_loss_10: 0.5176 - dense_1_loss_11: 0.5087 - dense_1_loss_12: 0.5081 - dense_1_loss_13: 0.5042 - dense_1_loss_14: 0.5044 - dense_1_loss_15: 0.5118 - dense_1_acc_1: 0.5094 - dense_1_acc_2: 0.6304 - dense_1_acc_3: 0.6410 - dense_1_acc_4: 0.6476 - dense_1_acc_5: 0.6470 - dense_1_acc_6: 0.7105 - dense_1_acc_7: 0.7394 - dense_1_acc_8: 0.7588 - dense_1_acc_9: 0.7577 - dense_1_acc_10: 0.7635 - dense_1_acc_11: 0.7676 - dense_1_acc_12: 0.7670 - dense_1_acc_13: 0.7698 - dense_1_acc_14: 0.7710 - dense_1_acc_15: 0.7702\n",
984 | "Epoch 8/10\n",
985 | "13770/13770 [==============================] - 51s 4ms/step - loss: 8.4593 - dense_1_loss_1: 0.6861 - dense_1_loss_2: 0.6684 - dense_1_loss_3: 0.6493 - dense_1_loss_4: 0.6298 - dense_1_loss_5: 0.6115 - dense_1_loss_6: 0.5701 - dense_1_loss_7: 0.5525 - dense_1_loss_8: 0.5334 - dense_1_loss_9: 0.5259 - dense_1_loss_10: 0.5143 - dense_1_loss_11: 0.5050 - dense_1_loss_12: 0.5044 - dense_1_loss_13: 0.5003 - dense_1_loss_14: 0.5003 - dense_1_loss_15: 0.5079 - dense_1_acc_1: 0.5147 - dense_1_acc_2: 0.6299 - dense_1_acc_3: 0.6415 - dense_1_acc_4: 0.6495 - dense_1_acc_5: 0.6468 - dense_1_acc_6: 0.7113 - dense_1_acc_7: 0.7410 - dense_1_acc_8: 0.7611 - dense_1_acc_9: 0.7605 - dense_1_acc_10: 0.7646 - dense_1_acc_11: 0.7709 - dense_1_acc_12: 0.7683 - dense_1_acc_13: 0.7714 - dense_1_acc_14: 0.7745 - dense_1_acc_15: 0.7747\n",
986 | "Epoch 9/10\n",
987 | "13770/13770 [==============================] - 51s 4ms/step - loss: 8.4227 - dense_1_loss_1: 0.6855 - dense_1_loss_2: 0.6675 - dense_1_loss_3: 0.6478 - dense_1_loss_4: 0.6282 - dense_1_loss_5: 0.6105 - dense_1_loss_6: 0.5681 - dense_1_loss_7: 0.5491 - dense_1_loss_8: 0.5302 - dense_1_loss_9: 0.5228 - dense_1_loss_10: 0.5106 - dense_1_loss_11: 0.5012 - dense_1_loss_12: 0.5010 - dense_1_loss_13: 0.4971 - dense_1_loss_14: 0.4975 - dense_1_loss_15: 0.5058 - dense_1_acc_1: 0.5182 - dense_1_acc_2: 0.6318 - dense_1_acc_3: 0.6430 - dense_1_acc_4: 0.6506 - dense_1_acc_5: 0.6499 - dense_1_acc_6: 0.7138 - dense_1_acc_7: 0.7463 - dense_1_acc_8: 0.7618 - dense_1_acc_9: 0.7622 - dense_1_acc_10: 0.7650 - dense_1_acc_11: 0.7714 - dense_1_acc_12: 0.7697 - dense_1_acc_13: 0.7744 - dense_1_acc_14: 0.7765 - dense_1_acc_15: 0.7749\n",
988 | "Epoch 10/10\n"
989 | ]
990 | },
991 | {
992 | "name": "stdout",
993 | "output_type": "stream",
994 | "text": [
995 | "13770/13770 [==============================] - 50s 4ms/step - loss: 8.3825 - dense_1_loss_1: 0.6850 - dense_1_loss_2: 0.6665 - dense_1_loss_3: 0.6463 - dense_1_loss_4: 0.6262 - dense_1_loss_5: 0.6081 - dense_1_loss_6: 0.5651 - dense_1_loss_7: 0.5465 - dense_1_loss_8: 0.5276 - dense_1_loss_9: 0.5200 - dense_1_loss_10: 0.5072 - dense_1_loss_11: 0.4977 - dense_1_loss_12: 0.4974 - dense_1_loss_13: 0.4934 - dense_1_loss_14: 0.4936 - dense_1_loss_15: 0.5019 - dense_1_acc_1: 0.5252 - dense_1_acc_2: 0.6338 - dense_1_acc_3: 0.6433 - dense_1_acc_4: 0.6529 - dense_1_acc_5: 0.6486 - dense_1_acc_6: 0.7179 - dense_1_acc_7: 0.7445 - dense_1_acc_8: 0.7640 - dense_1_acc_9: 0.7635 - dense_1_acc_10: 0.7683 - dense_1_acc_11: 0.7759 - dense_1_acc_12: 0.7744 - dense_1_acc_13: 0.7805 - dense_1_acc_14: 0.7815 - dense_1_acc_15: 0.7796\n"
996 | ]
997 | },
998 | {
999 | "data": {
1000 | "text/plain": [
1001 | ""
1002 | ]
1003 | },
1004 | "execution_count": 31,
1005 | "metadata": {},
1006 | "output_type": "execute_result"
1007 | }
1008 | ],
1009 | "source": [
1010 | "model.fit([x_train, a0, c0], list(y_train), epochs=10)"
1011 | ]
1012 | },
1013 | {
1014 | "cell_type": "code",
1015 | "execution_count": 32,
1016 | "metadata": {},
1017 | "outputs": [],
1018 | "source": [
1019 | "m_t = x_test.shape[0]\n",
1020 | "a0_t = np.zeros((m_t, n_a))\n",
1021 | "c0_t = np.zeros((m_t, n_a))"
1022 | ]
1023 | },
1024 | {
1025 | "cell_type": "code",
1026 | "execution_count": 34,
1027 | "metadata": {},
1028 | "outputs": [
1029 | {
1030 | "name": "stdout",
1031 | "output_type": "stream",
1032 | "text": [
1033 | "1530/1530 [==============================] - 3s 2ms/step\n"
1034 | ]
1035 | },
1036 | {
1037 | "data": {
1038 | "text/plain": [
1039 | "[8.1394441193225333,\n",
1040 | " 0.68649219843297227,\n",
1041 | " 0.66842293131585218,\n",
1042 | " 0.6474493969499675,\n",
1043 | " 0.62604353209726171,\n",
1044 | " 0.60595984139473613,\n",
1045 | " 0.55427271182241,\n",
1046 | " 0.53408347352657448,\n",
1047 | " 0.51291458419725011,\n",
1048 | " 0.50179924154593269,\n",
1049 | " 0.48426854883144105,\n",
1050 | " 0.47200996883554397,\n",
1051 | " 0.467594226980521,\n",
1052 | " 0.45899881054373348,\n",
1053 | " 0.45738684663585588,\n",
1054 | " 0.46174781665303349,\n",
1055 | " 0.5294117646279678,\n",
1056 | " 0.63333333372290612,\n",
1057 | " 0.65163398677227546,\n",
1058 | " 0.65947712457257934,\n",
1059 | " 0.67450980423322693,\n",
1060 | " 0.73464052264207325,\n",
1061 | " 0.76143790880839035,\n",
1062 | " 0.76928104551789023,\n",
1063 | " 0.78169934663897245,\n",
1064 | " 0.78888888912263255,\n",
1065 | " 0.79607843160629277,\n",
1066 | " 0.79411764674716523,\n",
1067 | " 0.79411764674716523,\n",
1068 | " 0.80196078400206716,\n",
1069 | " 0.80326797354455093]"
1070 | ]
1071 | },
1072 | "execution_count": 34,
1073 | "metadata": {},
1074 | "output_type": "execute_result"
1075 | }
1076 | ],
1077 | "source": [
1078 | "model.evaluate([x_test, a0_t, c0_t], list(y_test))"
1079 | ]
1080 | },
1081 | {
1082 | "cell_type": "code",
1083 | "execution_count": 36,
1084 | "metadata": {},
1085 | "outputs": [],
1086 | "source": [
1087 | "from keras.utils import plot_model\n",
1088 | "plot_model(model, to_file='model.png')"
1089 | ]
1090 | },
1091 | {
1092 | "cell_type": "markdown",
1093 | "metadata": {},
1094 | "source": [
1095 | ""
1096 | ]
1097 | },
1098 | {
1099 | "cell_type": "code",
1100 | "execution_count": 45,
1101 | "metadata": {},
1102 | "outputs": [],
1103 | "source": [
1104 | "model.save_weights('model.h5')"
1105 | ]
1106 | }
1107 | ],
1108 | "metadata": {
1109 | "kernelspec": {
1110 | "display_name": "Python 3",
1111 | "language": "python",
1112 | "name": "python3"
1113 | },
1114 | "language_info": {
1115 | "codemirror_mode": {
1116 | "name": "ipython",
1117 | "version": 3
1118 | },
1119 | "file_extension": ".py",
1120 | "mimetype": "text/x-python",
1121 | "name": "python",
1122 | "nbconvert_exporter": "python",
1123 | "pygments_lexer": "ipython3",
1124 | "version": "3.5.1"
1125 | }
1126 | },
1127 | "nbformat": 4,
1128 | "nbformat_minor": 2
1129 | }
1130 |
--------------------------------------------------------------------------------
/model.h5:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piyush2896/Keystroke-Dynamics-Using-LSTMs/bcb1a361e8fad94ac45daa13e48b1b42c68984b2/model.h5
--------------------------------------------------------------------------------
/model.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piyush2896/Keystroke-Dynamics-Using-LSTMs/bcb1a361e8fad94ac45daa13e48b1b42c68984b2/model.png
--------------------------------------------------------------------------------