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 +}