{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\nprint(os.listdir(\"../input/dogs-vs-cats-redux-kernels-edition/\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"839e883ab163c78c50705b0c38a303536d05de60"},"cell_type":"code","source":"!pwd","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"eab57a28796b33fefa88f6d4c5848c6996e3fad9"},"cell_type":"code","source":"os.chdir('..')\nos.listdir()","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"import os, shutil\n\noriginal_dataset_dir = 'input/dogs-vs-cats-redux-kernels-edition/train'\n\nbase_dir = 'cats_and_dogs_small'\nos.mkdir(base_dir)\n\ntrain_dir = os.path.join(base_dir, 'train')\nos.mkdir(train_dir)\nvalidation_dir = os.path.join(base_dir, 'validation')\nos.mkdir(validation_dir)\ntest_dir = os.path.join(base_dir, 'test')\nos.mkdir(test_dir)\n\ntrain_cats_dir = os.path.join(train_dir, 'cats')\nos.mkdir(train_cats_dir)\n\ntrain_dogs_dir = os.path.join(train_dir, 'dogs')\nos.mkdir(train_dogs_dir)\n\nvalidation_cats_dir = os.path.join(validation_dir, 'cats')\nos.mkdir(validation_cats_dir)\n\nvalidation_dogs_dir = os.path.join(validation_dir, 'dogs')\nos.mkdir(validation_dogs_dir)\n\ntest_cats_dir = os.path.join(test_dir, 'cats')\nos.mkdir(test_cats_dir)\n\ntest_dogs_dir = os.path.join(test_dir, 'dogs')\nos.mkdir(test_dogs_dir)\n\nfnames = ['cat.{}.jpg'.format(i) for i in range(1000)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_dir, fname)\n    dst = os.path.join(train_cats_dir, fname)\n    shutil.copyfile(src, dst)\n    \nfnames = ['cat.{}.jpg'.format(i) for i in range(1000, 1500)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_dir,  fname)\n    dst = os.path.join(validation_cats_dir, fname)\n    shutil.copyfile(src, dst)\n    \nfnames = ['cat.{}.jpg'.format(i) for i in range(1500, 2000)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_dir, fname)\n    dst = os.path.join(test_cats_dir, fname)\n    shutil.copyfile(src, dst)\n    \nfnames = ['dog.{}.jpg'.format(i) for i in range(1000)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_dir, fname)\n    dst = os.path.join(train_dogs_dir, fname)\n    shutil.copyfile(src, dst)\n    \nfnames = ['dog.{}.jpg'.format(i) for i in range(1000, 1500)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_dir, fname)\n    dst = os.path.join(validation_dogs_dir, fname)\n    shutil.copyfile(src, dst)\n    \nfnames = ['dog.{}.jpg'.format(i) for i in range(1500, 2000)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_dir, fname)\n    dst = os.path.join(test_dogs_dir, fname)\n    shutil.copyfile(src, dst)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ad3f97feaf0e251211abc284ab348446b069a786"},"cell_type":"markdown","source":"### Sanity Checking"},{"metadata":{"trusted":true,"_uuid":"79c9b695d6671d6b1b32ef6923b26135a5ece765"},"cell_type":"code","source":"print('Total training cat images:', len(os.listdir(train_cats_dir)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1257b7ba50d62f97bd899d852e603e14295429ce"},"cell_type":"code","source":"print('Total training dog images:', len(os.listdir(train_dogs_dir)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"036283417251729748ec80c0b2b6f2d44fe3c004"},"cell_type":"code","source":"print('Total validation cat images: ', len(os.listdir(validation_cats_dir)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"42d4d6c32a11b58a31129e331d6f20cff341f859"},"cell_type":"code","source":"print('Total validation dog images:', len(os.listdir(validation_dogs_dir)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0db5fdcfe7734abed6808bd8acc3a801b5c7b632"},"cell_type":"code","source":"print('Total test cat images:', len(os.listdir(test_cats_dir)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d546ede22dda00a3c9cf09c31618fc006ca03503"},"cell_type":"code","source":"print('Total test dog images:', len(os.listdir(test_dogs_dir)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2ba17d97bb2c3dd74037ec138ab49a0c04e36074"},"cell_type":"code","source":"from keras import layers\nfrom keras import models\n\nmodel = models.Sequential()\nmodel.add(layers.Conv2D(32, (3, 3), activation = 'relu',\n                       input_shape = (150, 150, 3)))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Conv2D(64, (3, 3), activation = 'relu'))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Conv2D(128, (3, 3), activation = 'relu'))\nmodel.add(layers.MaxPooling2D(2, 2))\nmodel.add(layers.Conv2D(128, (3, 3), activation = 'relu'))\nmodel.add(layers.MaxPooling2D(2, 2))\nmodel.add(layers.Flatten())\nmodel.add(layers.Dense(512, activation = 'relu'))\nmodel.add(layers.Dense(1, activation = 'sigmoid'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f69a90f7b7492db30085df382fa7f6dacf87f5e0"},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"faeff86ef4a3fabca83acb0604fa051fa8fefa16"},"cell_type":"code","source":"from keras import optimizers\n\nmodel.compile(loss = 'binary_crossentropy',\n             optimizer=optimizers.RMSprop(lr=1e-4),\n             metrics = ['acc'])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"892239faa975048151102b6b874ccf1be9b8f16c"},"cell_type":"markdown","source":"### Using ImageDataGenerator to read images from directories"},{"metadata":{"trusted":true,"_uuid":"817aa992fc2c1f9100f957244aba9b0cd952992c"},"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\n\ntrain_datagen = ImageDataGenerator(rescale = 1./255)\ntest_datagen = ImageDataGenerator(rescale = 1./255)\n\ntrain_generator = train_datagen.flow_from_directory(\n                    train_dir,\n                    target_size = (150, 150),\n                    batch_size = 20,\n                    class_mode = 'binary')\n\nvalidation_generator = test_datagen.flow_from_directory(\n                        validation_dir,\n                        target_size = (150, 150),\n                        batch_size = 20,\n                        class_mode = 'binary')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c82098381892ca68f8f4ca5bed82019efde6c195"},"cell_type":"code","source":"for data_batch, labels_batch in train_generator:\n    print('data batch shape:', data_batch.shape)\n    print('labels batch shape:', labels_batch.shape)\n    break","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"67609867d950c8578d7cc6673540a9719c8bee9f"},"cell_type":"markdown","source":"### Fitting the model using a batch generator"},{"metadata":{"trusted":true,"_uuid":"3e44068bbc79e07f00de1dc84df25597dc40e27a"},"cell_type":"code","source":"history = model.fit_generator(\n                train_generator,\n                steps_per_epoch = 100,\n                epochs = 30,\n                validation_data = validation_generator,\n                validation_steps = 50)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1a6eecf5e7efb74abcc13be005a014a75f5623e5"},"cell_type":"markdown","source":"### Saving the Model"},{"metadata":{"trusted":true,"_uuid":"77b349ae2fe2c4d11e18a995ea738bbe9eec753b"},"cell_type":"code","source":"model.save('cats_and_dogs_small_1.h5')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"512646a6e091182b3ad074089811bdb75bb01d27"},"cell_type":"markdown","source":"### Displaying curves of loss and accuracy during training"},{"metadata":{"trusted":true,"_uuid":"f520c2e9917c3b382af62ffe46f5d66ddb9c8276"},"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nacc = history.history['acc']\nval_acc = history.history['val_acc']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(1, len(acc) + 1)\n\nplt.plot(epochs, acc, 'bo', label = 'Training acc')\nplt.plot(epochs, val_acc, 'b', label = 'Validation acc')\nplt.title('Training and Validation Accuracy')\nplt.legend()\n\nplt.figure()\n\nplt.plot(epochs, loss, 'bo', label = 'Training loss')\nplt.plot(epochs, val_loss, 'b', label = 'Validation loss')\nplt.title('Training and Validation Loss')\nplt.legend()\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7e30002ef79c0dc5ebcbd98bb4112e7a42fc9c71"},"cell_type":"code","source":"datagen = ImageDataGenerator(\n                            rotation_range=40,\n                            width_shift_range=0.2,\n                            height_shift_range=0.2,\n                            shear_range=0.2,\n                            zoom_range=0.2,\n                            horizontal_flip=True,\n                            fill_mode='nearest')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"065c72901d5367edfeaf837f08547caf31f3ba2c"},"cell_type":"markdown","source":"### Displaying some randomly augmented training images"},{"metadata":{"trusted":true,"_uuid":"80bd2e2d97e9a0fb06f89d1d2ba48c327d25230e"},"cell_type":"code","source":"import matplotlib.pyplot as plt\nfrom keras.preprocessing import image\n\nfnames = [os.path.join(train_cats_dir, fname) for fname in os.listdir(train_cats_dir)]\n\nimg_path = fnames[500]\n\nimg = image.load_img(img_path, target_size = (150, 150))\n\nx = image.img_to_array(img)\n\nx = x.reshape((1,) + x.shape)\n\ni = 0\nfor batch in datagen.flow(x, batch_size = 1):\n    plt.figure()\n    imgplot = plt.imshow(image.array_to_img(batch[0]))\n    i += 1\n    if i % 4 == 0:\n        break\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"79a7f9518d0b685a7eb235dfd1d58fe535e6f689"},"cell_type":"markdown","source":"### Defining a new convnet using dropout"},{"metadata":{"trusted":true,"_uuid":"29a30db8d1122a360cdda421c659c79ca544c407"},"cell_type":"code","source":"model = models.Sequential()\nmodel.add(layers.Conv2D(32, (3, 3), activation = 'relu', input_shape = (150, 150, 3)))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Conv2D(64, (3, 3), activation = 'relu'))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Conv2D(128, (3, 3), activation = 'relu'))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Conv2D(128, (3, 3), activation = 'relu'))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Flatten())\nmodel.add(layers.Dropout(0.5))\nmodel.add(layers.Dense(512, activation = 'relu'))\nmodel.add(layers.Dense(1, activation = 'sigmoid'))\n\nmodel.compile(loss = 'binary_crossentropy',\n             optimizer=optimizers.RMSprop(lr=1e-4),\n             metrics=['acc'])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c4c3333ae0d461b9005628b96f484521931ce809"},"cell_type":"markdown","source":"### Training the generator using data-augmentation generators"},{"metadata":{"trusted":true,"_uuid":"67b1797abd5a390b1c5c5d36f0c5c8ac1174f418"},"cell_type":"code","source":"train_datagen = ImageDataGenerator(\n                rescale = 1./255,\n                rotation_range=40,\n                width_shift_range=0.2,\n                height_shift_range=0.2,\n                shear_range=0.2,\n                zoom_range=0.2,\n                horizontal_flip=True)\n\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\ntrain_generator = train_datagen.flow_from_directory(\n                                train_dir,\n                                target_size = (150, 150),\n                                batch_size = 32,\n                                class_mode='binary')\n\nvalidation_generator = test_datagen.flow_from_directory(\n                                validation_dir,\n                                target_size = (150, 150),\n                                batch_size = 32,\n                                class_mode = 'binary')\n\nhistory = model.fit_generator(\n                            train_generator,\n                            steps_per_epoch = 100,\n                            epochs = 100,\n                            validation_data = validation_generator,\n                            validation_steps = 50)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"27f836e07bd7a5c816f35a2d956f1566da840b25"},"cell_type":"markdown","source":"### Saving the Model"},{"metadata":{"trusted":true,"_uuid":"6ae79263ed3bdc585d619ca9f5095ed19cf4a4c8"},"cell_type":"code","source":"model.save('cats_and_dogs_small_2.h5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1793613170719c5d5d55a2f7cecc2282ec4c20a4"},"cell_type":"code","source":"acc = history.history['acc']\nval_acc = history.history['val_acc']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(1, len(acc) + 1)\n\nplt.plot(epochs, acc, 'bo', label='Training Accuracy')\nplt.plot(epochs, val_acc, 'b', label = 'Validation Accuracy')\nplt.title('Training and Validation Accuracy')\nplt.legend()\n\nplt.figure()\n\nplt.plot(epochs, loss, 'bo', label = 'Training loss')\nplt.plot(epochs, val_loss, 'b', label='Validation loss')\nplt.title('Training and Validation loss')\nplt.legend()\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b6a5a4f791ae49ca1ed584820ba481ad2436c2f0"},"cell_type":"code","source":"import os\nprint(os.listdir('input/vgg16'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"47c123b99b72082ba2b86b9e3ca9ac5a8950fa26"},"cell_type":"code","source":"from keras.applications import VGG16\n\nconv_base = VGG16(weights='input/vgg16/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5',\n                 include_top = False,\n                 input_shape = (150, 150, 3))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5689ce7043688e93c4fdd1b659fa0cfd1f1a7a6f"},"cell_type":"code","source":"conv_base.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"570a02bd0c0db9a1807d35ebeac81b443c16e941"},"cell_type":"markdown","source":"### Fast Feature extraction without using data augmentation"},{"metadata":{"trusted":true,"_uuid":"f7297916464f3e70e2ebd5a557b80eb384aa662b"},"cell_type":"code","source":"!ls cats_and_dogs_small/","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3fe9a0e6b8319cb7412037cf6fb2ddf43853b89e"},"cell_type":"code","source":"import os\nimport numpy as np\nfrom keras.preprocessing.image import ImageDataGenerator\n\nbase_dir = 'cats_and_dogs_small'\ntrain_dir = os.path.join(base_dir, 'train')\nvalidation_dir = os.path.join(base_dir, 'validation')\ntest_dir = os.path.join(base_dir, 'test')\n\ndatagen = ImageDataGenerator(rescale = 1./255)\nbatch_size = 20\n\ndef extract_features(directory, sample_count):\n    features = np.zeros(shape = (sample_count, 4, 4, 512))\n    labels = np.zeros(shape = (sample_count))\n    generator = datagen.flow_from_directory(\n                        directory,\n                        target_size = (150, 150),\n                        batch_size = batch_size,\n                        class_mode='binary')\n    i = 0\n    for inputs_batch, labels_batch in generator:\n        features_batch = conv_base.predict(inputs_batch)\n        features[i*batch_size : (i + 1) * batch_size] = features_batch\n        labels[ i * batch_size : (i + 1) * batch_size ] = labels_batch\n        i += 1\n        if i * batch_size >= sample_count:\n            break\n    return features, labels\n\ntrain_features, train_labels = extract_features(train_dir, 2000)\nvalidation_features, validation_labels = extract_features(validation_dir, 1000)\ntest_features, test_labels = extract_features(test_dir, 1000)\n\ntrain_features = np.reshape(train_features, (2000, 4 * 4 * 512))\nvalidation_features = np.reshape(validation_features, (1000, 4 * 4 * 512))\ntest_features = np.reshape(test_features, (1000, 4 * 4 * 512))\n        ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b12df498b9f3d110200f0bfee9d6dfba5a071aaa"},"cell_type":"markdown","source":"### Defining and training the densely connected classifier"},{"metadata":{"trusted":true,"_uuid":"d3036e33a6ffc2bdf910a42a08199f369aaaea2a"},"cell_type":"code","source":"from keras import models\nfrom keras import layers\nfrom keras import optimizers\n\nmodel = models.Sequential()\nmodel.add(layers.Dense(256, activation = 'relu', input_dim = 4 * 4 * 512))\nmodel.add(layers.Dropout(0.5))\nmodel.add(layers.Dense(1, activation = 'sigmoid'))\n\nmodel.compile(optimizer=optimizers.RMSprop(lr=1e-5),\n             loss='binary_crossentropy',\n             metrics=['acc'])\n\nhistory = model.fit(train_features, train_labels,\n                   epochs = 30,\n                    batch_size = 20,\n                   validation_data = (validation_features, validation_labels))\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"70ed873dc92264725ecf7e1cea1e372138ff34fc"},"cell_type":"markdown","source":"### Plotting the results"},{"metadata":{"trusted":true,"_uuid":"931447f9857b97bb1ff9829ea311d0152664d259"},"cell_type":"code","source":"acc = history.history['acc']\nval_acc = history.history['val_acc']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(1, len(acc) + 1)\n\nplt.plot(epochs, acc, 'bo', label = 'Training Accuracy')\nplt.plot(epochs, val_acc, 'b', label = 'Validation Accuracy')\nplt.title('Training and Validation Accuracy')\nplt.legend()\n\nplt.figure()\n\nplt.plot(epochs, loss, 'bo', label = 'Training Loss')\nplt.plot(epochs, val_loss, 'b', label = 'Validation Loss')\nplt.title('Training and Validation Loss')\nplt.legend()\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f4963ae1f6ebed1e7ed4946e878eedc2c17f3e10"},"cell_type":"markdown","source":"### Feature Extraction with Data Augmentation\n    Addding a densely connected classifier on top of the convolutional base"},{"metadata":{"trusted":true,"_uuid":"be1a77afc4ea9b6243ffbc276aec7aab944994c6"},"cell_type":"code","source":"from  keras import models\nfrom keras import layers\n\nmodel = models.Sequential()\nmodel.add(conv_base)\nmodel.add(layers.Flatten())\nmodel.add(layers.Dense(256, activation = 'relu'))\nmodel.add(layers.Dense(1, activation = 'sigmoid'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"baf9ec64a899444d8509e59f2a6f70bb52eb1231"},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a6424dca4c2124726728120a8d8ad756c9ddffcf"},"cell_type":"code","source":"print('This is the number of trainable weights before freezing the conv base: ',len(model.trainable_weights))\nconv_base.trainable = False\nprint('This is the number of trainable weights after freezing the conv base:', len(model.trainable_weights))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"15ae49f9633147a01e672c37062d3a877bb2c553"},"cell_type":"markdown","source":"### Training the model end to end with a frozen convolutional base"},{"metadata":{"trusted":true,"_uuid":"bb9b7c24a23b8403168489a775a2bd76624c7c88"},"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\nfrom keras import optimizers\n\ntrain_datagen = ImageDataGenerator(\n                                rescale = 1./255,\n                                rotation_range = 40,\n                                width_shift_range = 0.2,\n                                height_shift_range = 0.2,\n                                shear_range = 0.2,\n                                zoom_range=0.2,\n                                horizontal_flip=True,\n                                fill_mode='nearest')\n\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\ntrain_generator = train_datagen.flow_from_directory(\n        train_dir,\n        target_size=(150, 150),\n        batch_size = 20,\n        class_mode = 'binary')\n\nvalidation_generator = test_datagen.flow_from_directory(\n        validation_dir,\n        target_size = (150, 150),\n        batch_size = 20,\n        class_mode = 'binary')\n\nmodel.compile(loss = 'binary_crossentropy',\n            optimizer = optimizers.RMSprop(lr=2e-5),\n             metrics=['acc'])\n\nhistory = model.fit_generator(\n        train_generator,\n        steps_per_epoch=100,\n        epochs=30,\n        validation_data=validation_generator,\n        validation_steps = 50)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"62cee0adc0fbbd44da6b37efaf0fd26597381fed"},"cell_type":"code","source":"acc = history.history['acc']\nval_acc = history.history['val_acc']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(1, len(acc) + 1)\n\nplt.plot(epochs, acc, 'bo', label = 'Training Acc')\nplt.plot(epochs, val_acc, 'b', label = 'Validation Acc')\nplt.title('Training and Validation Acc')\nplt.legend()\n\nplt.figure()\nplt.plot(epochs, loss, 'bo', label = 'Training Loss')\nplt.plot(epochs, val_loss, 'b', label = 'Validation Loss')\nplt.title('Training and Validation Loss')\nplt.legend()\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"47f72889953f5cbd7970d3336eeb5a57960907b8"},"cell_type":"code","source":"conv_base.summary()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"958edf26f75491b2a5664d56a375441ec0c1c009"},"cell_type":"markdown","source":"### Freezing all layers up to a specific one"},{"metadata":{"trusted":true,"_uuid":"cb5cbe1b4a6c7aee4aaa85d7c3f18a02643eb822"},"cell_type":"code","source":"conv_base.trainable = True\n\nset_trainable = False\nfor layer in conv_base.layers:\n    if layer.name == 'block5_conv1':\n        set_trainable = True\n    if set_trainable:\n        layer.trainable = True\n    else:\n        layer.trainable = False","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2cbfe67af785d8e47ae5512c2d8dbb4d9c85b892"},"cell_type":"markdown","source":"### Fine tuning the model"},{"metadata":{"trusted":true,"_uuid":"326a4069fc1371a2c54d8034fa41d5243173ea16"},"cell_type":"code","source":"model.compile(loss = 'binary_crossentropy',\n             optimizer=optimizers.RMSprop(lr=1e-5),\n             metrics=['acc'])\n\nhistory = model.fit_generator(\n    train_generator,\n    steps_per_epoch=100,\n    epochs=100,\n    validation_data = validation_generator,\n    validation_steps=50)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"71c0ef0302917c813d3cda248d22a2a779d8e766"},"cell_type":"code","source":"acc = history.history['acc']\nval_acc = history.history['val_acc']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(1, len(acc) + 1)\n\nplt.plot(epochs, acc, 'bo', label = 'Training Accuracy')\nplt.plot(epochs, val_acc, 'b', label = 'Validation Accuracy')\nplt.title('Training and Validation Accuracy')\n\nplt.figure()\nplt.plot(epochs, loss, 'bo', label ='Training Loss')\nplt.plot(epochs, val_loss, 'b', label = 'Validation Loss')\nplt.title('Training and validation loss')\nplt.legend()\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5400b94890cc4717270f3430991fd3b37437d1ef"},"cell_type":"markdown","source":"### Smoothing the plots"},{"metadata":{"trusted":true,"_uuid":"b4053aaab1a6e303dd1f0bd667ead36019a66854"},"cell_type":"code","source":"def smoothed_curve(points, factor=0.8):\n    smoothed_points = []\n    for point in points:\n        if smoothed_points:\n            previous = smoothed_points[-1]\n            smoothed_points.append(previous * factor + point * (1 - factor))\n        else:\n            smoothed_points.append(point)\n    return smoothed_points\n\nplt.plot(epochs, smoothed_curve(acc), 'bo', label = 'Smoothed training acc')\nplt.plot(epochs, smoothed_curve(val_acc), 'b', label = 'Smoothed validation acc')\nplt.title('Smoothed Training and Validation Accuracy')\nplt.legend()\n\nplt.figure()\nplt.plot(epochs, smoothed_curve(loss), 'bo', label = 'Smoothed training loss')\nplt.plot(epochs, smoothed_curve(val_loss), 'b', label = 'Smoothed validation loss')\nplt.title('Smoothed Training and Validation Loss')\nplt.legend()\n\nplt.show()\n\n        ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"12446d68b6ea6d877bb84693c1c59c3b0706ac83"},"cell_type":"markdown","source":"### Testing on test data"},{"metadata":{"trusted":true,"_uuid":"21c89008c7ecf45462f1e611e4bf05559d12124f"},"cell_type":"code","source":"test_generator = test_datagen.flow_from_directory(\n        test_dir,\n        target_size=(150, 150),\n        batch_size=20,\n        class_mode='binary')\n\ntest_loss, test_acc = model.evaluate_generator(test_generator, steps=50)\nprint('test acc:', test_acc)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3cb1c0118cc83821670d388031a9c89a8106a5c2"},"cell_type":"markdown","source":"### Visualizing Convnet filters\nDefining the loss tensor for filter visualization"},{"metadata":{"trusted":true,"_uuid":"788d326795c55fb90390b6e289fe5897c00a33ae"},"cell_type":"code","source":"from keras.applications import VGG16\nfrom keras import backend as K\n\nmodel = VGG16(weights = 'input/vgg16/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5',\n             include_top = False)\n\nlayer_name = 'block3_conv1'\nfilter_index = 0\n\nlayer_output = model.get_layer(layer_name).output\nloss = K.mean(layer_output[:, :, :, filter_index])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4527d51bd6481a24eae6dd8973ccd58aabf9e96f"},"cell_type":"markdown","source":"### Obtaining the gradient of the loss with regard to the input"},{"metadata":{"trusted":true,"_uuid":"c9179f739dd17cd6bf0dfde04960bf7b1a081d71"},"cell_type":"code","source":"grads = K.gradients(loss, model.input)[0]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d9c39543f8f224d0a3e937d9057762eb1eaf27e7"},"cell_type":"markdown","source":"### Gradient Normalization Trick"},{"metadata":{"trusted":true,"_uuid":"b08c6954c2ad55832d5039979b6bb113bc7f5250"},"cell_type":"code","source":"grads /= (K.sqrt(K.mean(K.square(grads))) + 1e-5)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5d09d529282b93a6c90c95eeecb0f62c4249773a"},"cell_type":"markdown","source":"### Fetching numpy output values given Numpy input values"},{"metadata":{"trusted":true,"_uuid":"f2a200c28d8d8e02e947c7189cfc2a5789afa25b"},"cell_type":"code","source":"iterate = K.function([model.input], [loss, grads])\n\nimport numpy as np\nloss_value, grads_value = iterate([np.zeros((1, 150, 150, 3))])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7b2f276a921bdf844196f9b8833781d7d0c41ef3"},"cell_type":"markdown","source":"### Loss Maximization using stochastic gradient descent"},{"metadata":{"trusted":true,"_uuid":"dea05017c171f87f00e8c392268b4b77b4229c28"},"cell_type":"code","source":"input_img_data = np.random.random((1, 150, 150, 3)) * 20 + 128\nstep = 1\n\nfor i in range(40):\n    loss_value, grads_value = iterate([input_img_data])\n    \n    input_img_data += grads_value * step ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"40bed2ef10e2e492d4e70439c4b543ad08a7b8a1"},"cell_type":"markdown","source":"### Utility function to convert a tensor into a valid image"},{"metadata":{"trusted":true,"_uuid":"f5608a9c847e24e984f90ec5fcdd629ac06819b6"},"cell_type":"code","source":"def deprocess_image(x):\n    x -= x.mean()\n    x /= (x.std() + 1e-5)\n    x *= 0.1\n    \n    x += 0.5\n    x = np.clip(x, 0, 1)\n    \n    x *= 255\n    x = np.clip(x, 0, 255).astype('uint8')\n    return x","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"4ff3ad2a6ce2356a7c62eaefb2027dbd015428f3"},"cell_type":"markdown","source":"### Function to generate filter visualizations"},{"metadata":{"trusted":true,"_uuid":"b5ef3f4075201937c1a5c1fa62f343f187bdadd6"},"cell_type":"code","source":"def generate_pattern(layer_name, filter_index, size = 150):\n    layer_output = model.get_layer(layer_name).output\n    loss = K.mean(layer_output[:, :, :, filter_index])\n    \n    grads = K.gradients(loss, model.input)[0]\n    grads /= (K.sqrt(K.mean(K.square(grads))) + 1e-5)\n    iterate = K.function([model.input], [loss, grads])\n    input_img_data = np.random.random((1, size, size, 3))* 20 + 128\n    \n    step = 1\n    for i in range(40):\n        loss_value, grads_value = iterate([input_img_data])\n        input_img_data += grads_value * step\n        \n    img = input_img_data[0]\n    return deprocess_image(img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d3109d1303946e4f96a57950cd2880e249baee21"},"cell_type":"code","source":"plt.imshow(generate_pattern('block3_conv1', 0 ))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a50f530d3b8e500e065e79889ddca5fc8bbcc657"},"cell_type":"markdown","source":"### Generating a grid of all filter response patterns in a layer"},{"metadata":{"trusted":true,"_uuid":"5e8531664ff9ae55514bf5a28752419abeecd379"},"cell_type":"code","source":"layer_name = 'block1_conv1'\nsize = 64\nmargin = 5\n\nresults = np.zeros((8 * size + 7 * margin, 8 * size + 7 * margin, 3))\n\nfor i in range(8):\n    for j in range(8):\n        filter_img = generate_pattern(layer_name, i + (j * 8), size = size)\n\n        horizontal_start = i * size + i* margin\n        horizontal_end = horizontal_start + size\n        vertical_start = j * size + j * margin\n        vertical_end = vertical_start + size\n        results[horizontal_start: horizontal_end,\n               vertical_start : vertical_end, :] = filter_img\n\nplt.figure(figsize=(10, 10))\nplt.imshow(results)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b2e0a0dfb429a29d1cc41cc74c85092017129e78"},"cell_type":"markdown","source":"### Loading the VGG16 network with pretrained weights\n`Note: We are including the densely connected classifier on top; in all previous cases we discarded it`"},{"metadata":{"trusted":true,"_uuid":"3a0b0a05f0d5c384f5b7b7175df89d3af19671e1"},"cell_type":"code","source":"from keras.applications.vgg16 import VGG16\n\nmodel = VGG16(weights='input/vgg16/vgg16_weights_tf_dim_ordering_tf_kernels.h5')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"63c19496ec16c9c43e36757bd3c84f4fe3b6100a"},"cell_type":"markdown","source":"### Preprocessing an input image for VGG16"},{"metadata":{"trusted":true,"_uuid":"e09a4f9011c981bfde9ba630fa6318e67093c2f4"},"cell_type":"code","source":"from keras.preprocessing import image\nfrom keras.applications.vgg16 import preprocess_input, decode_predictions\nimport numpy as np\n","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}