Newer
Older
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Part 1 - Convolutional Neural Networks for CIFAR-10\n",
"\n",
"\n",
"In this notebook chapter, we'll build, train and optimize a neural network to classify images of the CIFAR-10 dataset using convolutional neural networks.\n",
"\n",
"This guide uses [tf.keras](https://www.tensorflow.org/guide/keras), a high-level API to build and train models in TensorFlow.\n"
]
},
{
"cell_type": "code",
"execution_count": 98,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2.7.1\n",
"Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz\n",
"170500096/170498071 [==============================] - 7s 0us/step\n",
"170508288/170498071 [==============================] - 7s 0us/step\n",
"Train: X=(50000, 32, 32, 3), y=(50000, 1)\n",
"Test: X=(10000, 32, 32, 3), y=(10000, 1)\n",
"(50000, 1)\n",
"(10000, 1)\n",
"(50000, 10)\n",
"(10000, 10)\n"
]
}
],
"source": [
"from __future__ import absolute_import, division, print_function, unicode_literals\n",
"\n",
"# Import TensorFlow and TensorFlow Datasets\n",
"import tensorflow as tf\n",
"print(tf.__version__)\n",
"\n",
"# Helper libraries\n",
"import math\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from tensorflow.keras.datasets import cifar10\n",
"from tensorflow.keras.utils import to_categorical\n",
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
"# load dataset\n",
"(X_train, y_train), (X_test, y_test) = cifar10.load_data()\n",
"X_train = X_train.astype('float32')\n",
"X_test = X_test.astype('float32')\n",
"\n",
"class_names = ['airplanes', 'cars', 'birds', 'cats', 'deer',\n",
" 'dogs', 'frogs', 'horses', 'ships', 'trucks']\n",
"num_classes = len(class_names)\n",
"\n",
"\n",
"# summarize loaded dataset\n",
"print('Train: X=%s, y=%s' % (X_train.shape, y_train.shape))\n",
"print('Test: X=%s, y=%s' % (X_test.shape, y_test.shape))\n",
"y_train_cat = to_categorical(y_train, 10)\n",
"y_test_cat = to_categorical(y_test, 10)\n",
"print(y_train.shape)\n",
"print(y_test.shape)\n",
"print(y_train_cat.shape)\n",
"print(y_test_cat.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Preprocess the data\n",
"\n",
"### 1.1 Zero-Centered Images\n",
"\n",
"The value of each pixel in the image data is an integer in the range `[0,255]`. For the model to work properly, these values need to be zero-centered to the range. So here we compute the mean value per colour channel over all training images and subtract the mean value per colour channel from every image in the training and test set."
]
},
{
"cell_type": "code",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[125.3069 122.95015 113.866 ]\n",
"[-25.327402 -39.670845 -56.451923]\n",
"(32, 32, 3)\n",
"(50000, 32, 32, 3)\n",
"(10000, 32, 32, 3)\n",
"float32\n"
]
}
],
"source": [
"train_mean = X_train.mean(axis=(0,1,2))\n",
"train_std = X_train.std(axis=(0,1,2))\n",
"print(train_mean)\n",
"X_train_zc = X_train - train_mean\n",
"X_test_zc = X_test - train_mean\n",
"\n",
"\n",
"print(X_train_zc[3].mean(axis=(0,1)))\n",
"print(X_train_zc[3].shape)\n",
"print(X_train_zc.shape)\n",
"print(X_test_zc.shape)\n",
"print(X_train_zc.dtype)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1.2 Data Augmentation"
]
},
{
"cell_type": "code",
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
"metadata": {},
"outputs": [],
"source": [
"import tensorflow as tf\n",
"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
"from tensorflow.keras.preprocessing import image\n",
"\n",
"\n",
"train_datagen = ImageDataGenerator(\n",
" # set input mean to 0 over the dataset\n",
" featurewise_center=False, \n",
" # set each sample mean to 0\n",
" samplewise_center=False, \n",
" # divide inputs by std of the dataset\n",
" featurewise_std_normalization=False, \n",
" # divide each input by its std\n",
" samplewise_std_normalization=False, \n",
" # apply ZCA whitening\n",
" zca_whitening=False, \n",
" # epsilon for ZCA whitening\n",
" zca_epsilon=1e-06, \n",
" # randomly rotate images in the range (degrees, 0 to 180)\n",
" rotation_range=0, \n",
" # randomly shift images horizontally (fraction of total width)\n",
" width_shift_range=0.1,\n",
" # randomly shift images vertically (fraction of total height)\n",
" height_shift_range=0.1,\n",
" # set range for random shear\n",
" shear_range=0., \n",
" # set range for random zoom\n",
" zoom_range=0., \n",
" # set range for random channel shifts\n",
" # set mode for filling points outside the input boundaries\n",
" channel_shift_range=0., \n",
" # value used for fill_mode = \"constant\"\n",
" fill_mode='nearest',\n",
" cval=0., \n",
" # randomly flip images\n",
" horizontal_flip=True, \n",
" # randomly flip images\n",
" vertical_flip=False, \n",
" # set rescaling factor (applied before any other transformation)\n",
" rescale=None,\n",
" # set function that will be applied on each input\n",
" preprocessing_function=None,\n",
" # image data format, either \"channels_first\" or \"channels_last\"\n",
" data_format=None,\n",
" # fraction of images reserved for validation (strictly between 0 and 1)\n",
" validation_split=0.0)\n",
"\n",
"validation_datagen = ImageDataGenerator( \n",
" # rescale the pixel values (between 0 and 255) to the [0,1] interval \n",
" # rescale=1./255\n",
")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Build the model\n",
"\n",
"Building the neural network requires configuring the layers of the model, then compiling the model."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.1 Define the network\n",
"\n",
"The basic building block of a neural network is the *layer*. A layer extracts a representation from the data fed into it. Hopefully, a series of connected layers results in a representation that is meaningful for the problem at hand.\n",
"\n",
"Much of deep learning consists of chaining together simple layers. Most layers, like `tf.keras.layers.Dense`, have internal parameters which are adjusted (\"learned\") during training."
]
},
{
"cell_type": "code",
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
"metadata": {},
"outputs": [],
"source": [
"model = tf.keras.Sequential()\n",
"model.add(tf.keras.layers.Conv2D(32, (3, 3), padding='same',\n",
" input_shape=X_train_zc.shape[1:]))\n",
"model.add(tf.keras.layers.BatchNormalization())\n",
"model.add(tf.keras.layers.Activation('relu'))\n",
"model.add(tf.keras.layers.Conv2D(32, (3, 3)))\n",
"model.add(tf.keras.layers.BatchNormalization())\n",
"model.add(tf.keras.layers.Activation('relu'))\n",
"model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))\n",
"model.add(tf.keras.layers.Dropout(0.25))\n",
"\n",
"model.add(tf.keras.layers.Conv2D(64, (3, 3), padding='same'))\n",
"model.add(tf.keras.layers.BatchNormalization())\n",
"model.add(tf.keras.layers.Activation('relu'))\n",
"model.add(tf.keras.layers.Conv2D(64, (3, 3)))\n",
"model.add(tf.keras.layers.BatchNormalization())\n",
"model.add(tf.keras.layers.Activation('relu'))\n",
"model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))\n",
"model.add(tf.keras.layers.Dropout(0.25))\n",
"\n",
"model.add(tf.keras.layers.Flatten())\n",
"model.add(tf.keras.layers.Dense(512))\n",
"model.add(tf.keras.layers.BatchNormalization())\n",
"model.add(tf.keras.layers.Activation('relu'))\n",
"model.add(tf.keras.layers.Dropout(0.5))\n",
"model.add(tf.keras.layers.Dense(num_classes))\n",
"model.add(tf.keras.layers.BatchNormalization())\n",
"model.add(tf.keras.layers.Activation('softmax'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`tf.keras.layers.Conv2D(32, (3, 3)))` implies the following parameter settings:\n",
"\n",
"\n",
"- `filters` : Integer, the dimensionality of the output space (i.e. the number of output filters in the \n",
"convolution). In this case, the number of filters is $32$.\n",
"\n",
"- `kernel_size` : An integer or tuple/list of 2 integers, specifying the height and width of the 2D convolution window (receptive field). Can be a single integer to specify the same value for all spatial dimensions. In this \n",
"case, the receptive field of the filters are $3\\times3$.\n",
"\n",
"- `strides` : An integer or tuple/list of 2 integers, specifying the strides of the convolution along the height and width. Can be a single integer to specify the same value for all spatial dimensions. Default strides : $(1, 1)$\n",
"\n",
"- `padding`: one of `valid` or `same`. In this case, the size of the output volume won't be changed.\n",
"\n",
"`tf.keras.layers.MaxPooling2D(pool_size=(2, 2))` implies the following parameter settings:\n",
"\n",
"- `pool_size`: integer or tuple of 2 integers, factors by which to downscale (vertical, horizontal). $(2, 2)$ will halve the input in both spatial dimension. If only one integer is specified, the same window length will be used for both dimensions.\n",
"- `strides`: Integer, tuple of 2 integers, or `None`. `strides` values. If `None`, it will default to `pool_size`. In this case $(2,2)$."
]
},
{
"cell_type": "code",
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
"execution_count": 102,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"sequential\"\n",
"_________________________________________________________________\n",
" Layer (type) Output Shape Param # \n",
"=================================================================\n",
" conv2d_4 (Conv2D) (None, 32, 32, 32) 896 \n",
" \n",
" batch_normalization_4 (Batc (None, 32, 32, 32) 128 \n",
" hNormalization) \n",
" \n",
" activation (Activation) (None, 32, 32, 32) 0 \n",
" \n",
" conv2d_5 (Conv2D) (None, 30, 30, 32) 9248 \n",
" \n",
" batch_normalization_5 (Batc (None, 30, 30, 32) 128 \n",
" hNormalization) \n",
" \n",
" activation_1 (Activation) (None, 30, 30, 32) 0 \n",
" \n",
" max_pooling2d (MaxPooling2D (None, 15, 15, 32) 0 \n",
" ) \n",
" \n",
" dropout (Dropout) (None, 15, 15, 32) 0 \n",
" \n",
" conv2d_6 (Conv2D) (None, 15, 15, 64) 18496 \n",
" \n",
" batch_normalization_6 (Batc (None, 15, 15, 64) 256 \n",
" hNormalization) \n",
" \n",
" activation_2 (Activation) (None, 15, 15, 64) 0 \n",
" \n",
" conv2d_7 (Conv2D) (None, 13, 13, 64) 36928 \n",
" \n",
" batch_normalization_7 (Batc (None, 13, 13, 64) 256 \n",
" hNormalization) \n",
" \n",
" activation_3 (Activation) (None, 13, 13, 64) 0 \n",
" \n",
" max_pooling2d_1 (MaxPooling (None, 6, 6, 64) 0 \n",
" 2D) \n",
" \n",
" dropout_1 (Dropout) (None, 6, 6, 64) 0 \n",
" \n",
" flatten (Flatten) (None, 2304) 0 \n",
" \n",
" dense (Dense) (None, 512) 1180160 \n",
" \n",
" batch_normalization_8 (Batc (None, 512) 2048 \n",
" hNormalization) \n",
" \n",
" activation_4 (Activation) (None, 512) 0 \n",
" \n",
" dropout_2 (Dropout) (None, 512) 0 \n",
" \n",
" dense_1 (Dense) (None, 10) 5130 \n",
" \n",
" batch_normalization_9 (Batc (None, 10) 40 \n",
" hNormalization) \n",
" \n",
" activation_5 (Activation) (None, 10) 0 \n",
" \n",
"=================================================================\n",
"Total params: 1,253,714\n",
"Trainable params: 1,252,286\n",
"Non-trainable params: 1,428\n",
"_________________________________________________________________\n"
]
}
],
"source": [
"model.summary()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.2 Compile and Fit the Network"
]
},
{
"cell_type": "code",
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
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
"execution_count": 103,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/conda/lib/python3.7/site-packages/ipykernel_launcher.py:26: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/100\n",
"125/125 [==============================] - 65s 496ms/step - loss: 2.2637 - accuracy: 0.1915 - val_loss: 1.9200 - val_accuracy: 0.2960\n",
"Epoch 2/100\n",
"125/125 [==============================] - 59s 475ms/step - loss: 1.9513 - accuracy: 0.2770 - val_loss: 1.7717 - val_accuracy: 0.3740\n",
"Epoch 3/100\n",
"125/125 [==============================] - 58s 461ms/step - loss: 1.8561 - accuracy: 0.3145 - val_loss: 1.6933 - val_accuracy: 0.4010\n",
"Epoch 4/100\n",
"125/125 [==============================] - 60s 482ms/step - loss: 1.7906 - accuracy: 0.3532 - val_loss: 1.6480 - val_accuracy: 0.4350\n",
"Epoch 5/100\n",
"125/125 [==============================] - 56s 451ms/step - loss: 1.7519 - accuracy: 0.3702 - val_loss: 1.6108 - val_accuracy: 0.4580\n",
"Epoch 6/100\n",
"125/125 [==============================] - 57s 456ms/step - loss: 1.7103 - accuracy: 0.3938 - val_loss: 1.5763 - val_accuracy: 0.4750\n",
"Epoch 7/100\n",
"125/125 [==============================] - 57s 453ms/step - loss: 1.6755 - accuracy: 0.4050 - val_loss: 1.5648 - val_accuracy: 0.4650\n",
"Epoch 8/100\n",
"125/125 [==============================] - 59s 472ms/step - loss: 1.6370 - accuracy: 0.4275 - val_loss: 1.5384 - val_accuracy: 0.4800\n",
"Epoch 9/100\n",
"125/125 [==============================] - 57s 456ms/step - loss: 1.6283 - accuracy: 0.4325 - val_loss: 1.4877 - val_accuracy: 0.5010\n",
"Epoch 10/100\n",
"125/125 [==============================] - 57s 454ms/step - loss: 1.5921 - accuracy: 0.4462 - val_loss: 1.4827 - val_accuracy: 0.5000\n",
"Epoch 11/100\n",
"125/125 [==============================] - 57s 455ms/step - loss: 1.5814 - accuracy: 0.4538 - val_loss: 1.4720 - val_accuracy: 0.5030\n",
"Epoch 12/100\n",
"125/125 [==============================] - 56s 452ms/step - loss: 1.5691 - accuracy: 0.4595 - val_loss: 1.4404 - val_accuracy: 0.5180\n",
"Epoch 13/100\n",
"125/125 [==============================] - 57s 460ms/step - loss: 1.5502 - accuracy: 0.4582 - val_loss: 1.4321 - val_accuracy: 0.5130\n",
"Epoch 14/100\n",
"125/125 [==============================] - 60s 477ms/step - loss: 1.5285 - accuracy: 0.4715 - val_loss: 1.4144 - val_accuracy: 0.5300\n",
"Epoch 15/100\n",
"125/125 [==============================] - 59s 473ms/step - loss: 1.5151 - accuracy: 0.4755 - val_loss: 1.3980 - val_accuracy: 0.5310\n",
"Epoch 16/100\n",
"125/125 [==============================] - 60s 477ms/step - loss: 1.5007 - accuracy: 0.4757 - val_loss: 1.4200 - val_accuracy: 0.5270\n",
"Epoch 17/100\n",
"125/125 [==============================] - 60s 479ms/step - loss: 1.4775 - accuracy: 0.4885 - val_loss: 1.4524 - val_accuracy: 0.4960\n",
"Epoch 18/100\n",
"125/125 [==============================] - 58s 468ms/step - loss: 1.4692 - accuracy: 0.5027 - val_loss: 1.3896 - val_accuracy: 0.5330\n",
"Epoch 19/100\n",
"125/125 [==============================] - 59s 471ms/step - loss: 1.4788 - accuracy: 0.4870 - val_loss: 1.3865 - val_accuracy: 0.5140\n",
"Epoch 20/100\n",
"125/125 [==============================] - 61s 489ms/step - loss: 1.4375 - accuracy: 0.5148 - val_loss: 1.3598 - val_accuracy: 0.5390\n",
"Epoch 21/100\n",
"125/125 [==============================] - 59s 473ms/step - loss: 1.4504 - accuracy: 0.4988 - val_loss: 1.3318 - val_accuracy: 0.5450\n",
"Epoch 22/100\n",
"125/125 [==============================] - 59s 471ms/step - loss: 1.4279 - accuracy: 0.5215 - val_loss: 1.3777 - val_accuracy: 0.5300\n",
"Epoch 23/100\n",
"125/125 [==============================] - 58s 466ms/step - loss: 1.4136 - accuracy: 0.5180 - val_loss: 1.3823 - val_accuracy: 0.5200\n",
"Epoch 24/100\n",
"125/125 [==============================] - 59s 472ms/step - loss: 1.4027 - accuracy: 0.5340 - val_loss: 1.3522 - val_accuracy: 0.5270\n",
"Epoch 25/100\n",
"125/125 [==============================] - 59s 472ms/step - loss: 1.3762 - accuracy: 0.5440 - val_loss: 1.3318 - val_accuracy: 0.5430\n",
"Epoch 26/100\n",
"125/125 [==============================] - 59s 472ms/step - loss: 1.3990 - accuracy: 0.5272 - val_loss: 1.4013 - val_accuracy: 0.5180\n",
"Epoch 27/100\n",
"125/125 [==============================] - 59s 473ms/step - loss: 1.3665 - accuracy: 0.5437 - val_loss: 1.3762 - val_accuracy: 0.5210\n",
"Epoch 28/100\n",
"125/125 [==============================] - 58s 466ms/step - loss: 1.3634 - accuracy: 0.5460 - val_loss: 1.3323 - val_accuracy: 0.5380\n",
"Epoch 29/100\n",
"125/125 [==============================] - 59s 473ms/step - loss: 1.3478 - accuracy: 0.5477 - val_loss: 1.3114 - val_accuracy: 0.5390\n",
"Epoch 30/100\n",
"125/125 [==============================] - 56s 448ms/step - loss: 1.3260 - accuracy: 0.5583 - val_loss: 1.2892 - val_accuracy: 0.5530\n",
"Epoch 32/100\n",
"125/125 [==============================] - 56s 446ms/step - loss: 1.3238 - accuracy: 0.5508 - val_loss: 1.3091 - val_accuracy: 0.5420\n",
"Epoch 33/100\n",
"125/125 [==============================] - 56s 445ms/step - loss: 1.3083 - accuracy: 0.5645 - val_loss: 1.3815 - val_accuracy: 0.5130\n",
"Epoch 34/100\n",
"125/125 [==============================] - 55s 439ms/step - loss: 1.2933 - accuracy: 0.5725 - val_loss: 1.2927 - val_accuracy: 0.5430\n",
"Epoch 35/100\n",
"125/125 [==============================] - 56s 446ms/step - loss: 1.2855 - accuracy: 0.5698 - val_loss: 1.1875 - val_accuracy: 0.5910\n",
"Epoch 36/100\n",
"125/125 [==============================] - 56s 445ms/step - loss: 1.2898 - accuracy: 0.5732 - val_loss: 1.2752 - val_accuracy: 0.5550\n",
"Epoch 37/100\n",
"125/125 [==============================] - 56s 447ms/step - loss: 1.2658 - accuracy: 0.5832 - val_loss: 1.3143 - val_accuracy: 0.5400\n",
"Epoch 38/100\n",
"125/125 [==============================] - 56s 447ms/step - loss: 1.2637 - accuracy: 0.5817 - val_loss: 1.2509 - val_accuracy: 0.5640\n",
"Epoch 39/100\n",
"125/125 [==============================] - 55s 443ms/step - loss: 1.2505 - accuracy: 0.5907 - val_loss: 1.2469 - val_accuracy: 0.5640\n",
"Epoch 40/100\n",
"125/125 [==============================] - 56s 444ms/step - loss: 1.2545 - accuracy: 0.5910 - val_loss: 1.1830 - val_accuracy: 0.5850\n",
"Epoch 41/100\n",
"125/125 [==============================] - 55s 443ms/step - loss: 1.2268 - accuracy: 0.6062 - val_loss: 1.1905 - val_accuracy: 0.5830\n",
"Epoch 42/100\n",
"125/125 [==============================] - 56s 446ms/step - loss: 1.2524 - accuracy: 0.5847 - val_loss: 1.2197 - val_accuracy: 0.5750\n",
"Epoch 43/100\n",
"125/125 [==============================] - 55s 441ms/step - loss: 1.2286 - accuracy: 0.5938 - val_loss: 1.2149 - val_accuracy: 0.5740\n",
"Epoch 44/100\n",
"125/125 [==============================] - 56s 444ms/step - loss: 1.2193 - accuracy: 0.5953 - val_loss: 1.2929 - val_accuracy: 0.5420\n",
"Epoch 45/100\n",
"125/125 [==============================] - 55s 441ms/step - loss: 1.2190 - accuracy: 0.5965 - val_loss: 1.2086 - val_accuracy: 0.5710\n",
"Epoch 46/100\n",
"125/125 [==============================] - 56s 448ms/step - loss: 1.2008 - accuracy: 0.6115 - val_loss: 1.1594 - val_accuracy: 0.5880\n",
"Epoch 47/100\n",
"125/125 [==============================] - 55s 442ms/step - loss: 1.2039 - accuracy: 0.6085 - val_loss: 1.1784 - val_accuracy: 0.5770\n",
"Epoch 48/100\n",
"125/125 [==============================] - 55s 444ms/step - loss: 1.1963 - accuracy: 0.6047 - val_loss: 1.2196 - val_accuracy: 0.5760\n",
"Epoch 49/100\n",
"125/125 [==============================] - 55s 444ms/step - loss: 1.1730 - accuracy: 0.6242 - val_loss: 1.1989 - val_accuracy: 0.5790\n",
"Epoch 50/100\n",
"125/125 [==============================] - 56s 446ms/step - loss: 1.1624 - accuracy: 0.6148 - val_loss: 1.1506 - val_accuracy: 0.6000\n",
"Epoch 51/100\n",
"125/125 [==============================] - 55s 440ms/step - loss: 1.1769 - accuracy: 0.6235 - val_loss: 1.2207 - val_accuracy: 0.5760\n",
"Epoch 52/100\n",
"125/125 [==============================] - 55s 443ms/step - loss: 1.1402 - accuracy: 0.6382 - val_loss: 1.1913 - val_accuracy: 0.5810\n",
"Epoch 53/100\n",
"125/125 [==============================] - 55s 441ms/step - loss: 1.1687 - accuracy: 0.6120 - val_loss: 1.2070 - val_accuracy: 0.5780\n",
"Epoch 54/100\n",
"125/125 [==============================] - 55s 441ms/step - loss: 1.1623 - accuracy: 0.6168 - val_loss: 1.2214 - val_accuracy: 0.5800\n",
"Epoch 55/100\n",
" 77/125 [=================>............] - ETA: 19s - loss: 1.1498 - accuracy: 0.6246"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"IOPub message rate exceeded.\n",
"The notebook server will temporarily stop sending output\n",
"to the client in order to avoid crashing it.\n",
"To change this limit, set the config variable\n",
"`--NotebookApp.iopub_msg_rate_limit`.\n",
"\n",
"Current values:\n",
"NotebookApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
"NotebookApp.rate_limit_window=3.0 (secs)\n",
"\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 62/100\n",
"125/125 [==============================] - 55s 442ms/step - loss: 1.0842 - accuracy: 0.6538 - val_loss: 1.1262 - val_accuracy: 0.6240\n",
"Epoch 63/100\n",
"125/125 [==============================] - 56s 447ms/step - loss: 1.1145 - accuracy: 0.6292 - val_loss: 1.0857 - val_accuracy: 0.6260\n",
"Epoch 64/100\n",
"125/125 [==============================] - 56s 447ms/step - loss: 1.1011 - accuracy: 0.6392 - val_loss: 1.1256 - val_accuracy: 0.6110\n",
"Epoch 65/100\n",
"125/125 [==============================] - 56s 445ms/step - loss: 1.0765 - accuracy: 0.6565 - val_loss: 1.0557 - val_accuracy: 0.6370\n",
"Epoch 66/100\n",
"125/125 [==============================] - 56s 445ms/step - loss: 1.0834 - accuracy: 0.6450 - val_loss: 1.1164 - val_accuracy: 0.6160\n",
"Epoch 67/100\n",
"125/125 [==============================] - 55s 442ms/step - loss: 1.0699 - accuracy: 0.6575 - val_loss: 1.0950 - val_accuracy: 0.6170\n",
"Epoch 68/100\n",
"125/125 [==============================] - 56s 450ms/step - loss: 1.0688 - accuracy: 0.6615 - val_loss: 1.1049 - val_accuracy: 0.6220\n",
"Epoch 69/100\n",
"125/125 [==============================] - 56s 452ms/step - loss: 1.0589 - accuracy: 0.6578 - val_loss: 1.0180 - val_accuracy: 0.6580\n",
"Epoch 70/100\n",
"125/125 [==============================] - 56s 451ms/step - loss: 1.0588 - accuracy: 0.6555 - val_loss: 1.1188 - val_accuracy: 0.6100\n",
"Epoch 71/100\n",
"125/125 [==============================] - 56s 448ms/step - loss: 1.0515 - accuracy: 0.6590 - val_loss: 1.0780 - val_accuracy: 0.6370\n",
"Epoch 72/100\n",
"125/125 [==============================] - 56s 447ms/step - loss: 1.0405 - accuracy: 0.6637 - val_loss: 1.1619 - val_accuracy: 0.6070\n",
"Epoch 73/100\n",
"125/125 [==============================] - 56s 449ms/step - loss: 1.0456 - accuracy: 0.6575 - val_loss: 1.1258 - val_accuracy: 0.6220\n",
"Epoch 74/100\n",
"125/125 [==============================] - 56s 447ms/step - loss: 1.0444 - accuracy: 0.6587 - val_loss: 1.0532 - val_accuracy: 0.6410\n",
"Epoch 75/100\n",
"125/125 [==============================] - 56s 448ms/step - loss: 1.0352 - accuracy: 0.6727 - val_loss: 1.0651 - val_accuracy: 0.6350\n",
"Epoch 76/100\n",
"125/125 [==============================] - 56s 447ms/step - loss: 1.0354 - accuracy: 0.6662 - val_loss: 1.0534 - val_accuracy: 0.6430\n",
"Epoch 77/100\n",
"125/125 [==============================] - 57s 453ms/step - loss: 1.0294 - accuracy: 0.6662 - val_loss: 1.0510 - val_accuracy: 0.6550\n",
"Epoch 78/100\n",
"125/125 [==============================] - 57s 453ms/step - loss: 1.0230 - accuracy: 0.6733 - val_loss: 1.0229 - val_accuracy: 0.6620\n",
"Epoch 79/100\n",
"125/125 [==============================] - 55s 443ms/step - loss: 1.0049 - accuracy: 0.6685 - val_loss: 1.0117 - val_accuracy: 0.6500\n",
"Epoch 80/100\n",
"125/125 [==============================] - 56s 447ms/step - loss: 1.0287 - accuracy: 0.6693 - val_loss: 1.0722 - val_accuracy: 0.6320\n",
"Epoch 81/100\n",
"125/125 [==============================] - 56s 452ms/step - loss: 0.9973 - accuracy: 0.6783 - val_loss: 1.0493 - val_accuracy: 0.6560\n",
"Epoch 82/100\n",
"125/125 [==============================] - 56s 446ms/step - loss: 1.0021 - accuracy: 0.6817 - val_loss: 0.9638 - val_accuracy: 0.6770\n",
"Epoch 83/100\n",
"125/125 [==============================] - 57s 454ms/step - loss: 1.0031 - accuracy: 0.6800 - val_loss: 1.0365 - val_accuracy: 0.6540\n",
"Epoch 84/100\n",
"125/125 [==============================] - 56s 445ms/step - loss: 0.9859 - accuracy: 0.6867 - val_loss: 1.0449 - val_accuracy: 0.6490\n",
"Epoch 85/100\n",
"125/125 [==============================] - 55s 438ms/step - loss: 0.9872 - accuracy: 0.6840 - val_loss: 1.0435 - val_accuracy: 0.6610\n",
"Epoch 86/100\n",
"125/125 [==============================] - 57s 456ms/step - loss: 0.9900 - accuracy: 0.6837 - val_loss: 1.0121 - val_accuracy: 0.6690\n",
"Epoch 87/100\n",
"125/125 [==============================] - 56s 448ms/step - loss: 0.9744 - accuracy: 0.6898 - val_loss: 1.0126 - val_accuracy: 0.6620\n",
"Epoch 88/100\n",
"125/125 [==============================] - 57s 456ms/step - loss: 0.9805 - accuracy: 0.6830 - val_loss: 1.0174 - val_accuracy: 0.6630\n",
"Epoch 89/100\n",
"125/125 [==============================] - 56s 448ms/step - loss: 0.9726 - accuracy: 0.6798 - val_loss: 1.1025 - val_accuracy: 0.6260\n",
"Epoch 90/100\n",
"125/125 [==============================] - 56s 446ms/step - loss: 0.9697 - accuracy: 0.6815 - val_loss: 1.0069 - val_accuracy: 0.6640\n",
"Epoch 91/100\n",
"125/125 [==============================] - 55s 439ms/step - loss: 0.9654 - accuracy: 0.6835 - val_loss: 1.0464 - val_accuracy: 0.6450\n",
"Epoch 92/100\n",
"125/125 [==============================] - 56s 446ms/step - loss: 0.9722 - accuracy: 0.6833 - val_loss: 1.0428 - val_accuracy: 0.6530\n",
"Epoch 93/100\n",
"125/125 [==============================] - 55s 444ms/step - loss: 0.9626 - accuracy: 0.6860 - val_loss: 0.9629 - val_accuracy: 0.6750\n",
"Epoch 94/100\n",
"125/125 [==============================] - 55s 443ms/step - loss: 0.9472 - accuracy: 0.6930 - val_loss: 0.9866 - val_accuracy: 0.6710\n",
"Epoch 95/100\n",
"125/125 [==============================] - 55s 443ms/step - loss: 0.9285 - accuracy: 0.6970 - val_loss: 0.9925 - val_accuracy: 0.6740\n",
"Epoch 96/100\n",
"125/125 [==============================] - 55s 442ms/step - loss: 0.9325 - accuracy: 0.7030 - val_loss: 1.0282 - val_accuracy: 0.6610\n",
"Epoch 97/100\n",
"125/125 [==============================] - 55s 443ms/step - loss: 0.9534 - accuracy: 0.6977 - val_loss: 1.0087 - val_accuracy: 0.6480\n",
"Epoch 98/100\n",
"125/125 [==============================] - 56s 445ms/step - loss: 0.9582 - accuracy: 0.6845 - val_loss: 1.0345 - val_accuracy: 0.6560\n",
"Epoch 99/100\n",
"125/125 [==============================] - 56s 448ms/step - loss: 0.9299 - accuracy: 0.6998 - val_loss: 0.9744 - val_accuracy: 0.6860\n",
"Epoch 100/100\n",
"125/125 [==============================] - 55s 440ms/step - loss: 0.9254 - accuracy: 0.7017 - val_loss: 0.9833 - val_accuracy: 0.6780\n"
]
},
{
"data": {
"text/plain": [
"<bound method Model.evaluate of <keras.engine.sequential.Sequential object at 0x7ff455bf7410>>"
]
},
"execution_count": 103,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import datetime, os\n",
"logdir = os.path.join(\"logs\", datetime.datetime.now().strftime(\"%Y%m%d-%H%M%S\"))\n",
"tensorboard_callback = tf.keras.callbacks.TensorBoard(logdir, histogram_freq=1)\n",
"\n",
"# Compile Network \n",
"model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001, decay=1e-6),\n",
" loss='categorical_crossentropy',\n",
" metrics=['accuracy'])\n",
"\n",
"num_validation_examples = 1000\n",
"num_train_examples = 5000\n",
"\n",
"\n",
"train_iterator = train_datagen.flow(X_train_zc[num_validation_examples:num_train_examples], \n",
" y_train_cat[num_validation_examples:num_train_examples], \n",
" batch_size=32)\n",
"validation_iterator = validation_datagen.flow(X_train_zc[:num_validation_examples:], \n",
" y_train_cat[:num_validation_examples:], \n",
" batch_size=32)\n",
"\n",
"# Fit Network\n",
"history = model.fit_generator(generator= train_iterator, \n",
" validation_data = validation_iterator, \n",
" steps_per_epoch=len(train_iterator),\n",
" callbacks=[tensorboard_callback])\n",
"\n",
"# Determine \n",
"model.evaluate"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.3 Evaluate the Network on the test dataset"
]
},
{
"cell_type": "code",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"313/313 [==============================] - 30s 95ms/step - loss: 1.0085 - accuracy: 0.6609\n"
]
},
{
"data": {
"text/plain": [
"[1.0084725618362427, 0.6608999967575073]"
]
},
"execution_count": 104,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model.evaluate(X_test_zc, y_test_cat)"
]
},
{
"cell_type": "code",
"outputs": [
{
"data": {
"image/png": "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vna73X2+d+PGjdx+++39fsapp546JG1du3YtF1100ZDca7TImLIQQoheZWVlsWXLFgDuvPNOkpOT+cpXvtJ53uv14nKFDiXLly9n+fLl/X7G+vXrh6StY4FkykIIIQbk+uuv59Zbb2XVqlV87WtfY8OGDZxyyimcdNJJnHrqqezduxfomrneeeed3HjjjaxevZpp06Zx1113dd4vOTm58/rVq1dzxRVXMGfOHK699lrsnQyfe+455syZw7Jly7j99tsHlBE/9NBDLFy4kAULFvD1r38dAJ/Px/XXX8+CBQtYuHAhv/nNbwC46667mDdvHosWLeLqq68+8W/WAEmmLIQQUeL7z+xkV2njkN5z3oRUvvfh+QN+X0lJCevXr8fpdNLY2Mgbb7yBy+Xi5Zdf5pvf/CaPP/54j/fs2bOH1157jaamJmbPns1tt93WY9nQ+++/z86dO5kwYQKnnXYab731FsuXL+eWW25h3bp1TJ06lWuuuSbsdpaWlvL1r3+dTZs2kZGRwXnnncdTTz1FUVERx48fZ8eOHQDU19cD8NOf/pTDhw8TFxfXeWwkSaYshBBiwK688kqcTicADQ0NXHnllSxYsIA77riDnTt3hnzPhRdeSFxcHNnZ2eTm5lJRUdHjmpUrV1JYWIjD4WDJkiUUFxezZ88epk2b1rnEaCBB+b333mP16tXk5OTgcrm49tprWbduHdOmTePQoUN8/vOf54UXXiA1NRWARYsWce211/LAAw/02i0/nCRTFkKIKDGYjHa4JCUldT7/zne+w5o1a3jyyScpLi5m9erVId8TFxfX+dzpdOL1egd1zVDIyMhg69atvPjii9x99908+uij3HvvvTz77LOsW7eOZ555hh//+Mds3759RIOzZMpCCCFOSENDAxMnTgTg/vvvH/L7z549m0OHDlFcXAzAI488EvZ7V65cyeuvv051dTU+n4+HHnqIs846i+rqavx+P5dffjk/+tGP2Lx5M36/n2PHjrFmzRp+9rOf0dDQQHNz85B/PX2RTFkIIcQJ+drXvsYnP/lJfvSjH3HhhRcO+f0TEhL44x//yPnnn09SUhIrVqzo9dpXXnmFwsLCztf/+te/+OlPf8qaNWvQWnPhhRdyySWXsHXrVm644Qb8fj8AP/nJT/D5fFx33XU0NDSgteb2228nPT19yL+evih7ZttIW758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li3j9ttv77xvd2vXrmX+/PncdtttPPTQQ53HKyoquOyyy1i8eDGLFy/u/EXg73//O4sWLWLx4sV8/OMf7/z6HnvssZDtO+OMM7j44ouZN8+U0bv00ktZtmwZ8+fP55577ul8zwsvvMDSpUtZvHgxZ599Nn6/n5kzZ2JXs/L7/cyYMQOpbiXECEnKBlRg3+YwKaU4Y2YOj916Kl8/fw5JcS7u/vgy7v74MhpUirkonKA8DCI2LbD7+uNixnbxkO8/s5NdpY1Des95E1L53ofnD/h9JSUlrF+/HqfTSWNjI2+88QYul4uXX36Zb37zmzz++OM93rNnzx5ee+01mpqamD17NrfddluPJT3vv/8+O3fuZMKECZx22mm89dZbLF++nFtuuYV169YxdepUrrmm95U6Dz30ENdccw2XXHIJ3/zmN/F4PMTExHD77bdz1lln8eSTT+Lz+Whubmbnzp386Ec/Yv369WRnZ1Nb29feC8bmzZvZsWNH56zne++9l8zMTNra2lixYgWXX345fr+fm266qbO9tbW1OBwOrrvuOh588EG++MUv8vLLL7N48WKkupUQIyQuBa79F0xcNqi3Ox2K21ZP57bV0zuPJa28jl+uT+O8xkQWpYZ+n9vr551DNZwxM3vI54KElYYqpc5XSu219lj9RojzX1JK7bL2X31FKXXCI94dkimPuCuvvBKn0/wS1NDQwJVXXsmCBQu444472LkzdFWcCy+8kLi4OLKzs8nNzaWioqLHNStXrqSwsBCHw8GSJUsoLi5mz549TJs2rTMQ9haU3W43zz33HJdeeimpqamsWrWKF198EYBXX32V2267DQCn00laWhqvvvoqV155JdnZZuJHZmZmyPt2b1/wMqS77rqLxYsXc/LJJ3Ps2DH279/PO++8w5lnntl5nX3fG2+8kb///e+ACeY33CC1NoQYUTPP7VJE5EStPvtD3Ou8ggfeORLyfEldK1f+39t84t4NvLSr58+7E9VvpqyUcgJ/AM7F7BjznlLqaa31rqDL3geWa61blVK3AT8HPnoiDRvrs69tg8loh0tSUlLn8+985zusWbOGJ598kuLiYlavXh3yPXFxcZ3PnU4nXq93UNf05sUXX6S+vp6FC83C/9bWVhISEnrt6u6Ny+XqnCTm9/u7TGgL/rrXrl3Lyy+/zNtvv01iYiKrV6/uc5lS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\n",
"text/plain": [
"<Figure size 576x576 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
"source": [
"# Plot training and validation accuracy\n",
"acc = history.history['accuracy']\n",
"val_acc = history.history['val_accuracy']\n",
"\n",
"loss = history.history['loss']\n",
"val_loss = history.history['val_loss']\n",
"\n",
"epochs_range = range(100)\n",
"\n",
"plt.figure(figsize=(8, 8))\n",
"plt.subplot(1, 2, 1)\n",
"plt.plot(epochs_range, acc, label='Training Accuracy')\n",
"plt.plot(epochs_range, val_acc, label='Validation Accuracy')\n",
"plt.legend(loc='lower right')\n",
"plt.title('Training and Validation Accuracy')\n",
"\n",
"plt.subplot(1, 2, 2)\n",
"plt.plot(epochs_range, loss, label='Training Loss')\n",
"plt.plot(epochs_range, val_loss, label='Validation Loss')\n",
"plt.legend(loc='upper right')\n",
"plt.title('Training and Validation Loss')\n",
"plt.show()"
]
},
{
"cell_type": "code",
"source": [
"# Load the TensorBoard notebook extension\n",
"%load_ext tensorboard"
]
},
{
"cell_type": "code",
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
"execution_count": 107,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"ERROR: Failed to launch TensorBoard (exited with 1).\n",
"Contents of stderr:\n",
"Traceback (most recent call last):\n",
" File \"/opt/conda/bin/tensorboard\", line 5, in <module>\n",
" from tensorboard.main import run_main\n",
" File \"/opt/conda/lib/python3.7/site-packages/tensorboard/main.py\", line 27, in <module>\n",
" from tensorboard import default\n",
" File \"/opt/conda/lib/python3.7/site-packages/tensorboard/default.py\", line 33, in <module>\n",
" from tensorboard.plugins.audio import audio_plugin\n",
" File \"/opt/conda/lib/python3.7/site-packages/tensorboard/plugins/audio/audio_plugin.py\", line 23, in <module>\n",
" from tensorboard import plugin_util\n",
" File \"/opt/conda/lib/python3.7/site-packages/tensorboard/plugin_util.py\", line 24, in <module>\n",
" import markdown\n",
" File \"/opt/conda/lib/python3.7/site-packages/markdown/__init__.py\", line 29, in <module>\n",
" from .core import Markdown, markdown, markdownFromFile # noqa: E402\n",
" File \"/opt/conda/lib/python3.7/site-packages/markdown/core.py\", line 26, in <module>\n",
" from . import util\n",
" File \"/opt/conda/lib/python3.7/site-packages/markdown/util.py\", line 88, in <module>\n",
" INSTALLED_EXTENSIONS = metadata.entry_points(group='markdown.extensions')\n",
"TypeError: entry_points() got an unexpected keyword argument 'group'"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"os.makedirs(logdir, exist_ok=True)\n",
"%tensorboard --logdir logs\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Save the model"
]
},
{
"cell_type": "code",
"source": [
"model.save('./Daten/cifar_10_convnets_1.h5')"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "FE7KNzPPVrVV"
},
"source": [
"# Part 2 - Dogs vs Cats Image Classification : Visualizing what ConvNets learn?"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "gN7G9GFmVrVY"
},
"source": [
"In this notebook chapter, we will discuss how to classify images into pictures of cats or pictures of dogs. We'll build an image classifier using `tf.keras.Sequential` model and load data using `tf.keras.preprocessing.image.ImageDataGenerator`. At the end, we will visualize filters and intermediate activation layers.\n",
"\n",
"In the process, we will build practical experience and develop intuition around the following concepts\n",
"\n",
"* Building _data input pipelines_ using the `tf.keras.preprocessing.image.ImageDataGenerator` class — How can we efficiently work with data on disk to interface with our model?\n",
"* _Overfitting_ - what is it, how to identify it, and how can we prevent it?\n",
"* _Data Augmentation_ and _Dropout_ - Key techniques to fight overfitting in computer vision tasks that we will incorporate into our data pipeline and image classifier model.\n",
"* _Visualizing ConvNet filters_\n",
"* _Visualizing intermediate activations_\n",
"\n",
"\n",
"### We will follow the general machine learning workflow:\n",
"\n",
"1. Examine and understand data\n",
"2. Build an input pipeline\n",
"3. Build our model\n",
"4. Train our model\n",
"5. Test our model\n",
"6. Improve our model/Repeat the process\n",
"\n",
"<hr>\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "zF9uvbXNVrVY"
},
"source": [
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "VddxeYBEVrVZ"
},
"source": [
"Let's start by importing required packages:\n",
"\n",
"* os — to read files and directory structure\n",
"* numpy — for some matrix math outside of TensorFlow\n",
"* matplotlib.pyplot — to plot the graph and display images in our training and validation data"
]
},
{
"cell_type": "code",
"metadata": {
"colab": {},
"colab_type": "code",
"id": "rtPGh2MAVrVa"
},
"outputs": [],
"source": [
"from __future__ import absolute_import, division, print_function, unicode_literals\n",
"\n",
"import os\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"metadata": {
"colab": {},
"colab_type": "code",
"id": "L1WtoaOHVrVh"
},
"outputs": [],
"source": [
"import tensorflow as tf\n",
"from tensorflow.keras.preprocessing.image import ImageDataGenerator"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "UZZI6lNkVrVm"
},
"source": [
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "DPHx8-t-VrVo"
},
"source": [
"To build our image classifier, we begin by downloading the dataset. The dataset we are using is a filtered version of <a href=\"https://www.kaggle.com/c/dogs-vs-cats/data\" target=\"_blank\">Dogs vs. Cats</a> dataset from Kaggle (ultimately, this dataset is provided by Microsoft Research).\n",
"\n",
"In this Jupyter Notebook however, we will make use of the class `tf.keras.preprocessing.image.ImageDataGenerator` which will read data from disk. We therefore need to directly download *Dogs vs. Cats* from a URL and unzip it to your computers filesystem."
]
},
{
"cell_type": "code",
"metadata": {
"colab": {},
"colab_type": "code",
"id": "OYmOylPlVrVt"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Downloading data from https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip\n",
"68608000/68606236 [==============================] - 0s 0us/step\n",
"68616192/68606236 [==============================] - 0s 0us/step\n"
]
}
],
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
"source": [
"_URL = 'https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip'\n",
"\n",
"zip_dir = tf.keras.utils.get_file('cats_and_dogs_filterted.zip', origin=_URL, extract=True)"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "Giv0wMQzVrVw"
},
"source": [
"The dataset we have downloaded has following directory structure.\n",
"\n",
"<pre style=\"font-size: 10.0pt; font-family: Arial; line-height: 2; letter-spacing: 1.0pt;\" >\n",
"<b>cats_and_dogs_filtered</b>\n",
"|__ <b>train</b>\n",
" |______ <b>cats</b>: [cat.0.jpg, cat.1.jpg, cat.2.jpg ....]\n",
" |______ <b>dogs</b>: [dog.0.jpg, dog.1.jpg, dog.2.jpg ...]\n",
"|__ <b>validation</b>\n",
" |______ <b>cats</b>: [cat.2000.jpg, cat.2001.jpg, cat.2002.jpg ....]\n",
" |______ <b>dogs</b>: [dog.2000.jpg, dog.2001.jpg, dog.2002.jpg ...]\n",
"</pre>"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "VpmywIlsVrVx"
},
"source": [
"We'll now assign variables with the proper file path for the training and validation sets."
]
},
{
"cell_type": "code",
"metadata": {
"colab": {},
"colab_type": "code",
"id": "sRucI3QqVrVy"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"/home/jovyan/.keras/datasets\n",
"/home/jovyan/.keras/datasets/cats_and_dogs_filtered\n",
"/home/jovyan/.keras/datasets/cats_and_dogs_filtered/train\n",
"/home/jovyan/.keras/datasets/cats_and_dogs_filtered/validation\n"
]
}
],
"source": [
"print(os.path.dirname(zip_dir))\n",
"base_dir = os.path.join(os.path.dirname(zip_dir), 'cats_and_dogs_filtered')\n",
"print(base_dir)\n",
"train_dir = os.path.join(base_dir, 'train')\n",
"print(train_dir)\n",
"validation_dir = os.path.join(base_dir, 'validation')\n",
"print(validation_dir)"
]
},
{
"cell_type": "code",
"metadata": {
"colab": {},
"colab_type": "code",
"id": "Utv3nryxVrV0"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"/home/jovyan/.keras/datasets/cats_and_dogs_filtered/train/cats\n",
"/home/jovyan/.keras/datasets/cats_and_dogs_filtered/train/dogs\n",
"/home/jovyan/.keras/datasets/cats_and_dogs_filtered/validation/cats\n",
"/home/jovyan/.keras/datasets/cats_and_dogs_filtered/validation/dogs\n"
]
}
],
"source": [
"train_cats_dir = os.path.join(train_dir, 'cats') # directory with our training cat pictures\n",
"print(train_cats_dir)\n",
"train_dogs_dir = os.path.join(train_dir, 'dogs') # directory with our training dog pictures\n",
"print(train_dogs_dir)\n",
"validation_cats_dir = os.path.join(validation_dir, 'cats') # directory with our validation cat pictures\n",
"print(validation_cats_dir)\n",
"validation_dogs_dir = os.path.join(validation_dir, 'dogs') # directory with our validation dog pictures\n",
"print(validation_dogs_dir)"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "ZdrHHTy2VrV3"