File size: 59,727 Bytes
d87258b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "_cell_guid": "79c7e3d0-c299-4dcb-8224-4455121ee9b0",
    "_uuid": "d629ff2d2480ee46fbb7e2d37f6b5fab8052498a",
    "execution": {
     "iopub.execute_input": "2023-02-20T08:40:54.388846Z",
     "iopub.status.busy": "2023-02-20T08:40:54.388169Z",
     "iopub.status.idle": "2023-02-20T08:41:00.443644Z",
     "shell.execute_reply": "2023-02-20T08:41:00.442592Z",
     "shell.execute_reply.started": "2023-02-20T08:40:54.388807Z"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd \n",
    "import matplotlib.pyplot as plt\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras import layers\n",
    "from time import perf_counter \n",
    "import os\n",
    "import gradio as gr "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-02-20T08:41:00.448605Z",
     "iopub.status.busy": "2023-02-20T08:41:00.448215Z",
     "iopub.status.idle": "2023-02-20T08:41:00.452903Z",
     "shell.execute_reply": "2023-02-20T08:41:00.451701Z",
     "shell.execute_reply.started": "2023-02-20T08:41:00.448568Z"
    }
   },
   "outputs": [],
   "source": [
    "## Defining batch specfications\n",
    "batch_size = 100\n",
    "img_height = 250\n",
    "img_width = 250"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "ename": "NotFoundError",
     "evalue": "Could not find directory /kaggle/input/accident-detection-from-cctv-footage/data/train",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNotFoundError\u001b[0m                             Traceback (most recent call last)",
      "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_49476/1820641928.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[1;31m## loading training set\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m training_ds = tf.keras.preprocessing.image_dataset_from_directory(\n\u001b[0m\u001b[0;32m      3\u001b[0m     \u001b[1;34m'/kaggle/input/accident-detection-from-cctv-footage/data/train'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      4\u001b[0m     \u001b[0mseed\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m42\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      5\u001b[0m     \u001b[0mimage_size\u001b[0m\u001b[1;33m=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mimg_height\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mimg_width\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m~\\anaconda3\\lib\\site-packages\\keras\\utils\\image_dataset.py\u001b[0m in \u001b[0;36mimage_dataset_from_directory\u001b[1;34m(directory, labels, label_mode, class_names, color_mode, batch_size, image_size, shuffle, seed, validation_split, subset, interpolation, follow_links, crop_to_aspect_ratio, **kwargs)\u001b[0m\n\u001b[0;32m    205\u001b[0m     \u001b[1;32mif\u001b[0m \u001b[0mseed\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    206\u001b[0m         \u001b[0mseed\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrandom\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrandint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1e6\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 207\u001b[1;33m     image_paths, labels, class_names = dataset_utils.index_directory(\n\u001b[0m\u001b[0;32m    208\u001b[0m         \u001b[0mdirectory\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    209\u001b[0m         \u001b[0mlabels\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m~\\anaconda3\\lib\\site-packages\\keras\\utils\\dataset_utils.py\u001b[0m in \u001b[0;36mindex_directory\u001b[1;34m(directory, labels, formats, class_names, shuffle, seed, follow_links)\u001b[0m\n\u001b[0;32m    532\u001b[0m     \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    533\u001b[0m         \u001b[0msubdirs\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 534\u001b[1;33m         \u001b[1;32mfor\u001b[0m \u001b[0msubdir\u001b[0m \u001b[1;32min\u001b[0m \u001b[0msorted\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtf\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mio\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgfile\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlistdir\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdirectory\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    535\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mtf\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mio\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgfile\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0misdir\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtf\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mio\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgfile\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdirectory\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msubdir\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    536\u001b[0m                 \u001b[1;32mif\u001b[0m \u001b[0msubdir\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mendswith\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"/\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m~\\anaconda3\\lib\\site-packages\\tensorflow\\python\\lib\\io\\file_io.py\u001b[0m in \u001b[0;36mlist_directory_v2\u001b[1;34m(path)\u001b[0m\n\u001b[0;32m    766\u001b[0m   \"\"\"\n\u001b[0;32m    767\u001b[0m   \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mis_directory\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpath\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 768\u001b[1;33m     raise errors.NotFoundError(\n\u001b[0m\u001b[0;32m    769\u001b[0m         \u001b[0mnode_def\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    770\u001b[0m         \u001b[0mop\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNotFoundError\u001b[0m: Could not find directory /kaggle/input/accident-detection-from-cctv-footage/data/train"
     ]
    }
   ],
   "source": [
    "## loading training set\n",
    "training_ds = tf.keras.preprocessing.image_dataset_from_directory(\n",
    "    '/kaggle/input/accident-detection-from-cctv-footage/data/train',\n",
    "    seed=42,\n",
    "    image_size= (img_height, img_width),\n",
    "    batch_size=batch_size\n",
    "\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-02-20T08:41:01.012308Z",
     "iopub.status.busy": "2023-02-20T08:41:01.012015Z",
     "iopub.status.idle": "2023-02-20T08:41:01.184826Z",
     "shell.execute_reply": "2023-02-20T08:41:01.183854Z",
     "shell.execute_reply.started": "2023-02-20T08:41:01.012279Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 98 files belonging to 2 classes.\n"
     ]
    }
   ],
   "source": [
    "## loading validation dataset\n",
    "validation_ds =  tf.keras.preprocessing.image_dataset_from_directory(\n",
    "    '/kaggle/input/accident-detection-from-cctv-footage/data/val',\n",
    "    seed=42,\n",
    "    image_size= (img_height, img_width),\n",
    "    batch_size=batch_size)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-02-20T08:41:01.188186Z",
     "iopub.status.busy": "2023-02-20T08:41:01.187793Z",
     "iopub.status.idle": "2023-02-20T08:41:01.370586Z",
     "shell.execute_reply": "2023-02-20T08:41:01.369561Z",
     "shell.execute_reply.started": "2023-02-20T08:41:01.188143Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 100 files belonging to 2 classes.\n"
     ]
    }
   ],
   "source": [
    "testing_ds = tf.keras.preprocessing.image_dataset_from_directory(\n",
    "    '/kaggle/input/accident-detection-from-cctv-footage/data/test',\n",
    "    seed=42,\n",
    "    image_size= (img_height, img_width),\n",
    "    batch_size=batch_size)\n",
    "\n",
    "class_names = training_ds.class_names\n",
    "\n",
    "## Configuring dataset for performance\n",
    "AUTOTUNE = tf.data.experimental.AUTOTUNE\n",
    "training_ds = training_ds.cache().prefetch(buffer_size=AUTOTUNE)\n",
    "testing_ds = testing_ds.cache().prefetch(buffer_size=AUTOTUNE)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-02-20T08:41:01.372477Z",
     "iopub.status.busy": "2023-02-20T08:41:01.372122Z",
     "iopub.status.idle": "2023-02-20T08:41:01.434573Z",
     "shell.execute_reply": "2023-02-20T08:41:01.433143Z",
     "shell.execute_reply.started": "2023-02-20T08:41:01.372443Z"
    }
   },
   "outputs": [],
   "source": [
    "## Defining Cnn\n",
    "MyCnn = tf.keras.models.Sequential([\n",
    "  layers.BatchNormalization(),\n",
    "  layers.Conv2D(32, 3, activation='relu'),\n",
    "  layers.MaxPooling2D(),\n",
    "  layers.Conv2D(64, 3, activation='relu'),\n",
    "  layers.MaxPooling2D(),\n",
    "  layers.Conv2D(128, 3, activation='relu'),\n",
    "  layers.MaxPooling2D(),\n",
    "  layers.Flatten(),\n",
    "  layers.Dense(256, activation='relu'),\n",
    "  layers.Dense(len(class_names), activation= 'softmax')\n",
    "])\n",
    "\n",
    "MyCnn.compile(optimizer='adam',loss='sparse_categorical_crossentropy', metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-02-20T08:41:01.440818Z",
     "iopub.status.busy": "2023-02-20T08:41:01.440381Z",
     "iopub.status.idle": "2023-02-20T08:52:01.307418Z",
     "shell.execute_reply": "2023-02-20T08:52:01.306489Z",
     "shell.execute_reply.started": "2023-02-20T08:41:01.440783Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/10\n",
      "8/8 [==============================] - 58s 7s/step - loss: 4.9837 - accuracy: 0.5221 - val_loss: 0.8230 - val_accuracy: 0.4694\n",
      "Epoch 2/10\n",
      "8/8 [==============================] - 57s 7s/step - loss: 0.6444 - accuracy: 0.6131 - val_loss: 1.1053 - val_accuracy: 0.4898\n",
      "Epoch 3/10\n",
      "8/8 [==============================] - 57s 7s/step - loss: 0.5694 - accuracy: 0.6979 - val_loss: 0.8568 - val_accuracy: 0.5612\n",
      "Epoch 4/10\n",
      "8/8 [==============================] - 57s 7s/step - loss: 0.4762 - accuracy: 0.7737 - val_loss: 0.7721 - val_accuracy: 0.7143\n",
      "Epoch 5/10\n",
      "8/8 [==============================] - 57s 7s/step - loss: 0.3685 - accuracy: 0.8432 - val_loss: 1.0672 - val_accuracy: 0.6531\n",
      "Epoch 6/10\n",
      "8/8 [==============================] - 56s 7s/step - loss: 0.2715 - accuracy: 0.9001 - val_loss: 0.6782 - val_accuracy: 0.7857\n",
      "Epoch 7/10\n",
      "8/8 [==============================] - 56s 7s/step - loss: 0.2258 - accuracy: 0.9027 - val_loss: 0.4271 - val_accuracy: 0.8265\n",
      "Epoch 8/10\n",
      "8/8 [==============================] - 56s 7s/step - loss: 0.1960 - accuracy: 0.9343 - val_loss: 0.2990 - val_accuracy: 0.8469\n",
      "Epoch 9/10\n",
      "8/8 [==============================] - 57s 7s/step - loss: 0.1215 - accuracy: 0.9595 - val_loss: 0.8526 - val_accuracy: 0.7653\n",
      "Epoch 10/10\n",
      "8/8 [==============================] - 56s 7s/step - loss: 0.0969 - accuracy: 0.9659 - val_loss: 0.3811 - val_accuracy: 0.8571\n"
     ]
    }
   ],
   "source": [
    "## lets train our CNN\n",
    "retVal = MyCnn.fit(training_ds, validation_data= validation_ds, epochs = 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-02-20T08:52:01.309892Z",
     "iopub.status.busy": "2023-02-20T08:52:01.309581Z",
     "iopub.status.idle": "2023-02-20T08:52:01.552166Z",
     "shell.execute_reply": "2023-02-20T08:52:01.551138Z",
     "shell.execute_reply.started": "2023-02-20T08:52:01.309856Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f37c8259450>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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fvEL7r33XlwuF16vl+9+97t0dXXxyU9+kmg0irWWb33rW7Nef9ZMdDrI2TxmenqetdZ+9fvP22Vf/Knd3xqZ8Wc4hdNPR5sup7dHrk/PywfRaNQODAxYa6393e9+ZxsaGjLar9DaYrqn5+Vljxpg59EOzp1f2LfWEZHpOXToEJ/5zGdIJBKUlJTwyCOP5LqkvJB3Qb044MLrNuxq6eQPG8K5LkdE5tAFF1zAm2++mesy8k5eHUwE8LgMF9ZU6ICiiEhK3gU1QF04yK6WzmmfqiMi4kR5GtQhTnf3c7wzsztdiIg4WV4Gdf3i5OXju45OfgmtiEgxyMugvnhREGNgp8apReZMe3s7Dz300Iz2vf7666ecO+PLX/4y27Ztm9HnF7u8DOryUg/nzi9n1xST0ojI7JksqOPxyW/o8eyzz046FzXAP/zDP/Cxj31sxvXlwuCl7bmWl0ENySlPp5o9TERmTyFNc/r5z3+exsZG6urquP/++4eWv/baa3z4wx+moaGByy67jK6uLuLxOPfccw8rV65k1apV/Ou//uuImgFef/11mpqaAPjKV77Cpk2b2LBhA3/2Z3/GwYMHueqqq1i7di1r167ld7/73dD3/dM//RMrV66koaFhqP3Wrl07tH7fvn2sW7furP9u8u486kF14SD/+XYLZ7r7qSovyXU5InPruS/B8d9Puok/HgP3NP4LL1oJH//GhKsLaZrTr3/961RXVxOPx7n22mvZuHEj69at44//+I/ZunUrl156KZ2dnfj9fjZv3syBAwd488038Xg8nD59esqm2rFjB9u3b8fv99PT08Mvf/lLfD4f+/bt45ZbbuH111/nueee4yc/+QmvvPIKZWVlnD59murqakKhEG+99RarV6/miSee4Pbbb5/y+6aStz3q4SlP1asWyZV8neb0ySefZO3ataxZs4Zdu3axd+9e3nnnHWpra7n00ksBCAaDeDwetm3bxuc+9zk8nuQPterq6in/3DfeeCN+vx+AgYEB7rrrLlauXMmnP/1pdu/eDcC2bdu44447hqZLHfzcO++8kyeeeIJ4PM7WrVu59dZbp/y+qeR1jxqSc1N/5IL5Oa5GZI5N0vMd1Fuk05weOHCABx54gNdee42qqipuv/12+vr6sNaOe4fviZZ7PB4SieTdpEb/OdL/3N/61reoqanh7bffJpFI4PP5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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "## stats on training data\n",
    "plt.plot(retVal.history['loss'], label = 'training loss')\n",
    "plt.plot(retVal.history['accuracy'], label = 'training accuracy')\n",
    "plt.grid(True)\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-02-20T08:52:01.554052Z",
     "iopub.status.busy": "2023-02-20T08:52:01.553660Z",
     "iopub.status.idle": "2023-02-20T08:52:01.730127Z",
     "shell.execute_reply": "2023-02-20T08:52:01.729277Z",
     "shell.execute_reply.started": "2023-02-20T08:52:01.554008Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f37c81dd490>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "## stats on validation data\n",
    "plt.plot(retVal.history['val_loss'], label = 'validation loss')\n",
    "plt.plot(retVal.history['val_accuracy'], label = 'validation accuracy')\n",
    "plt.grid(True)\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-02-20T08:52:01.731605Z",
     "iopub.status.busy": "2023-02-20T08:52:01.731316Z",
     "iopub.status.idle": "2023-02-20T08:52:08.187177Z",
     "shell.execute_reply": "2023-02-20T08:52:08.186162Z",
     "shell.execute_reply.started": "2023-02-20T08:52:01.731577Z"
    }
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'plt' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_49476/2510904728.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[1;31m## lets vizualize results on testing data\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      2\u001b[0m \u001b[0mAccuracyVector\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfigure\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfigsize\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m30\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m30\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      4\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mimages\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mlabels\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mtesting_ds\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtake\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      5\u001b[0m     \u001b[0mpredictions\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mMyCnn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpredict\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mimages\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'plt' is not defined"
     ]
    }
   ],
   "source": [
    "## lets vizualize results on testing data\n",
    "AccuracyVector = []\n",
    "plt.figure(figsize=(30, 30))\n",
    "for images, labels in testing_ds.take(1):\n",
    "    predictions = MyCnn.predict(images)\n",
    "    predlabel = []\n",
    "    prdlbl = []\n",
    "    \n",
    "    for mem in predictions:\n",
    "        predlabel.append(class_names[np.argmax(mem)])\n",
    "        prdlbl.append(np.argmax(mem))\n",
    "    \n",
    "    AccuracyVector = np.array(prdlbl) == labels\n",
    "    for i in range(40):\n",
    "        ax = plt.subplot(10, 4, i + 1)\n",
    "        plt.imshow(images[i].numpy().astype(\"uint8\"))\n",
    "        plt.title('Pred: '+ predlabel[i]+' actl:'+class_names[labels[i]] )\n",
    "        plt.axis('off')\n",
    "        plt.grid(True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-02-20T08:52:08.189825Z",
     "iopub.status.busy": "2023-02-20T08:52:08.188920Z",
     "iopub.status.idle": "2023-02-20T08:52:08.599049Z",
     "shell.execute_reply": "2023-02-20T08:52:08.598203Z",
     "shell.execute_reply.started": "2023-02-20T08:52:08.189777Z"
    }
   },
   "outputs": [],
   "source": [
    "MyCnn.save('Model.h5')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-02-20T08:52:08.600822Z",
     "iopub.status.busy": "2023-02-20T08:52:08.600308Z",
     "iopub.status.idle": "2023-02-20T08:52:09.332439Z",
     "shell.execute_reply": "2023-02-20T08:52:09.331471Z",
     "shell.execute_reply.started": "2023-02-20T08:52:08.600788Z"
    }
   },
   "outputs": [],
   "source": [
    "from keras.utils.vis_utils import plot_model\n",
    "plot_model(MyCnn, to_file='model_plot.png', show_shapes=True, show_layer_names=True)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}