{"cells":[{"metadata":{"trusted":true,"_uuid":"b3bf13be5e863b94570a0df006a47d66b4f024b3"},"cell_type":"code","source":"%reload_ext autoreload\n%autoreload 2\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"caf2074f4a88baf49eea5d31f79de3f494cf85fb"},"cell_type":"code","source":"import os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"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 torch\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\nfrom keras.applications.vgg16 import VGG16\nfrom keras.applications.vgg19 import VGG19\nfrom keras.applications.resnet50 import ResNet50\nfrom keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array\nfrom keras.models import Model\nfrom keras.layers import Activation, Dense, Input, Flatten, Conv2D, Dropout, MaxPooling2D, BatchNormalization\nfrom keras.optimizers import SGD\nfrom keras.callbacks import History\nfrom keras import metrics\nfrom sklearn.model_selection import train_test_split","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"batch_size = 32\nfiles_directory = '../input/dogs-vs-cats/train/train/'\n# img_width, img_height = 224, 224\nimg_width, img_height = 96,96","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"54bde379d2c315bbbb549da905e4a2e854c8d15e"},"cell_type":"markdown","source":"# Prepare the data\nFirst things first, we need to split the data into a list of cat and dog images. Next, we need to put it through Keras's \nImageDataGenerator because there's too many images to fit in memory. Plus, this opens up the possibility of using \nlarger images!\n\nWe'll actually create two ImageDataGenerators, one for training and one for validation!"},{"metadata":{"trusted":true,"_uuid":"856db92a21c7c8647c0fe3397a7f27d2312fe29c"},"cell_type":"code","source":"files = os.listdir(files_directory)\ncat_files = [f for f in files if 'cat' in f]\ndog_files = [f for f in files if 'dog' in f]\n\nprint(cat_files[:3])\nprint(dog_files[:3])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"75a18659c2ab7d832a2e8d56cfa8a9890d120121"},"cell_type":"code","source":"df_cat = pd.DataFrame({\n    'filename': cat_files,\n    'label': 'cat',\n})\ndf_dog = pd.DataFrame({\n    'filename': dog_files,\n    'label': 'dog',\n})\ndf = pd.concat([df_cat, df_dog])\ndf = df.sample(frac=1).reset_index(drop=True)\n\ndf.head(15)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"61ca74accbf68474a6acf91be18812ae403f1d05","scrolled":false},"cell_type":"code","source":"datagen = ImageDataGenerator(\n                             #validation_split=0.01,\n                             rescale=1./255., \n#                              width_shift_range=0.2,\n#                              height_shift_range=0.2,\n                             horizontal_flip=True,\n                             rotation_range=40,\n                             shear_range=0.2,\n                             zoom_range=[0.8, 1.2])\ntrain_gen = datagen.flow_from_dataframe(dataframe=df,\n                                        directory=files_directory,\n                                        x_col='filename',\n                                        y_col='label',\n                                        target_size=(img_height, img_width),\n                                        batch_size=batch_size,\n                                        class_mode='binary',\n                                        shuffle=True\n#                                         subset='training'\n                                       )\n# valid_gen = datagen.flow_from_dataframe(dataframe=df,\n#                                         directory=files_directory,\n#                                         x_col='filename',\n#                                         y_col='label',\n#                                         target_size=(img_height, img_width),\n#                                         batch_size=batch_size,\n#                                         class_mode='binary',\n#                                         shuffle=True,\n#                                         subset='validation')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ba6538d7358ca2a1fd17828f01c97d389ca69b72"},"cell_type":"markdown","source":"# Let's view a batch of images"},{"metadata":{"trusted":true,"_uuid":"6dafe4060fe753e837ea660ffa160d988ffb6715"},"cell_type":"code","source":"print(train_gen.class_indices)\n# print(valid_gen.class_indices)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ceeb45dcf826325a1c8c29f7cb3e38d6f223d9f2"},"cell_type":"code","source":"valid_gen.filenames","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"db8e5a01ad60cb699a90bded46d514ba458e1dbd"},"cell_type":"code","source":"dog_label = train_gen.class_indices['dog']\nbatch_features, batch_labels = next(train_gen)\n# batch_features, batch_labels = next(valid_gen)\n\nrows = 4\ncols = 4\nplt.figure(figsize=(24,24))\nfor i in range(1, rows*cols + 1):\n    plt.subplot(rows,cols,i)\n    plt.imshow(batch_features[i-1])\n    plt.text(0, 0, 'dog' if batch_labels[i-1] == dog_label else 'cat',  # i don't know why this is suddenly getting flipped\n             fontsize=24,\n             color='r')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"251aef43863f466dc264f6d5f0e4ca69ccc4592e"},"cell_type":"markdown","source":"# Transfer Learning\nWe'll use transfer learning to help figure out if the images are cats / dogs \nWe'll test out 3 pre-trained networks:\n- VGG19\n- VGG16\n- ResNet50"},{"metadata":{"trusted":true,"_uuid":"04c5e788f03a9b14f56a5de0189cb8b2a81f3336"},"cell_type":"code","source":"def get_base_model(architecture):\n    if architecture == 'resnet' or architecture == 'resnet50':\n        base_model = ResNet50(weights='../input/resnet50/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5', include_top=False, pooling='average')\n    elif architecture == 'vgg19':\n        base_model = VGG19(weights='../input/vgg19/vgg19_weights_tf_dim_ordering_tf_kernels_notop.h5', include_top=False, pooling='average')\n    else:\n        base_model = VGG16(weights='../input/vgg16/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5', include_top=False, pooling='average')\n    \n    for layer in base_model.layers:\n        layer.trainable = True\n    \n    return base_model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"323261811c298cfed43a8a50f15ebdbb78f3186b"},"cell_type":"code","source":"def get_model():\n    base_model = get_base_model('resnet50')\n    X_input = Input(shape=(img_width, img_height, 3), name='input')\n    \n    X = base_model(X_input)\n    X = Flatten()(X)\n    X = Dropout(0.3)(X)\n    out = Dense(1, activation='sigmoid')(X)\n    return Model(X_input, [out])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e598f9e3501864e890c66d78a25c40190ad5c451","scrolled":false},"cell_type":"code","source":"model = get_model()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b58dd584425e0451c4f2033511f744a52528568f"},"cell_type":"code","source":"all_history = {\n    'loss': [],\n    'val_loss': [],\n    'acc': [],\n    'val_acc': []\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"031aa96689549e013909ffeb68ef48dd4dfed2c8"},"cell_type":"code","source":"model.compile(optimizer='sgd',\n             loss='binary_crossentropy',\n             metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e47a8ffa50e28e60016afba57d5c361b97bff53f","scrolled":true},"cell_type":"code","source":"epochs = 14\nhistory = History()\nmodel.fit_generator(train_gen,\n                    epochs=epochs,\n                    #validation_data=valid_gen,\n                    callbacks=[history])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ca2ae272b5966837ab3d5e68d7c37ac37dd55483"},"cell_type":"code","source":"all_history['loss'] += history.history['loss']\n# all_history['val_loss'] += history.history['val_loss']\nall_history['acc'] += history.history['acc']\n# all_history['val_acc'] += history.history['val_acc']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4dfc36ce594191b2c224e9c8ce40e293977b33ba"},"cell_type":"code","source":"plt.figure(figsize=(8,4))\nplt.plot(all_history['loss'])\nplt.plot(all_history['val_loss'])\nplt.title('Training and Validation Loss')\nplt.legend(['train loss', 'valid loss'])\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6f11f811ca1dcdfc40bc7c1afcaa1e0655c17bab"},"cell_type":"markdown","source":"# Make Predictions"},{"metadata":{"trusted":true,"_uuid":"2c0186bbafadd8990144e5f211b14a92b72554c4"},"cell_type":"code","source":"test_dir = '../input/dogs-vs-cats/test1'\ntest_files = pd.DataFrame({\n    'filename': os.listdir(test_dir),\n})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5e12edbcacce6b9895c23d109e5fa4e5c8aacf45"},"cell_type":"code","source":"test_datagen = ImageDataGenerator(rescale=1./255)\ntest_gen = test_datagen.flow_from_directory(test_dir,\n                                            target_size=(img_height, img_width),\n                                            batch_size=batch_size,\n                                            class_mode=None,\n                                            shuffle=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a4cb52314aa110a007041a5dbd839a2826d6a55a"},"cell_type":"code","source":"test_gen.reset()\npred = model.predict_generator(test_gen, verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a619d308e63cfcdbeb373cd97f3be88ffd21ce58"},"cell_type":"code","source":"pred = [1 if p[0] > 0.5 else 0 for p in pred]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"120aa52b3d0b14e15dea218541b6c72b0110f7df"},"cell_type":"code","source":"test_filenames = test_gen.filenames","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"249d9d6dbb9efda6a3d2af81f00ed37b4e249952"},"cell_type":"code","source":"test_filenames = [f.replace('test1/', '') for f in test_filenames]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2a8026ed889fa2b3f74227155b114088a84c7c56"},"cell_type":"code","source":"submission = pd.DataFrame({\n    'id': test_filenames,\n    'label': pred\n})\nsubmission.to_csv('./submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0ec03dc13b454b2b019a97f7f1583fd34693c5fe"},"cell_type":"code","source":"","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}