{"cells":[{"metadata":{"_cell_guid":"7a98e214-fcaa-373a-c677-bca8d582aec4","_uuid":"83c6932fa69796519ec77a8a0d05f0dd5de6be52"},"cell_type":"markdown","source":""},{"metadata":{"_cell_guid":"b9c4cf08-e964-d988-0ff6-0c82b55f22cc","_uuid":"9d4eec90198d82834f3d88840bcf50fb188b6061","trusted":false},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"46e9a366-75fb-1cc8-ee28-45e88abbfad1","_uuid":"e709d59077046fba7aa6f7abd6e0ccdf76ccfa1c","trusted":false},"cell_type":"code","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)\nimport keras \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/train\"]).decode(\"utf8\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"2f51f69f-6834-ed8e-a323-7d7258c81089","_uuid":"af785c3c79fb7bf1570ae9982acfbebb874be999","trusted":false},"cell_type":"code","source":"import theano\ntheano.config.device = 'gpu'\ntheano.config.floatX = 'float32'","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"74589918-b954-5f2f-eeb6-cebab6eef28a","_uuid":"08af3e32d3b638ddb2d2eec8fb6ce28d22e7de6f","trusted":false},"cell_type":"code","source":"fimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nfirst = mpimg.imread('../input/train/c0/img_100026.jpg')\nplt.imshow(first)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"68f9b755-630e-6d89-d94f-35eeae72a3c7","_uuid":"b0b1c6514da79798bfea46a092e72a3f2eb610ab","trusted":true},"cell_type":"code","source":"from __future__ import division, print_function\n\nimport os, json\nfrom glob import glob\nimport numpy as np\nfrom scipy import misc, ndimage\nfrom scipy.ndimage.interpolation import zoom\n\nfrom keras import backend as K\nfrom keras.layers.normalization import BatchNormalization\nfrom keras.utils.data_utils import get_file\nfrom keras.models import Sequential\nfrom keras.layers.core import Flatten, Dense, Dropout, Lambda\nfrom keras.layers.convolutional import Convolution2D, MaxPooling2D, ZeroPadding2D\nfrom keras.layers.pooling import GlobalAveragePooling2D\nfrom keras.optimizers import SGD, Adam\nfrom keras.preprocessing import image\n\n# In case we are going to use the TensorFlow backend we need to explicitly set the Theano image ordering\nfrom keras import backend as K\nK.set_image_dim_ordering('th')\n\nvgg_mean = np.array([123.68, 116.779, 103.939], dtype=np.float32).reshape((3,1,1))\ndef vgg_preprocess(x):\n    x = x - vgg_mean\n    return x[:, ::-1] # reverse axis rgb->bgr\n\n\nclass Vgg16BN():\n    \"\"\"The VGG 16 Imagenet model with Batch Normalization for the Dense Layers\"\"\"\n\n\n    def __init__(self, size=(224,224), include_top=True):\n        self.FILE_PATH = 'http://files.fast.ai/models/'\n        self.create(size, include_top)\n        self.get_classes()\n\n\n    def get_classes(self):\n        fname = 'imagenet_class_index.json'\n        fpath = get_file(fname, self.FILE_PATH+fname, cache_subdir='models')\n        with open(fpath) as f:\n            class_dict = json.load(f)\n        self.classes = [class_dict[str(i)][1] for i in range(len(class_dict))]\n\n    def predict(self, imgs, details=False):\n        all_preds = self.model.predict(imgs)\n        idxs = np.argmax(all_preds, axis=1)\n        preds = [all_preds[i, idxs[i]] for i in range(len(idxs))]\n        classes = [self.classes[idx] for idx in idxs]\n        return np.array(preds), idxs, classes\n\n\n    def ConvBlock(self, layers, filters):\n        model = self.model\n        for i in range(layers):\n            model.add(ZeroPadding2D((1, 1)))\n            model.add(Convolution2D(filters, 3, 3, activation='relu'))\n        model.add(MaxPooling2D((2, 2), strides=(2, 2)))\n\n\n    def FCBlock(self):\n        model = self.model\n        model.add(Dense(4096, activation='relu'))\n        model.add(BatchNormalization())\n        model.add(Dropout(0.5))\n\n\n    def create(self, size, include_top):\n        if size != (224,224):\n            include_top=False\n\n        model = self.model = Sequential()\n        model.add(Lambda(vgg_preprocess, input_shape=(3,)+size, output_shape=(3,)+size))\n\n        self.ConvBlock(2, 64)\n        self.ConvBlock(2, 128)\n        self.ConvBlock(3, 256)\n        self.ConvBlock(3, 512)\n        self.ConvBlock(3, 512)\n\n        if not include_top:\n            fname = 'vgg16_bn_conv.h5'\n            model.load_weights(get_file(fname, self.FILE_PATH+fname, cache_subdir='models'))\n            return\n\n        model.add(Flatten())\n        self.FCBlock()\n        self.FCBlock()\n        model.add(Dense(1000, activation='softmax'))\n\n        fname = 'vgg16_bn.h5'\n        model.load_weights(get_file(fname, self.FILE_PATH+fname, cache_subdir='models'))\n\n\n    def get_batches(self, path, gen=image.ImageDataGenerator(), shuffle=True, batch_size=8, class_mode='categorical'):\n        return gen.flow_from_directory(path, target_size=(224,224),\n                class_mode=class_mode, shuffle=shuffle, batch_size=batch_size)\n\n\n    def ft(self, num):\n        model = self.model\n        model.pop()\n        for layer in model.layers: layer.trainable=False\n        model.add(Dense(num, activation='softmax'))\n        self.compile()\n\n    def finetune(self, batches):\n        self.ft(batches.num_classes)\n\n        classes = list(iter(batches.class_indices))\n        for c in batches.class_indices:\n            classes[batches.class_indices[c]] = c\n        self.classes = classes\n\n\n    def compile(self, lr=0.001):\n        self.model.compile(optimizer=Adam(lr=lr),\n                loss='categorical_crossentropy', metrics=['accuracy'])\n\n\n    def fit_data(self, trn, labels,  val, val_labels,  nb_epoch=1, batch_size=64):\n        self.model.fit(trn, labels, nb_epoch=nb_epoch,\n                validation_data=(val, val_labels), batch_size=batch_size)\n\n\n    def fit(self, batches, val_batches, nb_epoch=1):\n        self.model.fit_generator(batches, samples_per_epoch=batches.samples, nb_epoch=nb_epoch,\n                validation_data=val_batches, nb_val_samples=val_batches.samples)\n\n\n    def test(self, path, batch_size=8):\n        test_batches = self.get_batches(path, shuffle=False, batch_size=batch_size, class_mode=None)\n        return test_batches, self.model.predict_generator(test_batches, test_batches.samples)\n","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"aef3a165-8052-b874-b809-c7669b115574","_uuid":"b76028b9f721fb45ca7d5924375014306bbf11e6","trusted":true},"cell_type":"code","source":"vgg = Vgg16BN()\n# Grab a few images at a time for training and validation.\n# NB: They must be in subdirectories named based on their category\npath = '../input/'\nbatch_size=1\nbatches = vgg.get_batches(path+'train', batch_size=batch_size)\nval_batches = vgg.get_batches(path+'test', batch_size=batch_size*2)\nvgg.finetune(batches)\nvgg.fit(batches, val_batches, nb_epoch=1)","execution_count":null,"outputs":[]}],"metadata":{"_change_revision":0,"_is_fork":false,"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}