{
  "metadata": {
    "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,
  "cells": [
    {
      "metadata": {
        "_cell_guid": "04d7997d-22e0-fd0f-4a7a-b54cce5acf3a",
        "_active": false,
        "collapsed": false
      },
      "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\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nfrom subprocess import check_output\nprint(check_output([\"ls\", \"../input\"]).decode(\"utf8\"))\n# print(check_output([\"ls\", \"../input/train\"]).decode(\"utf8\"))\n\n# Any results you write to the current directory are saved as output.",
      "execution_count": null,
      "cell_type": "code",
      "outputs": [],
      "execution_state": "idle"
    },
    {
      "metadata": {
        "_cell_guid": "303cc0c4-0535-92a5-770d-ecf72c01e2fb",
        "_active": false,
        "collapsed": false
      },
      "source": "Now we want to split the data into train, validation, and sample folders:",
      "execution_count": null,
      "cell_type": "markdown",
      "outputs": [],
      "execution_state": "idle"
    },
    {
      "metadata": {
        "_cell_guid": "c37ea7e4-ff89-8bf7-98e8-2e64333124c8",
        "_active": false,
        "collapsed": false
      },
      "source": "import os\nimport shutil\nimport random\n\nnew_dir = \"~/hank/\"\n\ntry:\n    shutil.rmtree(new_dir)\nexcept FileNotFoundError:\n    None\n\ntrain_files = os.listdir(\"../input/train\")\ncat_files = [file for file in train_files if \"cat\" in file]\ndog_files = [file for file in train_files if \"dog\" in file]\n\nrandom.shuffle(dog_files)\nrandom.shuffle(cat_files)\n\ntrain_split = 0.8\ntrain_idx = round(len(dog_files) * train_split)\n\ndog_train = dog_files[:train_idx]\ndog_valid = dog_files[train_idx:]\n\ncat_train = cat_files[:train_idx]\ncat_valid = cat_files[train_idx:]\n\nsample_size = 10\ndog_sample = dog_files[:sample_size]\ncat_sample = cat_files[:sample_size]",
      "execution_count": null,
      "cell_type": "code",
      "outputs": [],
      "execution_state": "idle"
    },
    {
      "metadata": {
        "_cell_guid": "cc8a47ea-c2c2-7255-0241-d19f229d640f",
        "_active": false,
        "collapsed": false
      },
      "source": "total, used, free = shutil.disk_usage(\"/\")\nprint (\"{} free mb\".format(free / 1000000))",
      "execution_count": null,
      "cell_type": "code",
      "outputs": [],
      "execution_state": "idle"
    },
    {
      "metadata": {
        "_cell_guid": "cda1e5be-3727-6497-b8ba-62e4a5f8cd40",
        "_active": false,
        "collapsed": false
      },
      "source": "import warnings\nimport numpy as np\n\nfrom keras.models import Model\nfrom keras.layers import Dense, Input, BatchNormalization, Activation, merge\nfrom keras.layers import Conv2D, SeparableConv2D, MaxPooling2D, GlobalAveragePooling2D\nfrom keras.preprocessing import image\nfrom keras.utils.data_utils import get_file\nfrom keras import backend as K",
      "execution_count": null,
      "cell_type": "code",
      "outputs": [],
      "execution_state": "idle"
    },
    {
      "metadata": {
        "_cell_guid": "916def42-ac6a-d87c-aabb-405889b73ad6",
        "_active": false,
        "collapsed": false
      },
      "source": "# dog_valid_imgs = [image.load_img(\"../input/train/\"+file, target_size=(299, 299)) for file in dog_valid]\n# cat_valid_imgs = [image.load_img(\"../input/train/\"+file, target_size=(299, 299)) for file in cat_valid]\n# dog_train_imgs = [image.load_img(\"../input/train/\"+file, target_size=(299, 299)) for file in dog_train]\n# cat_train_imgs = [image.load_img(\"../input/train/\"+file, target_size=(299, 299)) for file in cat_train]\n# dog_sample_imgs = [image.load_img(\"../input/train/\"+file, target_size=(299, 299)) for file in dog_sample]\n# cat_sample_imgs = [image.load_img(\"../input/train/\"+file, target_size=(299, 299)) for file in cat_sample]",
      "execution_count": null,
      "cell_type": "code",
      "outputs": [],
      "execution_state": "idle"
    },