diff --git a/notebooks/neural_networks/inception_transferlearning.ipynb b/notebooks/neural_networks/inception_transferlearning.ipynb
new file mode 100644
index 0000000..0c94183
--- /dev/null
+++ b/notebooks/neural_networks/inception_transferlearning.ipynb
@@ -0,0 +1,1107 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 77,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "
\n",
+ "
SparkContext
\n",
+ "\n",
+ "
Spark UI
\n",
+ "\n",
+ "
\n",
+ " - Version
\n",
+ " v2.2.0 \n",
+ " - Master
\n",
+ " local[4] \n",
+ " - AppName
\n",
+ " PySparkShell \n",
+ "
\n",
+ "
\n",
+ " "
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 77,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "sc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 78,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "from PIL import Image\n",
+ "from os import listdir\n",
+ "from os.path import join, basename\n",
+ "import struct\n",
+ "import pickle\n",
+ "import json\n",
+ "import os\n",
+ "from scipy import misc\n",
+ "import datetime as dt\n",
+ "# import matplotlib.pyplot as plt\n",
+ "# %matplotlib inline"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 79,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# %pylab inline\n",
+ "from bigdl.nn.layer import *\n",
+ "from bigdl.nn.criterion import *\n",
+ "from bigdl.optim.optimizer import *\n",
+ "from bigdl.util.common import *\n",
+ "from bigdl.dataset.transformer import *\n",
+ "from bigdl.dataset import mnist\n",
+ "from transformer import *"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 80,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\n",
+ "def scala_T(input_T):\n",
+ " \"\"\"\n",
+ " Helper function for building Inception layers. Transforms a list of numbers to a dictionary with ascending keys \n",
+ " and 0 appended to the front. Ignores dictionary inputs. \n",
+ " \n",
+ " :param input_T: either list or dict\n",
+ " :return: dictionary with ascending keys and 0 appended to front {0: 0, 1: realdata_1, 2: realdata_2, ...}\n",
+ " \"\"\" \n",
+ " if type(input_T) is list:\n",
+ " # insert 0 into first index spot, such that the real data starts from index 1\n",
+ " temp = [0]\n",
+ " temp.extend(input_T)\n",
+ " return dict(enumerate(temp))\n",
+ " # if dictionary, return it back\n",
+ " return input_T"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 81,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def Inception_Layer_v1(input_size, config, name_prefix=\"\"):\n",
+ " \"\"\"\n",
+ " Builds the inception-v1 submodule, a local network, that is stacked in the entire architecture when building\n",
+ " the full model. \n",
+ " \n",
+ " :param input_size: dimensions of input coming into the local network\n",
+ " :param config: ?\n",
+ " :param name_prefix: string naming the layers of the particular local network\n",
+ " :return: concat container object with all of the Sequential layers' output concatenated depthwise\n",
+ " \"\"\" \n",
+ " \n",
+ " '''\n",
+ " Concat is a container who concatenates the output of it's submodules along the provided dimension: all submodules \n",
+ " take the same inputs, and their output is concatenated.\n",
+ " '''\n",
+ " concat = Concat(2)\n",
+ " \n",
+ " \"\"\"\n",
+ " In the above code, we first create a container Sequential. Then add the layers into the container one by one. The \n",
+ " order of the layers in the model is same with the insertion order. \n",
+ " \n",
+ " \"\"\"\n",
+ " conv1 = Sequential()\n",
+ " \n",
+ " #Adding layers to the conv1 model we just created\n",
+ " \n",
+ " #SpatialConvolution is a module that applies a 2D convolution over an input image.\n",
+ " conv1.add(SpatialConvolution(input_size, config[1][1], 1, 1, 1, 1).set_name(name_prefix + \"1x1\"))\n",
+ " conv1.add(ReLU(True).set_name(name_prefix + \"relu_1x1\"))\n",
+ " concat.add(conv1)\n",
+ " \n",
+ " conv3 = Sequential()\n",
+ " conv3.add(SpatialConvolution(input_size, config[2][1], 1, 1, 1, 1).set_name(name_prefix + \"3x3_reduce\"))\n",
+ " conv3.add(ReLU(True).set_name(name_prefix + \"relu_3x3_reduce\"))\n",
+ " conv3.add(SpatialConvolution(config[2][1], config[2][2], 3, 3, 1, 1, 1, 1).set_name(name_prefix + \"3x3\"))\n",
+ " conv3.add(ReLU(True).set_name(name_prefix + \"relu_3x3\"))\n",
+ " concat.add(conv3)\n",
+ " \n",
+ " \n",
+ " conv5 = Sequential()\n",
+ " conv5.add(SpatialConvolution(input_size,config[3][1], 1, 1, 1, 1).set_name(name_prefix + \"5x5_reduce\"))\n",
+ " conv5.add(ReLU(True).set_name(name_prefix + \"relu_5x5_reduce\"))\n",
+ " conv5.add(SpatialConvolution(config[3][1], config[3][2], 5, 5, 1, 1, 2, 2).set_name(name_prefix + \"5x5\"))\n",
+ " conv5.add(ReLU(True).set_name(name_prefix + \"relu_5x5\"))\n",
+ " concat.add(conv5)\n",
+ " \n",
+ " \n",
+ " pool = Sequential()\n",
+ " pool.add(SpatialMaxPooling(3, 3, 1, 1, 1, 1, to_ceil=True).set_name(name_prefix + \"pool\"))\n",
+ " pool.add(SpatialConvolution(input_size, config[4][1], 1, 1, 1, 1).set_name(name_prefix + \"pool_proj\"))\n",
+ " pool.add(ReLU(True).set_name(name_prefix + \"relu_pool_proj\"))\n",
+ " concat.add(pool).set_name(name_prefix + \"output\")\n",
+ " return concat"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 82,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def Inception_v1_Bottleneck():\n",
+ " model = Sequential()\n",
+ " model.add(SpatialConvolution(3, 64, 7, 7, 2, 2, 3, 3, 1, False).set_name(\"conv1/7x7_s2\"))\n",
+ " model.add(ReLU(True).set_name(\"conv1/relu_7x7\"))\n",
+ " model.add(SpatialMaxPooling(3, 3, 2, 2, to_ceil=True).set_name(\"pool1/3x3_s2\"))\n",
+ " model.add(SpatialCrossMapLRN(5, 0.0001, 0.75).set_name(\"pool1/norm1\"))\n",
+ " model.add(SpatialConvolution(64, 64, 1, 1, 1, 1).set_name(\"conv2/3x3_reduce\"))\n",
+ " model.add(ReLU(True).set_name(\"conv2/relu_3x3_reduce\"))\n",
+ " model.add(SpatialConvolution(64, 192, 3, 3, 1, 1, 1, 1).set_name(\"conv2/3x3\"))\n",
+ " model.add(ReLU(True).set_name(\"conv2/relu_3x3\"))\n",
+ " model.add(SpatialCrossMapLRN(5, 0.0001, 0.75).set_name(\"conv2/norm2\"))\n",
+ " model.add(SpatialMaxPooling(3, 3, 2, 2, to_ceil=True).set_name(\"pool2/3x3_s2\"))\n",
+ " model.add(Inception_Layer_v1(192, scala_T([scala_T([64]), scala_T(\n",
+ " [96, 128]), scala_T([16, 32]), scala_T([32])]), \"inception_3a/\"))\n",
+ " model.add(Inception_Layer_v1(256, scala_T([scala_T([128]), scala_T(\n",
+ " [128, 192]), scala_T([32, 96]), scala_T([64])]), \"inception_3b/\"))\n",
+ " model.add(SpatialMaxPooling(3, 3, 2, 2, to_ceil=True))\n",
+ " model.add(Inception_Layer_v1(480, scala_T([scala_T([192]), scala_T(\n",
+ " [96, 208]), scala_T([16, 48]), scala_T([64])]), \"inception_4a/\"))\n",
+ " model.add(Inception_Layer_v1(512, scala_T([scala_T([160]), scala_T(\n",
+ " [112, 224]), scala_T([24, 64]), scala_T([64])]), \"inception_4b/\"))\n",
+ " model.add(Inception_Layer_v1(512, scala_T([scala_T([128]), scala_T(\n",
+ " [128, 256]), scala_T([24, 64]), scala_T([64])]), \"inception_4c/\"))\n",
+ " model.add(Inception_Layer_v1(512, scala_T([scala_T([112]), scala_T(\n",
+ " [144, 288]), scala_T([32, 64]), scala_T([64])]), \"inception_4d/\"))\n",
+ " model.add(Inception_Layer_v1(528, scala_T([scala_T([256]), scala_T(\n",
+ " [160, 320]), scala_T([32, 128]), scala_T([128])]), \"inception_4e/\"))\n",
+ " model.add(SpatialMaxPooling(3, 3, 2, 2, to_ceil=True))\n",
+ " model.add(Inception_Layer_v1(832, scala_T([scala_T([256]), scala_T(\n",
+ " [160, 320]), scala_T([32, 128]), scala_T([128])]), \"inception_5a/\"))\n",
+ " model.add(Inception_Layer_v1(832, scala_T([scala_T([384]), scala_T(\n",
+ " [192, 384]), scala_T([48, 128]), scala_T([128])]), \"inception_5b/\"))\n",
+ " model.add(SpatialAveragePooling(7, 7, 1, 1).set_name(\"pool5/7x7_s1\"))\n",
+ " model.add(Dropout(0.4).set_name(\"pool5/drop_7x7_s1\"))\n",
+ " model.add(View([1024], num_input_dims=3))\n",
+ " model.reset()\n",
+ " return model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 83,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def Inception_v1_NoAuxClassifier():\n",
+ " model = Inception_v1_Bottleneck()\n",
+ " model.add(Linear(1024, class_num).set_name(\"loss3/classifier_flowers\"))\n",
+ " model.add(LogSoftMax().set_name(\"loss3/loss3\"))\n",
+ " model.reset()\n",
+ " return model"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Creating the Bottleneck Model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 84,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# initializing BigDL engine\n",
+ "init_engine()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 85,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\n",
+ "# paths for datasets, saving checkpoints \n",
+ "from os import path\n",
+ "\n",
+ "DATA_ROOT = \"./sample_images\"\n",
+ "checkpoint_path = path.join(DATA_ROOT, \"checkpoints\")\n",
+ "\n",
+ "IMAGE_SIZE = 224"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 86,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialMaxPooling\n",
+ "creating: createSpatialCrossMapLRN\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialCrossMapLRN\n",
+ "creating: createSpatialMaxPooling\n",
+ "creating: createConcat\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialMaxPooling\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createConcat\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialMaxPooling\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialMaxPooling\n",
+ "creating: createConcat\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialMaxPooling\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createConcat\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialMaxPooling\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createConcat\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialMaxPooling\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createConcat\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialMaxPooling\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createConcat\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialMaxPooling\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialMaxPooling\n",
+ "creating: createConcat\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialMaxPooling\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createConcat\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSequential\n",
+ "creating: createSpatialMaxPooling\n",
+ "creating: createSpatialConvolution\n",
+ "creating: createReLU\n",
+ "creating: createSpatialAveragePooling\n",
+ "creating: createDropout\n",
+ "creating: createView\n"
+ ]
+ }
+ ],
+ "source": [
+ "inception_model = Inception_v1_Bottleneck()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Download the Pre-trained Model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 87,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\n",
+ "import urllib\n",
+ "\n",
+ "# path, names of the downlaoded pre-trained caffe models\n",
+ "caffe_prototxt = 'bvlc_googlenet.prototxt'\n",
+ "caffe_model = 'bvlc_googlenet.caffemodel'\n",
+ "\n",
+ "if not path.exists(caffe_model):\n",
+ " model_loader = urllib.URLopener()\n",
+ " model_loader.retrieve(\"http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel\", caffe_model)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Import Weights from Caffe Model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 88,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\n",
+ "# loading the weights to the BigDL inception model, EXCEPT the weights for the last fc layer (classification layer)\n",
+ "model = Model.load_caffe(inception_model, caffe_prototxt, caffe_model, match_all=False, bigdl_type=\"float\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "## Load images with their Labels"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 89,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "'''\n",
+ "Load img-label pairs, but only if label is shared by more than \"min_samples\" (160) other samples.\n",
+ "'''\n",
+ "# load img-label pairs, but only if label is shared by more than \"min_samples\" (160) other samples.\n",
+ "def imgs_to_load(labels_csv, pik, min_samples):\n",
+ " labels = pd.read_csv(labels_csv)\n",
+ " file_names = labels['obs_uid'].sort_values().tolist()\n",
+ " imgs = pickle.load(open(pik, \"rb\"))\n",
+ " result = []\n",
+ " \n",
+ " # item_name is index, obs_uid - count\n",
+ " counts = labels[['item_name', 'obs_uid']].groupby(['item_name']).count()\n",
+ " # print counts\n",
+ " labels = labels.set_index(['obs_uid'])\n",
+ " \n",
+ " for idx in range(len(file_names)):\n",
+ " uid = file_names[idx]\n",
+ " label = labels.loc[uid]['item_name']\n",
+ " add = True\n",
+ " if min_samples is not None:\n",
+ " cnt = counts.loc[label]['obs_uid']\n",
+ " add = cnt >= min_samples\n",
+ " # only add sample if there are more than min_sample number of samples w/that label\n",
+ " if add:\n",
+ " img = imgs[idx].convert('RGB')\n",
+ " img_np = np.array(img)\n",
+ " result.append((img_np, label))\n",
+ " \n",
+ " return result\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Download the processed images from Amazon s3\n",
+ "\n",
+ "This could take 10-20 minutes, images require space of 1G"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 90,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import urllib\n",
+ "from os import path\n",
+ "processed_imgs = 'processed-samples.pkl'\n",
+ "\n",
+ "if not path.exists(processed_imgs):\n",
+ "# imgs_loader = urllib.URLopener()\n",
+ "# imgs_loader.retrieve(\"https://s3-us-west-2.amazonaws.com/vegnonveg/processed-samples.pkl\", processed_imgs)\n",
+ " os.system('wget https://s3-us-west-2.amazonaws.com/vegnonveg/processed-samples.pkl')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 91,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "# of images: 1927\n"
+ ]
+ }
+ ],
+ "source": [
+ "img_labels = imgs_to_load(DATA_ROOT + '/vegnonveg-samples_labels.csv',processed_imgs, 160)\n",
+ "print \"# of images: \", len(img_labels)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 92,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "one img-label pair: (224, 224, 3) , Fresh cucumber\n"
+ ]
+ }
+ ],
+ "source": [
+ "# look at one img-label pair\n",
+ "print \"one img-label pair: \", img_labels[0][0].shape, \", \", img_labels[0][1]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 93,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "transform_input = Transformer([TransposeToTensor(False)])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Calculate the bottleneck values"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 94,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "pred_list = []\n",
+ "batch_size = 256\n",
+ "for start in range(0, len(img_labels), batch_size):\n",
+ " img_batch = img_labels[start : start + batch_size]\n",
+ " rdd_img = sc.parallelize(x[0] for x in img_batch)\n",
+ " rdd_sample = rdd_img.map(lambda img: Sample.from_ndarray(transform_input(img), np.array(0))) \n",
+ " preds = model.predict(rdd_sample)\n",
+ " p = preds.collect()\n",
+ " pred_list.extend(p)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 95,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "data = {\n",
+ " 'bottleneck_values': pred_list,\n",
+ " 'labels': [lbl for fname, lbl in img_labels]\n",
+ "}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 96,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "pickle.dump(data, open(DATA_ROOT + \"/bottlenecks_with_labels.pkl\", 'wb'))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Train and Test Classifiers"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 97,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pickle\n",
+ "from sklearn.model_selection import train_test_split, cross_val_score, StratifiedKFold\n",
+ "from sklearn.neural_network import MLPClassifier\n",
+ "from sklearn.metrics import precision_recall_fscore_support\n",
+ "from sklearn.linear_model import SGDClassifier, LogisticRegression"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 98,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "data = pickle.load(open(DATA_ROOT + \"/bottlenecks_with_labels.pkl\", 'rb'))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Use Stratified Train/Test Split\n",
+ "To make sure we have the same distribution of samples across labels in both train and test sets."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 99,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(1541, 1541, 386, 386)"
+ ]
+ },
+ "execution_count": 99,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "\n",
+ "x_train, x_test, train_labels, test_labels = \\\n",
+ " train_test_split(data['bottleneck_values'], \n",
+ " data['labels'], \n",
+ " test_size=0.2, \n",
+ " random_state=101,\n",
+ " stratify=data['labels'])\n",
+ "len(x_train), len(train_labels), len(x_test), len(test_labels)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 100,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "_, train_counts = np.unique(np.array(train_labels), return_counts=True)\n",
+ "train_counts = train_counts.astype(np.float) / len(train_labels)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 101,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([ 2.28812638, 0.19430052, -1.21141356, 1.36848522, 0.19430052,\n",
+ " -0.32824241, -0.27871228, -0.77468686, -1.03786861])"
+ ]
+ },
+ "execution_count": 101,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "_, test_counts = np.unique(np.array(test_labels), return_counts=True)\n",
+ "test_counts = test_counts.astype(np.float) / len(test_labels)\n",
+ "# Difference in labels counts, %\n",
+ "(train_counts - test_counts) / train_counts * 100"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Classifier #1: BigDL Logistic Regression"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 102,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{'Chicken eggs, caged hen, large size': 0, 'Fresh bananas, standard': 1, 'Fresh onions': 2, 'Fresh cucumber': 3, 'Fresh apple, red delicious': 4, 'Fresh potatoes, brown': 5, 'Fresh carrots': 6, 'Fresh oranges': 7, 'Fresh apples, typical local variety': 8}\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Create Labels for BigDl\n",
+ "categories = set(lbls for img, lbls in img_labels)\n",
+ "label_nums = dict(zip(categories, range(0,len(categories))))\n",
+ "pickle.dump(label_nums, open(DATA_ROOT + \"/labels_bigdl_classifier.pkl\", 'wb'))\n",
+ "print label_nums"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 103,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# get rdd\n",
+ "def get_rdd_sample(images, labels):\n",
+ " labels = map(lambda(word): label_nums[word] + 1, labels)\n",
+ " imgs = sc.parallelize(images)\n",
+ " labels = sc.parallelize(labels)\n",
+ " sample_rdd = imgs.zip(labels).map(lambda(bottleneck, label): Sample.from_ndarray(bottleneck, np.array(label)))\n",
+ " return sample_rdd\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 104,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "train_rdd = get_rdd_sample(x_train, train_labels)\n",
+ "test_rdd = get_rdd_sample(x_test, test_labels)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Define Model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 105,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "creating: createSequential\n",
+ "creating: createLinear\n",
+ "creating: createLogSoftMax\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Parameters\n",
+ "learning_rate = 0.2\n",
+ "training_epochs = 40\n",
+ "batch_size = 60\n",
+ "\n",
+ "# Network Parameters\n",
+ "n_input = 1024 # 1024\n",
+ "n_classes = len(set(lbls for img, lbls in img_labels)) # item_name categories\n",
+ "\n",
+ "\n",
+ "def fc_layer(n_input, n_classes):\n",
+ " model = Sequential()\n",
+ " model.add(Linear(n_input, n_classes))\n",
+ " model.add(LogSoftMax())\n",
+ " return model # Create an Optimizer\n",
+ "\n",
+ "model = fc_layer(n_input, n_classes)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 106,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "creating: createClassNLLCriterion\n",
+ "creating: createDefault\n",
+ "creating: createSGD\n",
+ "creating: createMaxEpoch\n",
+ "creating: createOptimizer\n",
+ "creating: createEveryEpoch\n",
+ "creating: createTop1Accuracy\n",
+ "creating: createTrainSummary\n",
+ "creating: createSeveralIteration\n",
+ "creating: createValidationSummary\n",
+ "saving logs to vegnonveg\n"
+ ]
+ }
+ ],
+ "source": [
+ "optimizer = Optimizer(\n",
+ " model=model,\n",
+ " training_rdd=train_rdd,\n",
+ " criterion=ClassNLLCriterion(),\n",
+ " optim_method=SGD(learningrate=learning_rate),\n",
+ " end_trigger=MaxEpoch(training_epochs),\n",
+ " batch_size=batch_size)\n",
+ "# Set the validation logic\n",
+ "optimizer.set_validation(\n",
+ " batch_size=batch_size,\n",
+ " val_rdd=test_rdd,\n",
+ " trigger=EveryEpoch(),\n",
+ " val_method=[Top1Accuracy()]\n",
+ ")\n",
+ "\n",
+ "app_name= 'vegnonveg' # + dt.datetime.now().strftime(\"%Y%m%d-%H%M%S\")\n",
+ "train_summary = TrainSummary(log_dir='/tmp/bigdl_summaries',\n",
+ " app_name=app_name)\n",
+ "train_summary.set_summary_trigger(\"Parameters\", SeveralIteration(50))\n",
+ "val_summary = ValidationSummary(log_dir='/tmp/bigdl_summaries',\n",
+ " app_name=app_name)\n",
+ "optimizer.set_train_summary(train_summary)\n",
+ "optimizer.set_val_summary(val_summary)\n",
+ "print \"saving logs to \",app_name"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 107,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Optimization Done.\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Start to train\n",
+ "trained_model = optimizer.optimize()\n",
+ "print \"Optimization Done.\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 108,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def map_predict_label(l):\n",
+ " return np.array(l).argmax()\n",
+ "def map_groundtruth_label(l):\n",
+ " return l[0] - 1\n",
+ "def map_to_label(l):\n",
+ " return label_nums.keys()[label_nums.values().index(l)]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 109,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1 ) Ground Truth label: Fresh potatoes, brown\n",
+ "1 ) Predicted label: Fresh onions\n",
+ "wrong\n",
+ "2 ) Ground Truth label: Fresh apples, typical local variety\n",
+ "2 ) Predicted label: Fresh apple, red delicious\n",
+ "wrong\n",
+ "3 ) Ground Truth label: Fresh cucumber\n",
+ "3 ) Predicted label: Fresh oranges\n",
+ "wrong\n",
+ "4 ) Ground Truth label: Fresh cucumber\n",
+ "4 ) Predicted label: Fresh cucumber\n",
+ "correct\n",
+ "5 ) Ground Truth label: Fresh apples, typical local variety\n",
+ "5 ) Predicted label: Fresh apple, red delicious\n",
+ "wrong\n",
+ "6 ) Ground Truth label: Fresh cucumber\n",
+ "6 ) Predicted label: Fresh cucumber\n",
+ "correct\n",
+ "7 ) Ground Truth label: Fresh carrots\n",
+ "7 ) Predicted label: Fresh carrots\n",
+ "correct\n",
+ "8 ) Ground Truth label: Fresh potatoes, brown\n",
+ "8 ) Predicted label: Fresh potatoes, brown\n",
+ "correct\n"
+ ]
+ }
+ ],
+ "source": [
+ "'''\n",
+ "Look at some predictions and their accuracy\n",
+ "'''\n",
+ "predictions = trained_model.predict(test_rdd)\n",
+ "\n",
+ "num_preds = 8\n",
+ "truth = test_rdd.take(num_preds)\n",
+ "preds = predictions.take(num_preds)\n",
+ "for idx in range(num_preds):\n",
+ " true_label = str(map_to_label(map_groundtruth_label(truth[idx].label.to_ndarray())))\n",
+ " pred_label = str(map_to_label(map_predict_label(preds[idx])))\n",
+ " print idx + 1, ')', 'Ground Truth label: ', true_label\n",
+ " print idx + 1, ')', 'Predicted label: ', pred_label\n",
+ " print \"correct\" if true_label == pred_label else \"wrong\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 110,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "creating: createTop1Accuracy\n"
+ ]
+ }
+ ],
+ "source": [
+ "'''\n",
+ "Measure Test Accuracy w/Test Set\n",
+ "'''\n",
+ "\n",
+ "results = trained_model.evaluate(test_rdd, 32, [Top1Accuracy()])\n",
+ "print(results[0])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Classifier #2: Neural Net"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 111,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "clf = MLPClassifier(hidden_layer_sizes=(512,))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 112,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "CPU times: user 1min 24s, sys: 1min 34s, total: 2min 59s\n",
+ "Wall time: 46.8 s\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "array([ 0.69245648, 0.6692607 , 0.69607843])"
+ ]
+ },
+ "execution_count": 112,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "%%time \n",
+ "cross_val_score(clf, x_train, train_labels, cv=StratifiedKFold(n_splits=3), scoring='accuracy')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Classifier #3: Logistic Regression"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 113,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "CPU times: user 6.77 s, sys: 192 ms, total: 6.96 s\n",
+ "Wall time: 6.86 s\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "array([ 0.67117988, 0.6614786 , 0.66666667])"
+ ]
+ },
+ "execution_count": 113,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "cross_val_score(LogisticRegression(), x_train, train_labels, cv=StratifiedKFold(n_splits=3), scoring='accuracy')"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 2",
+ "language": "python",
+ "name": "python2"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 2
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython2",
+ "version": "2.7.14"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}