{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "16ec3802-79dc-82a8-df25-3577d2394e56"
      },
      "outputs": [],
      "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",
        "\n",
        "import numpy as np\n",
        "import pandas as pd\n",
        "from glob import glob\n",
        "import os\n",
        "import cv2\n",
        "\n",
        "from sklearn.model_selection import GridSearchCV, StratifiedKFold\n",
        "from sklearn.preprocessing import LabelEncoder\n",
        "from sklearn.metrics import log_loss\n",
        "from keras.wrappers.scikit_learn import KerasClassifier\n",
        "from keras import backend as K\n",
        "from keras.models import Sequential\n",
        "from keras.layers.core import Activation, Dense, Dropout, Flatten\n",
        "from keras.layers.convolutional import Conv2D, ZeroPadding2D, MaxPooling2D\n",
        "from keras import optimizers\n",
        "from multiprocessing import Pool, cpu_count\n",
        "import PIL\n",
        "from PIL import ImageFilter, ImageStat, Image, ImageDraw\n",
        "\n",
        "from multiprocessing import Pool, cpu_count\n",
        "\n",
        "\n",
        "from subprocess import check_output\n",
        "print(check_output([\"ls\", \"../input\"]).decode(\"utf8\"))\n",
        "# Any results you write to the current directory are saved as output."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "a8e3d601-c1e0-3493-7feb-6fe500b335ce"
      },
      "outputs": [],
      "source": [
        "def get_im_cv2(path):\n",
        "    img = cv2.imread(path)    \n",
        "    resized = cv2.resize(img, (img_width, img_height), cv2.INTER_LINEAR)\n",
        "    return [path, resized]\n",
        "\n",
        "def normalize_image_features(paths):\n",
        "    imf_d = {}\n",
        "    p = Pool(cpu_count())\n",
        "    ret = p.map(get_im_cv2, paths)\n",
        "    for i in range(len(ret)):\n",
        "        imf_d[ret[i][0]] = ret[i][1]\n",
        "    ret = []\n",
        "    fdata = [imf_d[f] for f in paths]\n",
        "    fdata = np.array(fdata, dtype=np.uint8)\n",
        "    fdata = fdata.transpose((0, 3, 1, 2))\n",
        "    fdata = fdata.astype('float32')\n",
        "    fdata = fdata / 255\n",
        "    return fdata\n",
        "    \n",
        "\n",
        "\n",
        "K.set_image_dim_ordering('tf')\n",
        "\n",
        "img_width, img_height = 32, 32 \n",
        "\n",
        "nb_train_samples = 1481\n",
        "\n",
        "epochs = 50\n",
        "\n",
        "batch_size = 1\n",
        "\n",
        "ImageFile.LOAD_TRUNCATED_IMAGES = True\n",
        "\n",
        "CAT_COLUMN = 'type'\n",
        "\n",
        "if K.image_data_format() == 'channels_first':\n",
        "    input_shape = (3, img_width, img_height)\n",
        "else:\n",
        "    input_shape = (img_width, img_height, 3)\n",
        "    \n",
        "    \n",
        "#trainpath1 = '../input/train/*/*'\n",
        "#trainpath2 = '../input/additional/*/*'\n",
        "\n",
        "trainpath = '../input/train/*/*'\n",
        "testpath = '../input/test/*'\n",
        "\n",
        "\n",
        "\n",
        "#train1 = pd.DataFrame([{'path': c_path, \n",
        "#                          'image_name': os.path.basename(c_path), \n",
        "#                          CAT_COLUMN: os.path.basename(os.path.dirname(c_path))} \n",
        "#                            for c_path in glob(trainpath1)])\n",
        "\n",
        "#train2 = pd.DataFrame([{'path': c_path, \n",
        "#                          'image_name': os.path.basename(c_path), \n",
        "#                          CAT_COLUMN: os.path.basename(os.path.dirname(c_path))} \n",
        "#                            for c_path in glob(trainpath2)])\n",
        "\n",
        "#train = train1.append(train2, ignore_index=True)\n",
        "#train = train1\n",
        "\n",
        "#del train1, train2\n",
        "\n",
        "train = pd.DataFrame([{'path': c_path, \n",
        "                       'image_name': os.path.basename(c_path), \n",
        "                       CAT_COLUMN: os.path.basename(os.path.dirname(c_path))} \n",
        "                            for c_path in glob(trainpath)])\n",
        "\n",
        "print(len(train))\n",
        "\n",
        "test = pd.DataFrame([dict(path = c_path, \n",
        "                          image_name = os.path.basename(c_path)) \n",
        "                             for c_path in glob(testpath)])\n",
        "\n",
        "print(len(test))\n",
        "\n",
        "train_data = normalize_image_features(train['path'])\n",
        "\n",
        "le = LabelEncoder()\n",
        "train_target = le.fit_transform(train['type'].values)\n",
        "\n",
        "test_data = normalize_image_features(test['path'])\n",
        "\n",
        "test_id = test.image_name.values"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "b186c0f6-4f9b-03f7-16fc-dac608346397"
      },
      "outputs": [],
      "source": [
        "model = Sequential()\n",
        "model.add(ZeroPadding2D((1, 1), input_shape=input_shape))\n",
        "model.add(Conv2D(32, (3, 3)))\n",
        "model.add(Activation('relu'))\n",
        "model.add(Dropout(0.2))\n",
        "model.add(Conv2D(32, (3, 3)))\n",
        "model.add(Activation('relu'))\n",
        "model.add(MaxPooling2D((2, 2), strides=(2, 2)))\n",
        " \n",
        "model.add(Conv2D(64, (3, 3)))\n",
        "model.add(Activation('relu'))\n",
        "model.add(Dropout(0.2))\n",
        "model.add(MaxPooling2D((2, 2), strides=(2, 2))) \n",
        "\n",
        "model.add(Conv2D(128, (3, 3)))\n",
        "model.add(Activation('relu'))\n",
        "model.add(Dropout(0.2))\n",
        "model.add(MaxPooling2D((2, 2), strides=(2, 2))) \n",
        "\n",
        "\n",
        "model.add(Flatten())\n",
        "model.add(Dense(128, activation='relu'))\n",
        "model.add(Dropout(0.2))\n",
        "model.add(Dense(64, activation='relu'))\n",
        "model.add(Dropout(0.2))\n",
        "model.add(Dense(3, activation='softmax'))\n",
        "\n",
        "model.layers.pop()\n",
        "model.add(Dense(3, activation='softmax'))\n",
        "\n",
        "\n",
        "\n",
        "lrate = 0.001\n",
        "decay = lrate/epochs\n",
        "\n",
        "\n",
        "opt = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)\n",
        "\n",
        "\n",
        "model.compile(loss='sparse_categorical_crossentropy',\n",
        "              optimizer=opt,\n",
        "              metrics=['accuracy'])\n",
        "\n",
        "\n",
        "train_datagen = ImageDataGenerator(zca_whitening = True)\n",
        "\n",
        "train_datagen.fit(train_data)\n",
        "\n",
        "train_generator = train_datagen.flow(\n",
        "        x = train_data,\n",
        "        y = train_target,        \n",
        "        batch_size=batch_size,\n",
        "        #class_mode='sparse',\n",
        "        shuffle = True)\n",
        "\n",
        "model.fit_generator(\n",
        "    train_generator,\n",
        "    steps_per_epoch=nb_train_samples // batch_size,\n",
        "    epochs=epochs)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "6427d45a-2f6a-f60b-5839-196e423f17b4"
      },
      "outputs": [],
      "source": [
        "test_datagen = ImageDataGenerator(zca_whitening = True)\n",
        "\n",
        "test_generator = test_datagen.flow(\n",
        "        x = test_data,              \n",
        "        batch_size=batch_size,\n",
        "        class_mode='sparse',\n",
        "        shuffle = True)\n",
        "\n",
        "predict = model.predict_generator(generator = test_generator, \n",
        "                                  steps = 512)\n",
        "\n",
        "prediction = pd.DataFrame(test_generator.filenames, columns=['image_name'])\n",
        "prediction['image_name'] = prediction['image_name'].map(lambda x: x.lstrip('test\\\\'))\n",
        "prediction = pd.concat([prediction, pd.DataFrame(predict, columns=['Type_1', 'Type_2', 'Type_3'])], axis=1).to_csv('../output/MobileODTPredict_v5.csv', index=False)\n"
      ]
    }
  ],
  "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
}