{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "_cell_guid": "438e5b93-1cdd-1971-0d6c-742a6cd22cf1"
      },
      "source": [
        "All import"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "de517f59-bd52-02d3-7480-8560bccdfebe"
      },
      "outputs": [],
      "source": [
        "import numpy as np # linear algebra\n",
        "import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n",
        "import matplotlib.pylab as plt\n",
        "from random import shuffle\n",
        "\n",
        "import os\n",
        "import cv2"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "_cell_guid": "9dc42187-6dba-850b-c915-1d26d2d70056"
      },
      "source": [
        "Open Data form the train set "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "90f1a239-53f5-d081-b035-981e62f176b9"
      },
      "outputs": [],
      "source": [
        "train_path = \"../input/train\"\n",
        "\n",
        "ROWS = 128\n",
        "COLS = 128\n",
        "CHANNELS = 3\n",
        "\n",
        "images = [img for img in os.listdir(train_path)]\n",
        "images_dog = [img for img in os.listdir(train_path) if \"dog\" in img]\n",
        "images_cat = [img for img in os.listdir(train_path) if \"cat\" in img]\n",
        "\n",
        "#only taking a subset (less accuracy but faster training)\n",
        "train_dog = images_dog[:1000]\n",
        "train_cat = images_cat[:1000]\n",
        "valid_dog = images_dog[1000:1100]\n",
        "valid_cat = images_cat[1000:1100]\n",
        "\n",
        "train_list = train_dog + train_cat\n",
        "valid_list = valid_dog + valid_cat\n",
        "\n",
        "shuffle(train_list)\n",
        "\n",
        "train = np.ndarray(shape=(len(train_list),ROWS, COLS))\n",
        "labels = np.ndarray(len(train_list))\n",
        "\n",
        "for i, img_path in enumerate(train_list):\n",
        "    img = cv2.imread(os.path.join(train_path, img_path), 0)\n",
        "    img = cv2.resize(img, (ROWS, COLS), interpolation=cv2.INTER_CUBIC)\n",
        "    \n",
        "    train[i] = img\n",
        "    if \"dog\" in img_path:\n",
        "        labels[i] = 0\n",
        "    else:\n",
        "        labels[i] = 1\n",
        "\n",
        "valid = np.ndarray(shape=(len(valid_list), ROWS, COLS))\n",
        "valid_labels = np.ndarray(len(valid_list))\n",
        "\n",
        "for i, img_path in enumerate(valid_list):\n",
        "    img = cv2.imread(os.path.join(train_path, img_path), 0)\n",
        "    img = cv2.resize(img, (ROWS, COLS), interpolation=cv2.INTER_CUBIC)\n",
        "    \n",
        "    valid[i] = img\n",
        "    if \"dog\" in img_path:\n",
        "        valid_labels[i] = 0\n",
        "    else:\n",
        "        valid_labels[i] = 1"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "_cell_guid": "0793e49e-c8a6-8af3-905a-ba9c141630cf"
      },
      "source": [
        "Plot some training samples after prepocessing"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "4d939065-6228-3926-a19c-9974c37760c9"
      },
      "outputs": [],
      "source": [
        "n = 33\n",
        "plt.subplot(1,2,1)\n",
        "plt.imshow(cv2.imread(os.path.join(train_path, train_list[len(train_list)-n])))\n",
        "plt.subplot(1,2,2)\n",
        "plt.imshow(train[len(train_list)-n])\n",
        "plt.title(labels[len(train_list)-n])\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "_cell_guid": "34b00f40-b888-85c3-35b0-8e08b9d632bd"
      },
      "source": [
        "Averaging data and subtract mean (**Feature scaling**)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "91e4c5ad-9d20-da81-bfa2-536e27d8a8a2"
      },
      "outputs": [],
      "source": [
        "def average(data):\n",
        "    minimum = np.min(data)\n",
        "    maximum = np.max(data)\n",
        "    data = (data-minimum)/(maximum-minimum)\n",
        "    data = data - np.mean(data)\n",
        "    return data\n",
        "\n",
        "train = average(train)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "_cell_guid": "6993dfa6-169e-47fe-af94-192d8665ec3d"
      },
      "source": [
        "Train a model using **Keras**"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "b6333649-21e2-95e3-65d8-2aac79ef1999"
      },
      "outputs": [],
      "source": [
        "from keras.models import Sequential\n",
        "from keras.layers import Convolution2D\n",
        "from keras.layers import Dense, Activation, Flatten, Dropout, MaxPooling2D\n",
        "from keras.regularizers import l2\n",
        "\n",
        "model = Sequential()\n",
        "model.add(Convolution2D(8, 3, 3, border_mode='same', input_shape=(ROWS, COLS, 1), activation='relu'))\n",
        "model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), border_mode='same'))\n",
        "model.add(Convolution2D(4, 3, 3, border_mode='same', activation='relu'))\n",
        "model.add(Flatten())\n",
        "model.add(Dense(output_dim=64, W_regularizer=l2(0.01)))\n",
        "model.add(Dropout(0.5))\n",
        "model.add(Activation('relu'))\n",
        "model.add(Dense(output_dim=2, W_regularizer=l2(0.01)))  #binary classification\n",
        "model.add(Activation('softmax'))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "0b243ed3-6eae-92b1-30b5-7d68b4968470"
      },
      "outputs": [],
      "source": [
        "from keras.utils.np_utils import to_categorical\n",
        "from keras.optimizers import SGD, RMSprop\n",
        "#model.compile(loss='binary_crossentropy', optimizer=SGD(lr=0.005, momentum=0.9, decay=0.1, nesterov=False), metrics=['accuracy'])\n",
        "model.compile(loss='binary_crossentropy', optimizer=RMSprop(lr=1e-4), metrics=['accuracy'])\n",
        "labels_ = to_categorical(labels, 2) #convert labels to a matrix representation \n",
        "train_ = np.resize(train, (len(train), ROWS, COLS, 1))\n",
        "model.fit(train_, labels_, nb_epoch=20, batch_size=32)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "_cell_guid": "a786c605-5f63-aae9-5868-a612688259f8"
      },
      "source": [
        "Evaluate on validation set"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "35883ad7-9cc4-75e7-0cca-24fd44065d85"
      },
      "outputs": [],
      "source": [
        "valid_labels_ = to_categorical(valid_labels, 2)\n",
        "valid_ = average(valid)\n",
        "valid_ = np.resize(valid_, (len(valid_), ROWS, COLS, 1))\n",
        "print(\"valid set :\", model.evaluate(valid_, valid_labels_, verbose=False)[1]*100, \"%\")\n",
        "print(\"--------------------\")\n",
        "print(\"train set :\", model.evaluate(train_, labels_, verbose=False)[1]*100, \"%\")"
      ]
    }
  ],
  "metadata": {
    "_change_revision": 0,
    "_is_fork": false,
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.5.2"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}