
    {
      "metadata": {
        "_cell_guid": "059eba76-b5b0-e63f-8d86-d4fd196d8fb5",
        "_active": false,
        "collapsed": false
      },
      "source": "# TF_WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.4/xception_weights_tf_dim_ordering_tf_kernels.h5'\n# TF_WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.4/xception_weights_tf_dim_ordering_tf_kernels.h5'\nTF_WEIGHTS_PATH = \"https://s3.amazonaws.com/deep-learning-weights/xception_weights_tf_dim_ordering_tf_kernels.h5\"\nTF_WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.4/xception_weights_tf_dim_ordering_tf_kernels_notop.h5'",
      "execution_count": null,
      "cell_type": "code",
      "outputs": [],
      "execution_state": "idle"
    },
    {
      "metadata": {
        "_cell_guid": "2cc15c28-139f-ab09-e441-ccac894dba7f",
        "_active": false,
        "collapsed": false
      },
      "source": "def Xception(include_top=True, weights='imagenet',\n             input_tensor=None):\n    '''Instantiate the Xception architecture,\n    optionally loading weights pre-trained\n    on ImageNet. This model is available for TensorFlow only,\n    and can only be used with inputs following the TensorFlow\n    dimension ordering `(width, height, channels)`.\n    You should set `image_dim_ordering=\"tf\"` in your Keras config\n    located at ~/.keras/keras.json.\n    Note that the default input image size for this model is 299x299.\n    # Arguments\n        include_top: whether to include the fully-connected\n            layer at the top of the network.\n        weights: one of `None` (random initialization)\n            or \"imagenet\" (pre-training on ImageNet).\n        input_tensor: optional Keras tensor (i.e. output of `layers.Input()`)\n            to use as image input for the model.\n    # Returns\n        A Keras model instance.\n    '''\n    if weights not in {'imagenet', None}:\n        raise ValueError('The `weights` argument should be either '\n                         '`None` (random initialization) or `imagenet` '\n                         '(pre-training on ImageNet).')\n    if K.backend() != 'tensorflow':\n        raise Exception('The Xception model is only available with '\n                        'the TensorFlow backend.')\n    if K.image_dim_ordering() != 'tf':\n        warnings.warn('The Xception model is only available for the '\n                      'input dimension ordering \"tf\" '\n                      '(width, height, channels). '\n                      'However your settings specify the default '\n                      'dimension ordering \"th\" (channels, width, height). '\n                      'You should set `image_dim_ordering=\"tf\"` in your Keras '\n                      'config located at ~/.keras/keras.json. '\n                      'The model being returned right now will expect inputs '\n                      'to follow the \"tf\" dimension ordering.')\n        K.set_image_dim_ordering('tf')\n        old_dim_ordering = 'th'\n    else:\n        old_dim_ordering = None\n\n    # Determine proper input shape\n    if include_top:\n        input_shape = (299, 299, 3)\n    else:\n        input_shape = (None, None, 3)\n\n    if input_tensor is None:\n        img_input = Input(shape=input_shape)\n    else:\n        if not K.is_keras_tensor(input_tensor):\n            img_input = Input(tensor=input_tensor, shape=input_shape)\n        else:\n            img_input = input_tensor\n\n    x = Conv2D(32, 3, 3, subsample=(2, 2), bias=False, name='block1_conv1')(img_input)\n    x = BatchNormalization(name='block1_conv1_bn')(x)\n    x = Activation('relu', name='block1_conv1_act')(x)\n    x = Conv2D(64, 3, 3, bias=False, name='block1_conv2')(x)\n    x = BatchNormalization(name='block1_conv2_bn')(x)\n    x = Activation('relu', name='block1_conv2_act')(x)\n\n    residual = Conv2D(128, 1, 1, subsample=(2, 2),\n                      border_mode='same', bias=False)(x)\n    residual = BatchNormalization()(residual)\n\n    x = SeparableConv2D(128, 3, 3, border_mode='same', bias=False, name='block2_sepconv1')(x)\n    x = BatchNormalization(name='block2_sepconv1_bn')(x)\n    x = Activation('relu', name='block2_sepconv2_act')(x)\n    x = SeparableConv2D(128, 3, 3, border_mode='same', bias=False, name='block2_sepconv2')(x)\n    x = BatchNormalization(name='block2_sepconv2_bn')(x)\n\n    x = MaxPooling2D((3, 3), strides=(2, 2), border_mode='same', name='block2_pool')(x)\n    x = merge([x, residual], mode='sum')\n\n    residual = Conv2D(256, 1, 1, subsample=(2, 2),\n                      border_mode='same', bias=False)(x)\n    residual = BatchNormalization()(residual)\n\n    x = Activation('relu', name='block3_sepconv1_act')(x)\n    x = SeparableConv2D(256, 3, 3, border_mode='same', bias=False, name='block3_sepconv1')(x)\n    x = BatchNormalization(name='block3_sepconv1_bn')(x)\n    x = Activation('relu', name='block3_sepconv2_act')(x)\n    x = SeparableConv2D(256, 3, 3, border_mode='same', bias=False, name='block3_sepconv2')(x)\n    x = BatchNormalization(name='block3_sepconv2_bn')(x)\n\n    x = MaxPooling2D((3, 3), strides=(2, 2), border_mode='same', name='block3_pool')(x)\n    x = merge([x, residual], mode='sum')\n\n    residual = Conv2D(728, 1, 1, subsample=(2, 2),\n                      border_mode='same', bias=False)(x)\n    residual = BatchNormalization()(residual)\n\n    x = Activation('relu', name='block4_sepconv1_act')(x)\n    x = SeparableConv2D(728, 3, 3, border_mode='same', bias=False, name='block4_sepconv1')(x)\n    x = BatchNormalization(name='block4_sepconv1_bn')(x)\n    x = Activation('relu', name='block4_sepconv2_act')(x)\n    x = SeparableConv2D(728, 3, 3, border_mode='same', bias=False, name='block4_sepconv2')(x)\n    x = BatchNormalization(name='block4_sepconv2_bn')(x)\n\n    x = MaxPooling2D((3, 3), strides=(2, 2), border_mode='same', name='block4_pool')(x)\n    x = merge([x, residual], mode='sum')\n\n    for i in range(8):\n        residual = x\n        prefix = 'block' + str(i + 5)\n\n        x = Activation('relu', name=prefix + '_sepconv1_act')(x)\n        x = SeparableConv2D(728, 3, 3, border_mode='same', bias=False, name=prefix + '_sepconv1')(x)\n        x = BatchNormalization(name=prefix + '_sepconv1_bn')(x)\n        x = Activation('relu', name=prefix + '_sepconv2_act')(x)\n        x = SeparableConv2D(728, 3, 3, border_mode='same', bias=False, name=prefix + '_sepconv2')(x)\n        x = BatchNormalization(name=prefix + '_sepconv2_bn')(x)\n        x = Activation('relu', name=prefix + '_sepconv3_act')(x)\n        x = SeparableConv2D(728, 3, 3, border_mode='same', bias=False, name=prefix + '_sepconv3')(x)\n        x = BatchNormalization(name=prefix + '_sepconv3_bn')(x)\n\n        x = merge([x, residual], mode='sum')\n\n    residual = Conv2D(1024, 1, 1, subsample=(2, 2),\n                      border_mode='same', bias=False)(x)\n    residual = BatchNormalization()(residual)\n\n    x = Activation('relu', name='block13_sepconv1_act')(x)\n    x = SeparableConv2D(728, 3, 3, border_mode='same', bias=False, name='block13_sepconv1')(x)\n    x = BatchNormalization(name='block13_sepconv1_bn')(x)\n    x = Activation('relu', name='block13_sepconv2_act')(x)\n    x = SeparableConv2D(1024, 3, 3, border_mode='same', bias=False, name='block13_sepconv2')(x)\n    x = BatchNormalization(name='block13_sepconv2_bn')(x)\n\n    x = MaxPooling2D((3, 3), strides=(2, 2), border_mode='same', name='block13_pool')(x)\n    x = merge([x, residual], mode='sum')\n\n    x = SeparableConv2D(1536, 3, 3, border_mode='same', bias=False, name='block14_sepconv1')(x)\n    x = BatchNormalization(name='block14_sepconv1_bn')(x)\n    x = Activation('relu', name='block14_sepconv1_act')(x)\n\n    x = SeparableConv2D(2048, 3, 3, border_mode='same', bias=False, name='block14_sepconv2')(x)\n    x = BatchNormalization(name='block14_sepconv2_bn')(x)\n    x = Activation('relu', name='block14_sepconv2_act')(x)\n\n    if include_top:\n        x = GlobalAveragePooling2D(name='avg_pool')(x)\n        x = Dense(1000, activation='softmax', name='predictions')(x)\n\n    # Create model\n    model = Model(img_input, x)\n\n    # load weights\n    if weights == 'imagenet':\n        if include_top:\n            weights_path = get_file('xception_weights_tf_dim_ordering_tf_kernels.h5',\n                                    TF_WEIGHTS_PATH,\n                                    cache_subdir='models')\n        else:\n            weights_path = get_file('xception_weights_tf_dim_ordering_tf_kernels_notop.h5',\n                                    TF_WEIGHTS_PATH_NO_TOP,\n                                    cache_subdir='models')\n        model.load_weights(weights_path)\n\n    if old_dim_ordering:\n        K.set_image_dim_ordering(old_dim_ordering)\n    return model",
      "execution_count": null,
      "cell_type": "code",
      "outputs": [],
      "execution_state": "idle"
    },