{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "_cell_guid": "ab74bdce-9ca9-6fd3-b24f-185a67100dd5"
      },
      "source": [
        "using keras for remote sensing\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "ea88b6f7-a32f-6dd0-31da-9969162aa739"
      },
      "outputs": [],
      "source": [
        "from collections import defaultdict\n",
        "import csv\n",
        "import sys\n",
        "\n",
        "import cv2\n",
        "from shapely.geometry import MultiPolygon, Polygon\n",
        "import shapely.wkt\n",
        "import shapely.affinity\n",
        "import numpy as np\n",
        "import tifffile as tiff\n",
        "\n",
        "csv.field_size_limit(sys.maxsize);"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "0703109c-c1c1-9ceb-77f4-3ce3dc77c3cc"
      },
      "outputs": [],
      "source": [
        "IM_ID = '6120_2_2'\n",
        "POLY_TYPE = '1'  # buildings\n",
        "\n",
        "# Load grid size\n",
        "x_max = y_min = None\n",
        "for _im_id, _x, _y in csv.reader(open('../input/grid_sizes.csv')):\n",
        "    if _im_id == IM_ID:\n",
        "        x_max, y_min = float(_x), float(_y)\n",
        "        break\n",
        "\n",
        "# Load train poly with shapely\n",
        "train_polygons = dict()\n",
        "for _im_id, _poly_type, _poly in csv.reader(open('../input/train_wkt_v4.csv')):\n",
        "    if _im_id == IM_ID:\n",
        "        train_polygons[_poly_type]=shapely.wkt.loads(_poly)\n",
        "        break\n",
        "\n",
        "# Read image with tiff\n",
        "im_rgb = tiff.imread('../input/three_band/{}.tif'.format(IM_ID)).transpose([1, 2, 0])\n",
        "im_size = im_rgb.shape[:2]\n",
        "\n",
        "def get_scalers():\n",
        "    h, w = im_size  # they are flipped so that mask_for_polygons works correctly\n",
        "    w_ = w * (w / (w + 1))\n",
        "    h_ = h * (h / (h + 1))\n",
        "    return w_ / x_max, h_ / y_min\n",
        "\n",
        "def mask_for_polygons(polygons):\n",
        "    img_mask = np.zeros(im_size, np.uint8)\n",
        "    if not polygons:\n",
        "        return img_mask\n",
        "    int_coords = lambda x: np.array(x).round().astype(np.int32)\n",
        "    exteriors = [int_coords(poly.exterior.coords) for poly in polygons]\n",
        "    interiors = [int_coords(pi.coords) for poly in polygons\n",
        "                 for pi in poly.interiors]\n",
        "    cv2.fillPoly(img_mask, exteriors, 1)\n",
        "    cv2.fillPoly(img_mask, interiors, 0)\n",
        "    return img_mask\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "a3f92f64-834d-6528-2f89-d2626ef42615"
      },
      "outputs": [],
      "source": [
        "mask_map = list()\n",
        "for key in train_polygons.keys():\n",
        "    x_scaler, y_scaler = get_scalers()\n",
        "    train_polygons_scaled = shapely.affinity.scale(train_polygons[key], xfact=x_scaler, yfact=y_scaler, origin=(0, 0, 0))\n",
        "    mask_map.append( mask_for_polygons(train_polygons_scaled) )\n",
        "    \n",
        "mask = np.dstack(mask_map)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "9e4add19-6c27-ce5d-a324-77e296059413"
      },
      "outputs": [],
      "source": [
        "nrow, ncol = im_size\n",
        "x = np.arange(0, nrow, 16)\n",
        "y = np.arange(0, ncol, 16)\n",
        "\n",
        "patch_list = list()\n",
        "lbl_list = list()\n",
        "for xstart, xend in zip(x[:-1], x[1:]):\n",
        "    for ystart, yend in zip(y[:-1], y[1:]):\n",
        "        patch_list.append(im_rgb[xstart:xend, ystart:yend,:])\n",
        "        lbl_list.append(mask[xstart:xend, ystart:yend].mean())\n",
        "patches = np.array(patch_list)\n",
        "lbls = np.array(lbl_list)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "da9f4604-fa4c-6dfe-a117-6fcc823470b9"
      },
      "outputs": [],
      "source": [
        "from sklearn.cross_validation import train_test_split\n",
        "\n",
        "xtrain, xtest, ytrain, ytest = train_test_split(patches, lbls,\n",
        "                                  train_size=0.8,\n",
        "                                  test_size=0.2)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "b1463997-274e-eb86-7c8c-eb7f752a860d"
      },
      "outputs": [],
      "source": [
        "from keras.layers import Convolution2D, MaxPooling2D, Flatten, Dense\n",
        "from keras.layers.normalization import BatchNormalization\n",
        "from keras.layers import Activation\n",
        "from keras.models import Sequential\n",
        "\n",
        "model = Sequential()\n",
        "model.add(Convolution2D(64, 1, 1, border_mode='same', input_shape=(16, 16, 3), dim_ordering=\"tf\"))\n",
        "model.add(BatchNormalization(mode=0))\n",
        "model.add(Activation(\"relu\"))\n",
        "model.add(MaxPooling2D((2,2), dim_ordering=\"tf\"))\n",
        "model.add(Convolution2D(64, 1, 1, border_mode='same', dim_ordering=\"tf\"))\n",
        "model.add(BatchNormalization(mode=0))\n",
        "model.add(Activation(\"relu\"))\n",
        "model.add(Convolution2D(128, 3, 3, border_mode='same', dim_ordering=\"tf\"))\n",
        "model.add(BatchNormalization(mode=0))\n",
        "model.add(Activation(\"relu\"))\n",
        "model.add(MaxPooling2D((2,2), dim_ordering=\"tf\"))\n",
        "model.add(Flatten())\n",
        "model.add(Dense(1))\n",
        "\n",
        "model.compile(loss='mean_squared_error', optimizer='adam')"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "37f93611-0793-ad61-2079-8552a199e509"
      },
      "outputs": [],
      "source": [
        "%time model.fit(xtrain.values, ytrain.values, batch_size=32, nb_epoch=10, verbose=False)\n",
        "\n",
        "model.evaluate(xtrain.values, ytrain.values, batch_size=32, verbose=False), model.evaluate(X_test.values, Y_test.values, batch_size=32, verbose=False)"
      ]
    }
  ],
  "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
}