{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":5441,"databundleVersionId":38425,"sourceType":"competition"}],"dockerImageVersionId":30030,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# import libraries\nimport pandas as pd\nimport numpy as np\n\nfrom zipfile import ZipFile \n\nfrom sklearn.metrics import precision_score, recall_score, accuracy_score\n\nimport os,shutil\n\nimport keras\nimport tensorflow as tf\nfrom keras.models import Sequential\nfrom keras.layers import Conv2D, Dense, MaxPooling2D,Flatten,Dropout\nfrom keras import optimizers\nfrom keras.preprocessing.image import ImageDataGenerator\n\n\nimport matplotlib.pyplot as plt","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-12-07T20:11:57.506394Z","iopub.execute_input":"2023-12-07T20:11:57.506775Z","iopub.status.idle":"2023-12-07T20:12:03.047555Z","shell.execute_reply.started":"2023-12-07T20:11:57.506739Z","shell.execute_reply":"2023-12-07T20:12:03.046816Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# unzip given input files\nimport zipfile\n\nwith zipfile.ZipFile('../input/dogs-vs-cats-redux-kernels-edition/train.zip') as z:\n    z.extractall()\n    \nwith zipfile.ZipFile('../input/dogs-vs-cats-redux-kernels-edition/test.zip') as z:\n    z.extractall()","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","execution":{"iopub.status.busy":"2023-12-07T20:12:09.690901Z","iopub.execute_input":"2023-12-07T20:12:09.691248Z","iopub.status.idle":"2023-12-07T20:12:28.968290Z","shell.execute_reply.started":"2023-12-07T20:12:09.691220Z","shell.execute_reply":"2023-12-07T20:12:28.967544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load sample submission file\nsub = pd.read_csv(\"../input/dogs-vs-cats-redux-kernels-edition/sample_submission.csv\")\nsub.shape","metadata":{"execution":{"iopub.status.busy":"2023-12-07T20:12:31.362206Z","iopub.execute_input":"2023-12-07T20:12:31.362563Z","iopub.status.idle":"2023-12-07T20:12:31.384746Z","shell.execute_reply.started":"2023-12-07T20:12:31.362533Z","shell.execute_reply":"2023-12-07T20:12:31.383788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.head()","metadata":{"execution":{"iopub.status.busy":"2023-12-07T20:12:37.090978Z","iopub.execute_input":"2023-12-07T20:12:37.091374Z","iopub.status.idle":"2023-12-07T20:12:37.110744Z","shell.execute_reply.started":"2023-12-07T20:12:37.091336Z","shell.execute_reply":"2023-12-07T20:12:37.109724Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# creating base directory directories\nbase_dir = './cats_and_dogs_small'\nos.mkdir(base_dir)","metadata":{"execution":{"iopub.status.busy":"2023-12-07T20:16:19.735554Z","iopub.execute_input":"2023-12-07T20:16:19.735993Z","iopub.status.idle":"2023-12-07T20:16:19.740351Z","shell.execute_reply.started":"2023-12-07T20:16:19.735957Z","shell.execute_reply":"2023-12-07T20:16:19.739463Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# creat sub directories(train,validation and test) under base directory\ntrain_dir = os.path.join(base_dir, 'train')\nos.mkdir(train_dir)\n\nvalidation_dir = os.path.join(base_dir, 'validation')\nos.mkdir(validation_dir)\n\ntest_dir = os.path.join(base_dir, 'test')\nos.mkdir(test_dir)","metadata":{"execution":{"iopub.status.busy":"2023-12-07T20:16:23.451536Z","iopub.execute_input":"2023-12-07T20:16:23.451929Z","iopub.status.idle":"2023-12-07T20:16:23.458032Z","shell.execute_reply.started":"2023-12-07T20:16:23.451893Z","shell.execute_reply":"2023-12-07T20:16:23.457143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# create sub-directories(cats and dogs) under each sub directories(train,validation and test) created above\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)","metadata":{"execution":{"iopub.status.busy":"2023-12-07T20:16:26.667571Z","iopub.execute_input":"2023-12-07T20:16:26.668066Z","iopub.status.idle":"2023-12-07T20:16:26.676689Z","shell.execute_reply.started":"2023-12-07T20:16:26.668029Z","shell.execute_reply":"2023-12-07T20:16:26.675804Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# save the path of train and test directories where we saved cats and dogs images after unzipping the input files\noriginal_dataset_train_dir = './train'\noriginal_dataset_test_dir = './test'","metadata":{"execution":{"iopub.status.busy":"2023-12-07T20:16:34.072517Z","iopub.execute_input":"2023-12-07T20:16:34.072887Z","iopub.status.idle":"2023-12-07T20:16:34.077125Z","shell.execute_reply.started":"2023-12-07T20:16:34.072854Z","shell.execute_reply":"2023-12-07T20:16:34.076047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# copy 1000 cats images to \"./cats_and_dogs_small/train/cats\" sub directory we created above, these images will be used for training the model\nfnames = ['cat.{}.jpg'.format(i) for i in range(1000)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_train_dir, fname) # source folder \n    dst = os.path.join(train_cats_dir, fname) # destination folder\n    shutil.copyfile(src, dst) # copying cats images from source to destination folders","metadata":{"execution":{"iopub.status.busy":"2023-12-07T20:16:37.200840Z","iopub.execute_input":"2023-12-07T20:16:37.201236Z","iopub.status.idle":"2023-12-07T20:16:37.326027Z","shell.execute_reply.started":"2023-12-07T20:16:37.201203Z","shell.execute_reply":"2023-12-07T20:16:37.325140Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# copy 500 cats images to \"./cats_and_dogs_small/validation/cats\" sub directory we created above, these images will be used for validing the model\nfnames = ['cat.{}.jpg'.format(i) for i in range(1000, 1500)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_train_dir, fname)\n    dst = os.path.join(validation_cats_dir, fname)\n    shutil.copyfile(src, dst)","metadata":{"execution":{"iopub.status.busy":"2023-12-07T20:16:40.477639Z","iopub.execute_input":"2023-12-07T20:16:40.478026Z","iopub.status.idle":"2023-12-07T20:16:40.540497Z","shell.execute_reply.started":"2023-12-07T20:16:40.477994Z","shell.execute_reply":"2023-12-07T20:16:40.539607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# copy 500 cats images to \"./cats_and_dogs_small/test/cats\" sub directory we created above, these images will be used for testing the model\nfnames = ['cat.{}.jpg'.format(i) for i in range(1500, 2000)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_train_dir, fname)\n    dst = os.path.join(test_cats_dir, fname)\n    shutil.copyfile(src, dst)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# copy 1000 dogs images to \"./cats_and_dogs_small/train/dogs\" sub directory we created above, these images will be used for training the model\nfnames = ['dog.{}.jpg'.format(i) for i in range(1000)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_train_dir, fname)\n    dst = os.path.join(train_dogs_dir, fname)\n    shutil.copyfile(src, dst)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# copy 500 dogs images to \"./cats_and_dogs_small/validation/dogs\" sub directory we created above, these images will be used for validating the model\nfnames = ['dog.{}.jpg'.format(i) for i in range(1000,1500)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_train_dir, fname)\n    dst = os.path.join(validation_dogs_dir, fname)\n    shutil.copyfile(src, dst)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# copy 500 dogs images to \"./cats_and_dogs_small/test/dogs\" sub directory we created above, these images will be used for testing the model\nfnames = ['dog.{}.jpg'.format(i) for i in range(1500,2000)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_train_dir, fname)\n    dst = os.path.join(test_dogs_dir, fname)\n    shutil.copyfile(src, dst)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sanity check - lets check the folder where we copied the data has the data as expected\nprint(\"train_cats_dir:\",len(os.listdir(train_cats_dir)))\nprint(\"validation_cats_dir:\",len(os.listdir(validation_cats_dir)))\nprint(\"test_cats_dir:\",len(os.listdir(test_cats_dir)))\n\nprint(\"train_dogs_dir:\",len(os.listdir(train_dogs_dir)))\nprint(\"validation_dogs_dir:\",len(os.listdir(validation_dogs_dir)))\nprint(\"test_dogs_dir:\",len(os.listdir(test_dogs_dir)))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"So we indeed have 2,000 training images, 1,000 validation images. \n\nEach split contains the same number of samples from each class: this is a balanced binary-classification problem, which means classification accuracy will be an appropriate measure of success. ","metadata":{}},{"cell_type":"code","source":"# import ImageDataGenerator for pre pro-processing JPEG images as explained above\nfrom keras.preprocessing.image import ImageDataGenerator\n\n# scale pixes between 0 and 1 by dividing the pixes by 255\ntrain_datagen = ImageDataGenerator(rescale=1./255)\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\ntrain_generator = train_datagen.flow_from_directory(train_dir,target_size=(150, 150),batch_size=20,class_mode='binary')\n\nvalidation_generator = test_datagen.flow_from_directory(validation_dir,target_size=(150, 150),batch_size=20,class_mode='binary')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# since image generators yields bathches indefinitely, we need to break the loop\nfor 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","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3) Model Building","metadata":{}},{"cell_type":"markdown","source":"### 3.1) Basic CNN Model","metadata":{}},{"cell_type":"code","source":"EPOCH_1 = 1\nEPOCH_100 = 100\nEPOCH_30 = 30","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Basic CNN archietechture without Regularization\ninput_shape = [150,150,3]\n\nmodel = Sequential()\n\nmodel.add(Conv2D(32, kernel_size=(3, 3), activation='relu', \n                 input_shape=input_shape))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\nmodel.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\nmodel.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\nmodel.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\nmodel.add(Flatten())\nmodel.add(Dense(512, activation='relu'))\nmodel.add(Dense(512, activation='relu'))\nmodel.add(Dense(1, activation='sigmoid'))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# compile the model\nmodel.compile(loss='binary_crossentropy',\n              optimizer=optimizers.RMSprop(lr=1e-4),\n              metrics=['accuracy'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# fitting the model as discussed above\nhistory = model.fit_generator(\n            train_generator,\n            steps_per_epoch=100,\n            epochs=EPOCH_30,\n            validation_data=validation_generator,\n            validation_steps=50)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Let’s plot the loss and accuracy of the model over the training and validation data during training\nacc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(1, len(acc) + 1)\nplt.plot(epochs, acc, 'bo', label='Training acc')\nplt.plot(epochs, val_acc, 'b', label='Validation acc')\n\nplt.title('Training and validation accuracy')\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()\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"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')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Let's check augmented images!","metadata":{}},{"cell_type":"code","source":"from 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[3]\nimg = image.load_img(img_path, target_size=(150, 150))\n\nx = image.img_to_array(img)\nx = x.reshape((1,) + x.shape)\nplt.figure(figsize = (12,8))\n\ni=0\n\nfor batch in datagen.flow(x, batch_size=1):\n    plt.subplot(2,2,i+1)\n    imgplot = plt.imshow(image.array_to_img(batch[0]))\n    i += 1\n    if i % 4 == 0:\n        break\n\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Basic CNN archietechture with Regularization\ninput_shape = [150,150,3]\n\nmodel_1 = Sequential()\n\nmodel_1.add(Conv2D(32, kernel_size=(3, 3), activation='relu', \n                 input_shape=input_shape))\nmodel_1.add(MaxPooling2D(pool_size=(2, 2)))\n\nmodel_1.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))\nmodel_1.add(MaxPooling2D(pool_size=(2, 2)))\n\nmodel_1.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))\nmodel_1.add(MaxPooling2D(pool_size=(2, 2)))\n\nmodel_1.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))\nmodel_1.add(MaxPooling2D(pool_size=(2, 2)))\n\nmodel_1.add(Flatten())\nmodel_1.add(Dense(512, activation='relu'))\nmodel_1.add(Dropout(0.3)) # to overcome overfitting\nmodel_1.add(Dense(512, activation='relu'))\nmodel_1.add(Dropout(0.3)) # to overcome overfitting\nmodel_1.add(Dense(1, activation='sigmoid'))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"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\n# note, we are not applying these augmentations to the test data\ntest_datagen = ImageDataGenerator(rescale=1./255)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator = train_datagen.flow_from_directory(train_dir,target_size=(150, 150),batch_size=32,class_mode='binary')\n\nvalidation_generator = test_datagen.flow_from_directory(validation_dir,target_size=(150, 150),batch_size=32,class_mode='binary')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# compile the model\nmodel_1.compile(loss='binary_crossentropy',\n              optimizer=optimizers.RMSprop(lr=1e-4),\n              metrics=['accuracy'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model_1.fit_generator(\n            train_generator,\n            steps_per_epoch=63,            \n            epochs = EPOCH_100,\n            validation_data=validation_generator,\n            validation_steps=32)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Let’s plot the loss and accuracy of the model over the training and validation data during training\nacc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(1, len(acc) + 1)\nplt.plot(epochs, acc, 'bo', label='Training acc')\nplt.plot(epochs, val_acc, 'b', label='Validation acc')\n\nplt.title('Training and validation accuracy')\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()\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"By using regularization techniques even further, and by tuning the network’s parameters (such as the number of filters per convolution layer, or the number of layers in the network), we may be able to get an even better accuracy, likely up to 86% or 87%.\n\nBut it would prove difficult to go any higher just by training your own convnet from scratch, because we have so little data to work with. As a next step to improve your accuracy on this problem, we will use a pretrained model.","metadata":{}},{"cell_type":"code","source":"# lets import VGG16 pre-trained model\nfrom keras.applications import VGG16\n\nconv_base = VGG16(weights='imagenet',include_top=False,input_shape=(150, 150, 3))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"conv_base.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#base_dir = '/Users/fchollet/Downloads/cats_and_dogs_small'\n#train_dir = os.path.join(base_dir, 'train')\n#validation_dir = os.path.join(base_dir, 'validation')\n#test_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(directory,target_size=(150, 150),batch_size=batch_size,class_mode='binary')\n    \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","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_features, train_labels = extract_features(train_dir, 2000)\nvalidation_features, validation_labels = extract_features(validation_dir, 1000)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_features = np.reshape(train_features, (2000, 4*4* 512))\nvalidation_features = np.reshape(validation_features, (1000, 4*4* 512))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Densly Connected Classifier\nmodel = keras.models.Sequential()\nmodel.add(keras.layers.Dense(256, activation='relu', input_dim=4 * 4 * 512))\nmodel.add(keras.layers.Dropout(0.5))\nmodel.add(keras.layers.Dense(1, activation='sigmoid'))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# compile the model\nmodel.compile(optimizer=optimizers.RMSprop(lr=2e-5),\nloss='binary_crossentropy',\nmetrics=['acc'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# fit the model on the features extracted\nhistory = model.fit(train_features, train_labels,epochs=EPOCH_30,batch_size=20,validation_data=(validation_features, validation_labels))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# plotting the results\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()\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()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#  Adding a densely connected classifier on top of the convolutional base\nmodel = keras.models.Sequential()\nmodel.add(conv_base) # adding pre-trained conv base model\nmodel.add(keras.layers.Flatten())\nmodel.add(keras.layers.Dense(256, activation='relu'))\nmodel.add(keras.layers.Dense(1, activation='sigmoid'))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":" print('This is the number of trainable weights before freezing the conv base:', len(model.trainable_weights))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# freezing the layers of pre-trained model\nconv_base.trainable = False","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('This is the number of trainable weights after freezing the conv base:', len(model.trainable_weights))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#  Training the model end to end with a frozen convolutional base\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(validation_dir,target_size=(150, 150),batch_size=20,class_mode='binary')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(loss='binary_crossentropy',optimizer=optimizers.RMSprop(lr=2e-5),metrics=['acc'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit_generator(\n            train_generator,\n            steps_per_epoch=100,\n            epochs=EPOCH_30,\n            validation_data=validation_generator,\n            validation_steps=50)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# plotting the results\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()\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()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"conv_base.trainable = True\nset_trainable = False\n\nfor layer in conv_base.layers:\n    if layer.name == 'block5_conv1':\n        set_trainable = True\n    \n    if set_trainable:\n        layer.trainable = True\n    else:\n        layer.trainable = False","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(loss='binary_crossentropy',optimizer=optimizers.RMSprop(lr=1e-5),metrics=['acc'])\n\nhistory = model.fit_generator(train_generator,steps_per_epoch=100,epochs=EPOCH_100,validation_data=validation_generator,validation_steps=50)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# plotting the results\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()\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()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We have 93% accuracy now, which is way better than the model that we build from scratch.\n\nIn the next version of this notebook, we will make predictions on the test dataset!","metadata":{}}]}