
    {
      "metadata": {
        "_cell_guid": "c3f61b62-d9bc-0584-6302-5545f4b606b6",
        "_active": false,
        "collapsed": false
      },
      "source": "def preprocess_input(x):\n    x /= 255.\n    x -= 0.5\n    x *= 2.\n    return x",
      "execution_count": null,
      "cell_type": "code",
      "outputs": [],
      "execution_state": "idle"
    },
    {
      "metadata": {
        "_cell_guid": "71930274-fe16-04d9-dd97-3b0ba4f3d7c1",
        "_active": false,
        "collapsed": false
      },
      "source": "generator = image.ImageDataGenerator()",
      "execution_count": null,
      "cell_type": "code",
      "outputs": [],
      "execution_state": "idle"
    },
    {
      "metadata": {
        "_cell_guid": "4a2d0002-844d-506f-efe5-c01c1ff50304",
        "_active": false,
        "collapsed": false
      },
      "source": "def get_imgs(arr):\n    imgs = [image.load_img(\"../input/train/\"+file, target_size=(299, 299)) for file in arr]\n    imgs = [preprocess_input(np.expand_dims(image.img_to_array(img), axis=0)) for img in imgs]\n    return imgs",
      "execution_count": null,
      "cell_type": "code",
      "outputs": [],
      "execution_state": "idle"
    },