{"cells":[{"metadata":{"_uuid":"fe76d1d1ded592430e7548feacfa38dc42f085d9"},"cell_type":"markdown","source":"# Import Libraries & Check Input Data"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nfrom keras.preprocessing.image import ImageDataGenerator, load_img\nfrom keras.utils import to_categorical\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\nimport random\n\nimport os\nprint(os.listdir(\"../input\"))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7335a579cc0268fba5d34d6f7558f33c187eedb3"},"cell_type":"markdown","source":"# Prepare Training Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"# first thing is extracting the files\nimport os, shutil, zipfile\n\ndata = ['train', 'test1']\n\nfor el in data:\n    with zipfile.ZipFile('../input/' + el + \".zip\", \"r\") as z:\n        z.extractall(\".\")  # extract zip files to current dir","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(os.listdir(\".\"))  # List files in current dir","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"# Image files in training dir is either cat.x.jpg or dog.x.jpg\n# Create a dataframe to label each image file accordingly\nfilenames = os.listdir(\"./train\")\ncategories = []  # store the label for each image file\nfor filename in filenames:\n    category = filename.split('.')[0]\n    if category == 'dog':\n        categories.append(1)\n    else:\n        categories.append(0)\n\ndf = pd.DataFrame({\n    'filename': filenames,\n    'category': categories\n})\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a999484fc35b73373fafe2253ae9db7ff46fdb90"},"cell_type":"markdown","source":"# Examine the Data\nIt shows the data is quite balanced for all categories."},{"metadata":{"trusted":true,"_uuid":"fa26f0bc7a6d835a24989790b20f3c6f32946f45"},"cell_type":"code","source":"df['category'].value_counts().plot.bar()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"400a293df3c8499059d9175f3915187074efd971"},"cell_type":"markdown","source":"# Print a Random Sample Image"},{"metadata":{"trusted":true,"_uuid":"602b40f7353871cb161c60b5237f0da0096b2f47"},"cell_type":"code","source":"sample = random.choice(filenames)\nimage = load_img(\"./train/\"+sample)\nplt.imshow(image)\nprint(sample)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b244e6b7715a04fc6df92dd6dfa3d35c473ca600"},"cell_type":"markdown","source":"# Build Model"},{"metadata":{"trusted":true,"_uuid":"8c9f833c1441b657c779844912d0b8028218d454"},"cell_type":"code","source":"from keras.layers import Dropout, Flatten, Dense\nfrom keras import Model, optimizers\nfrom keras.applications import VGG16\n\nimg_width, img_height = 224, 224\ntarget_size = (img_width, img_height)\n\n# Load a pre-trained convolutional neural network (CNN) model\nmodel = VGG16(include_top=False, weights=\"imagenet\",\n             input_shape = (img_width, img_height, 3))\n\n# Do not retrain feature extraction layers\nfor layer in model.layers:\n    layer.trainable = False\n\nx = model.output\n# Extend the pre-trained model\n# Flatten the output layer to 1 dimension\nx = Flatten()(x)\nx = Dense(512, activation='relu')(x)\n# Add a dropout rate of 0.5 to control overfitting\nx = Dropout(0.5)(x)\n#x = Dense(64, activation='relu')(x)\n# Add a final sigmoid layer for classification\npredictions = Dense(1, activation='sigmoid')(x)\n\nmodel_final = Model(inputs = model.input,\n                   outputs = predictions)\n\nmodel_final.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_final.compile(loss='binary_crossentropy',\n#              optimizer='adam',\n#              optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),\n              optimizer=optimizers.Adam(lr=1e-4),\n              metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a29ebfd697dd7183a1a1345ea41ec138874340b7"},"cell_type":"markdown","source":"# Prepare Test and Training Data"},{"metadata":{"trusted":true,"_uuid":"4eeb7af8dcf02c4ef5ca744c8305c51a2f5cedef"},"cell_type":"code","source":"# Split training & validation datasets\ntrain_df, validate_df = train_test_split(df, test_size=0.1)\ntrain_df = train_df.reset_index()\nvalidate_df = validate_df.reset_index()\n\ntotal_train = train_df.shape[0]\ntotal_validate = validate_df.shape[0]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ff760be9104f7d9492467b8d9d3405011aa77d11"},"cell_type":"markdown","source":"# Construct the Training Image Generator"},{"metadata":{"trusted":true,"_uuid":"4d1c7818703a8a4bac5c036fdea45972aa9e5e9e"},"cell_type":"code","source":"train_datagen = ImageDataGenerator(\n    rotation_range=15,\n    rescale=1./255,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    fill_mode='nearest',\n    width_shift_range=0.1,\n    height_shift_range=0.1\n)\n\nbatch_size = 1  #16  # No of images per batch\nx_col, y_col = 'filename', 'category'\nclass_mode = 'binary'\n\n# To avoid the error below:\n# TypeError: If class_mode=\"binary\", y_col=\"category\" column values must be strings.\ntrain_df['category'] = train_df['category'].astype(str)  #optional\n\ntrain_generator = train_datagen.flow_from_dataframe(\n    train_df, \n    \"./train/\",\n    x_col=x_col,\n    y_col=y_col,\n    class_mode=class_mode,\n    target_size=target_size,\n    batch_size=batch_size\n)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"859c7b2857939c19fd2e3bb32839c9f7deb5aa3f"},"cell_type":"markdown","source":"# Construct the Validation Image Generator"},{"metadata":{"trusted":true,"_uuid":"7925e16bcacc89f4484fb6fe47e54d6420af732e"},"cell_type":"code","source":"validation_datagen = ImageDataGenerator(rescale=1./255)\n\n# To avoid the error below:\n# TypeError: If class_mode=\"binary\", y_col=\"category\" column values must be strings.\nvalidate_df['category'] = validate_df['category'].astype(str)\n\nvalidation_generator = validation_datagen.flow_from_dataframe(\n    validate_df, \n    \"./train/\", \n    x_col=x_col,\n    y_col=y_col,\n    class_mode=class_mode,\n    target_size=target_size,\n    batch_size=batch_size\n)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6e17fc1f002fedd60febb78fee5e81770640b909"},"cell_type":"markdown","source":"# Print Some Generated Images"},{"metadata":{"trusted":true,"_uuid":"23d923dba747f8b47dc75569244cecc6f70df321"},"cell_type":"code","source":"example_df = train_df.sample(n=1).reset_index(drop=True)\nexample_generator = train_datagen.flow_from_dataframe(\n    example_df, \n    \"./train/\", \n    x_col='filename',\n    y_col='category',\n    class_mode='binary'\n)\nplt.figure(figsize=(12, 12))\nfor i in range(0, 9):\n    plt.subplot(3, 3, i+1)\n    for X_batch, Y_batch in example_generator:\n        image = X_batch[0]\n        plt.imshow(image)\n        break\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5cd8df64e794ed17de326b613a9819e7da977a0e"},"cell_type":"markdown","source":"# Train the Model"},{"metadata":{"trusted":true,"_uuid":"0836a4cc8aa0abf603e0f96573c0c4ff383ad56b"},"cell_type":"code","source":"# Train the model\nepochs = 2\nhistory = model_final.fit_generator(\n    train_generator,\n    epochs=epochs,\n    validation_data=validation_generator,\n#    validation_steps=total_validate//batch_size,\n#    steps_per_epoch=total_train//batch_size)\n    validation_steps=100,\n    steps_per_epoch=1000)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"37e05b06e4131600f27d663f2098a2310750f13c"},"cell_type":"code","source":"def plot_model_history(model_history, acc='acc', val_acc='val_acc'):\n    fig, axs = plt.subplots(1,2,figsize=(15,5))\n    axs[0].plot(range(1,len(model_history.history[acc])+1),model_history.history[acc])\n    axs[0].plot(range(1,len(model_history.history[val_acc])+1),model_history.history[val_acc])\n    axs[0].set_title('Model Accuracy')\n    axs[0].set_ylabel('Accuracy')\n    axs[0].set_xlabel('Epoch')\n    axs[0].set_xticks(np.arange(1,len(model_history.history[acc])+1),len(model_history.history[acc])/10)\n    axs[0].legend(['train', 'val'], loc='best')\n    axs[1].plot(range(1,len(model_history.history['loss'])+1),model_history.history['loss'])\n    axs[1].plot(range(1,len(model_history.history['val_loss'])+1),model_history.history['val_loss'])\n    axs[1].set_title('Model Loss')\n    axs[1].set_ylabel('Loss')\n    axs[1].set_xlabel('Epoch')\n    axs[1].set_xticks(np.arange(1,len(model_history.history['loss'])+1),len(model_history.history['loss'])/10)\n    axs[1].legend(['train', 'val'], loc='best')\n    plt.show()\n    \nplot_model_history(history)  # Plot the accuracy & loss during training ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Save the trained model\nmodel_final.save('my_model.h5')","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":4}