{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "_cell_guid": "3feb3c61-7fbc-f846-2f76-c5b159d7eb07"
      },
      "source": [
        "Cat Vs Dog"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "eb9c8e32-ca37-58e6-749e-50502a4eb52e"
      },
      "outputs": [],
      "source": [
        "import cv2                 # working with, mainly resizing, images\n",
        "import numpy as np         # dealing with arrays\n",
        "import os                  # dealing with directories\n",
        "from random import shuffle # mixing up or currently ordered data that might lead our network astray in training.\n",
        "from tqdm import tqdm      # a nice pretty percentage bar for tasks. Thanks to viewer Daniel B\u00fchler for this suggestion\n",
        "\n",
        "TRAIN_DIR = '../input/train'\n",
        "TEST_DIR = '../input/test'\n",
        "IMG_SIZE = 50\n",
        "LR = 1e-3\n",
        "\n",
        "MODEL_NAME = 'dogsvscats-{}-{}.model'.format(LR, '2conv-basic') # just so we remember which saved model is which, sizes must match"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "76d0f740-985a-1dd6-df17-e91135ad8a38"
      },
      "outputs": [],
      "source": [
        "def label_img(img):\n",
        "    word_label = img.split('.')[-3]\n",
        "    # conversion to one-hot array [cat,dog]\n",
        "    #                            [much cat, no dog]\n",
        "    if word_label == 'cat': return [1,0]\n",
        "    #                             [no cat, very doggo]\n",
        "    elif word_label == 'dog': return [0,1]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "d3e082a4-0da5-e6d5-166d-b59e61023b9e"
      },
      "outputs": [],
      "source": [
        "def create_train_data():\n",
        "    training_data = []\n",
        "    for img in tqdm(os.listdir(TRAIN_DIR)):\n",
        "        label = label_img(img)\n",
        "        path = os.path.join(TRAIN_DIR,img)\n",
        "        img = cv2.imread(path,cv2.IMREAD_GRAYSCALE)\n",
        "        img = cv2.resize(img, (IMG_SIZE,IMG_SIZE))\n",
        "        training_data.append([np.array(img),np.array(label)])\n",
        "    shuffle(training_data)\n",
        "    np.save('train_data.npy', training_data)\n",
        "    return training_data"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "0c06bd92-938d-cb13-5a9c-8f05858e7384"
      },
      "outputs": [],
      "source": [
        "def process_test_data():\n",
        "    testing_data = []\n",
        "    for img in tqdm(os.listdir(TEST_DIR)):\n",
        "        path = os.path.join(TEST_DIR,img)\n",
        "        img_num = img.split('.')[0]\n",
        "        img = cv2.imread(path,cv2.IMREAD_GRAYSCALE)\n",
        "        img = cv2.resize(img, (IMG_SIZE,IMG_SIZE))\n",
        "        testing_data.append([np.array(img), img_num])\n",
        "        \n",
        "    shuffle(testing_data)\n",
        "    np.save('test_data.npy', testing_data)\n",
        "    return testing_data"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "c6d06e66-5dda-010b-de11-14131dded140"
      },
      "outputs": [],
      "source": [
        "train_data = create_train_data()\n",
        "# If you have already created the dataset:\n",
        "#train_data = np.load('train_data.npy')"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "2101ee61-1d91-3de9-d607-19a3a743b76a"
      },
      "outputs": [],
      "source": [
        "import tflearn\n",
        "from tflearn.layers.conv import conv_2d, max_pool_2d\n",
        "from tflearn.layers.core import input_data, dropout, fully_connected\n",
        "from tflearn.layers.estimator import regression\n",
        "\n",
        "convnet = input_data(shape=[None, IMG_SIZE, IMG_SIZE, 1], name='input')\n",
        "\n",
        "convnet = conv_2d(convnet, 32, 5, activation='relu')\n",
        "convnet = max_pool_2d(convnet, 5)\n",
        "\n",
        "convnet = conv_2d(convnet, 64, 5, activation='relu')\n",
        "convnet = max_pool_2d(convnet, 5)\n",
        "\n",
        "convnet = fully_connected(convnet, 1024, activation='relu')\n",
        "convnet = dropout(convnet, 0.8)\n",
        "\n",
        "convnet = fully_connected(convnet, 2, activation='softmax')\n",
        "convnet = regression(convnet, optimizer='adam', learning_rate=LR, loss='categorical_crossentropy', name='targets')\n",
        "\n",
        "model = tflearn.DNN(convnet, tensorboard_dir='log')"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "c51a7725-1e40-0c19-593d-01e8206551c9"
      },
      "outputs": [],
      "source": [
        "if os.path.exists('{}.meta'.format(MODEL_NAME)):\n",
        "    model.load(MODEL_NAME)\n",
        "    print('model loaded!')"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "9bfa5182-0a27-a724-35b6-47e662891b9e"
      },
      "outputs": [],
      "source": [
        "train = train_data[:-500]\n",
        "test = train_data[-500:]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "19843ba8-bcd9-f7e4-21ee-5b7f19768930"
      },
      "outputs": [],
      "source": [
        "X = np.array([i[0] for i in train]).reshape(-1,IMG_SIZE,IMG_SIZE,1)\n",
        "Y = [i[1] for i in train]\n",
        "\n",
        "test_x = np.array([i[0] for i in test]).reshape(-1,IMG_SIZE,IMG_SIZE,1)\n",
        "test_y = [i[1] for i in test]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "3c134973-ec8b-a6c8-aba8-4b712072b431"
      },
      "outputs": [],
      "source": [
        "model.fit({'input': X}, {'targets': Y}, n_epoch=2, validation_set=({'input': test_x}, {'targets': test_y}), \n",
        "    snapshot_step=50000, show_metric=True, run_id=MODEL_NAME)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "2d0e64ab-5ecc-5ca9-a6b8-39a4e06fda37"
      },
      "outputs": [],
      "source": [
        "import tensorflow as tf\n",
        "tf.reset_default_graph()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "dab415d2-8646-acff-091c-8358edede0ff"
      },
      "outputs": [],
      "source": [
        "convnet = input_data(shape=[None, IMG_SIZE, IMG_SIZE, 1], name='input')\n",
        "\n",
        "convnet = conv_2d(convnet, 32, 5, activation='relu')\n",
        "convnet = max_pool_2d(convnet, 5)\n",
        "\n",
        "convnet = conv_2d(convnet, 64, 5, activation='relu')\n",
        "convnet = max_pool_2d(convnet, 5)\n",
        "\n",
        "convnet = conv_2d(convnet, 32, 5, activation='relu')\n",
        "convnet = max_pool_2d(convnet, 5)\n",
        "\n",
        "convnet = conv_2d(convnet, 64, 5, activation='relu')\n",
        "convnet = max_pool_2d(convnet, 5)\n",
        "\n",
        "convnet = conv_2d(convnet, 32, 5, activation='relu')\n",
        "convnet = max_pool_2d(convnet, 5)\n",
        "\n",
        "convnet = conv_2d(convnet, 64, 5, activation='relu')\n",
        "convnet = max_pool_2d(convnet, 5)\n",
        "\n",
        "convnet = fully_connected(convnet, 1024, activation='relu')\n",
        "convnet = dropout(convnet, 0.8)\n",
        "\n",
        "convnet = fully_connected(convnet, 2, activation='softmax')\n",
        "convnet = regression(convnet, optimizer='adam', learning_rate=LR, loss='categorical_crossentropy', name='targets')\n",
        "\n",
        "model = tflearn.DNN(convnet, tensorboard_dir='log')\n",
        "\n",
        "\n",
        "\n",
        "if os.path.exists('{}.meta'.format(MODEL_NAME)):\n",
        "    model.load(MODEL_NAME)\n",
        "    print('model loaded!')\n",
        "\n",
        "train = train_data[:-500]\n",
        "test = train_data[-500:]\n",
        "\n",
        "X = np.array([i[0] for i in train]).reshape(-1,IMG_SIZE,IMG_SIZE,1)\n",
        "Y = [i[1] for i in train]\n",
        "\n",
        "test_x = np.array([i[0] for i in test]).reshape(-1,IMG_SIZE,IMG_SIZE,1)\n",
        "test_y = [i[1] for i in test]\n",
        "\n",
        "model.fit({'input': X}, {'targets': Y}, n_epoch=4, validation_set=({'input': test_x}, {'targets': test_y}), \n",
        "    snapshot_step=500, show_metric=True, run_id=MODEL_NAME)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "2b755a46-b76b-a212-4877-c7da75f23f65"
      },
      "outputs": [],
      "source": [
        "model.save(MODEL_NAME)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "e4d7a269-7924-0c22-192e-02662644a7dd"
      },
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\n",
        "\n",
        "# if you need to create the data:\n",
        "test_data = process_test_data()\n",
        "# if you already have some saved:\n",
        "#test_data = np.load('test_data.npy')\n",
        "\n",
        "fig=plt.figure()\n",
        "\n",
        "for num,data in enumerate(test_data[:12]):\n",
        "    # cat: [1,0]\n",
        "    # dog: [0,1]\n",
        "    \n",
        "    img_num = data[1]\n",
        "    img_data = data[0]\n",
        "    \n",
        "    y = fig.add_subplot(3,4,num+1)\n",
        "    orig = img_data\n",
        "    data = img_data.reshape(IMG_SIZE,IMG_SIZE,1)\n",
        "    #model_out = model.predict([data])[0]\n",
        "    model_out = model.predict([data])[0]  \n",
        "    \n",
        "    if np.argmax(model_out) == 1: str_label='Dog'\n",
        "    else: str_label='Cat'\n",
        "        \n",
        "    y.imshow(orig,cmap='gray')\n",
        "    plt.title(str_label)\n",
        "    y.axes.get_xaxis().set_visible(False)\n",
        "    y.axes.get_yaxis().set_visible(False)\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "b940c007-4ed1-e873-ae3c-7fda65813349"
      },
      "outputs": [],
      "source": [
        "with open('submission_file.csv','w') as f:\n",
        "    f.write('id,label\\n')\n",
        "            \n",
        "with open('submission_file.csv','a') as f:\n",
        "    for data in tqdm(test_data):\n",
        "        img_num = data[1]\n",
        "        img_data = data[0]\n",
        "        orig = img_data\n",
        "        data = img_data.reshape(IMG_SIZE,IMG_SIZE,1)\n",
        "        model_out = model.predict([data])[0]\n",
        "        f.write('{},{}\\n'.format(img_num,model_out[1]))"
      ]
    }
  ],
  "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.6.0"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}