
    {
      "metadata": {
        "_cell_guid": "0abd0101-71fc-8712-18b5-9c02c1f97462",
        "_active": false,
        "collapsed": false
      },
      "source": "dog_sample_imgs = get_imgs(dog_sample)\ncat_sample_imgs = get_imgs(cat_sample)",
      "execution_count": null,
      "cell_type": "code",
      "outputs": [],
      "execution_state": "idle"
    },
    {
      "metadata": {
        "_cell_guid": "c3e8bb38-99a4-6ccf-96f0-db429389c661",
        "_active": false,
        "collapsed": false
      },
      "source": "X_sample = dog_sample_imgs + cat_sample_imgs",
      "execution_count": null,
      "cell_type": "code",
      "outputs": [],
      "execution_state": "idle"
    },
    {
      "metadata": {
        "_cell_guid": "d7c2f0ed-7c4e-ba89-0eb3-9c229b66b5e1",
        "_active": false,
        "collapsed": false
      },
      "source": "Y_sample = [0] * len(dog_sample_imgs)\nY_sample += [1] * len(cat_sample_imgs)",
      "execution_count": null,
      "cell_type": "code",
      "outputs": [],
      "execution_state": "idle"
    },
    {
      "metadata": {
        "_cell_guid": "0395ce09-f52c-17a5-a2c4-282c7bbe7a58",
        "_active": false,
        "collapsed": false
      },
      "source": "model = Xception()",
      "execution_count": null,
      "cell_type": "code",
      "outputs": [],
      "execution_state": "idle"
    },
    {
      "metadata": {
        "_cell_guid": "ead5f8f5-b11b-392e-b893-c7247e537de2",
        "_active": false,
        "collapsed": false
      },
      "source": null,
      "execution_count": null,
      "cell_type": "code",
      "outputs": [],
      "execution_state": "idle"
    }
  ]
}