{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport zipfile, os\nimport matplotlib.pyplot as plt\nfrom keras.preprocessing.image import ImageDataGenerator, load_img\nfrom keras.applications import VGG16\nfrom keras import models\nfrom keras import layers\nfrom keras import optimizers\nfrom sklearn.model_selection import train_test_split\n\nwith zipfile.ZipFile('/kaggle/input/dogs-vs-cats/train.zip', 'r') as zip:\n    zip.extractall()    \n    zip.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_sub = pd.read_csv('/kaggle/input/dogs-vs-cats/sampleSubmission.csv')\nprint(sample_sub.head())\n\nsample_img = load_img('/kaggle/working/train/cat.6562.jpg') # cute pic :)\nplt.imshow(sample_img)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"filenames = os.listdir('/kaggle/working/train')\n\nlabels = []\nfor filename in filenames:\n    label = filename.split('.')[0] # splits on the first dot\n    if label == 'cat':\n        labels.append('0')\n    else:\n        labels.append('1')\n        \ndf = pd.DataFrame({'id': filenames, 'label':labels })\nprint(df.shape)\ndf.head()\n        \n        ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"By using a previously trained network, we're gonna keep the convolutional base (the series of convolutions and pooling layers) of said model, run a new data through it and then train a new classifier. This is called _feature extraction_. It's important to note that the earlier layers will extract generic patterns, such as edges, colors, textures. Whereas the deeper layers extract more abstract patterns, such as cat ears, dog paws. Thus, if the new dataset differs frmo the original we should only use the first layers of the model.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"conv_base = VGG16(weights='imagenet', include_top=False, input_shape=(200,200,3))\n# include_top refers to including the Dense layer on top of the network (1000 classes, in this case)\n\nmodel = models.Sequential()\nmodel.add(conv_base)\nmodel.add(layers.Flatten())\nmodel.add(layers.Dense(512, activation='relu'))\nmodel.add(layers.Dense(1, activation='sigmoid'))\n\n# freezing the convolutional base so that its weights aren't updated:\n#conv_base.trainable = False\n# only the weights of the Dense layers will be updated\n\n# we're gonna do some fine-tuning by training a part of the convolutional base\n# it's basically freezing all the layers except the most abstract ones\nconv_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\n\n\nmodel.compile(loss='binary_crossentropy', optimizer=optimizers.RMSprop(lr=1e-5), metrics=['acc'])\n\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_datagen = ImageDataGenerator(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)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df, validation_df = train_test_split(df, test_size=0.1)\n\ntrain_size = train_df.shape[0]\nvalidation_size = validation_df.shape[0]\nbatch_size = 20\n\ntrain_generator = train_datagen.flow_from_dataframe(train_df,\n                                                    '/kaggle/working/train/',\n                                                    x_col='id',\n                                                    y_col='label',\n                                                    class_mode='binary',\n                                                   target_size=(200,200),\n                                                   batch_size=batch_size)\n\nvalidation_generator = test_datagen.flow_from_dataframe(validation_df,\n                                                       '/kaggle/working/train/',\n                                                       x_col='id',\n                                                       y_col='label',\n                                                       class_mode='binary',\n                                                       target_size=(200,200),\n                                                       batch_size=batch_size)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit_generator(train_generator,\n                             steps_per_epoch=train_size//batch_size,\n                             epochs=5,\n                             validation_data=validation_generator,\n                             validation_steps=validation_size//batch_size)\n\nmodel.save('catsvsdogs_vgg16.h5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.style.use('ggplot')\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, 'b', label='training acc')\nplt.plot(epochs, val_acc, 'r', label='validation acc')\nplt.title('accuracy')\nplt.legend()\n\nplt.figure()\nplt.plot(epochs, loss, 'b', label='training loss')\nplt.plot(epochs, val_loss, 'r', label='validation loss')\nplt.title('loss')\nplt.legend()\n\nplt.show()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with zipfile.ZipFile('/kaggle/input/dogs-vs-cats/test1.zip', 'r') as zip:\n    zip.extractall()    \n    zip.close()\n    \nfilenames = os.listdir('/kaggle/working/test1')\ntest_df = pd.DataFrame({'id': filenames})\ntest_size = test_df.shape[0]\n\ntest_generator = test_datagen.flow_from_dataframe(test_df,\n                                                 '/kaggle/working/test1/',\n                                                 x_col='id',\n                                                 y_col=None,\n                                                 class_mode=None,\n                                                 batch_size=batch_size,\n                                                 target_size=(200,200))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"prediction = model.predict_generator(test_generator, steps=test_size//batch_size)\nthreshold = 0.5\ntest_df['label'] = np.where(prediction > threshold, 1, 0) # if ...: 1; else: 0\n\nsubmission = test_df.copy()\nsubmission['id'] = submission['id'].str.split('.').str[0]\nsubmission.to_csv('submission_mt.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}