{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# CS 20 : TensorFlow for Deep Learning Research\n",
    "## Lecture 03 : Linear and Logistic Regression\n",
    "### Linear Regression with huber loss by low-level"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.12.0\n"
     ]
    }
   ],
   "source": [
    "from __future__ import absolute_import, division, print_function\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import tensorflow as tf\n",
    "%matplotlib inline\n",
    "\n",
    "print(tf.__version__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Load and Pre-process data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Country</th>\n",
       "      <th>Birth rate</th>\n",
       "      <th>Life expectancy</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Vietnam</td>\n",
       "      <td>1.822</td>\n",
       "      <td>74.828244</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Vanuatu</td>\n",
       "      <td>3.869</td>\n",
       "      <td>70.819488</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Tonga</td>\n",
       "      <td>3.911</td>\n",
       "      <td>72.150659</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Timor-Leste</td>\n",
       "      <td>5.578</td>\n",
       "      <td>61.999854</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Thailand</td>\n",
       "      <td>1.579</td>\n",
       "      <td>73.927659</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       Country  Birth rate  Life expectancy\n",
       "0      Vietnam       1.822        74.828244\n",
       "1      Vanuatu       3.869        70.819488\n",
       "2        Tonga       3.911        72.150659\n",
       "3  Timor-Leste       5.578        61.999854\n",
       "4     Thailand       1.579        73.927659"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = pd.read_table('../data/lecture03/example_with_placeholder/birth_life_2010.txt')\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(190,) (190,)\n"
     ]
    }
   ],
   "source": [
    "x = data.loc[:,'Birth rate'].values\n",
    "y = data.loc[:,'Life expectancy'].values\n",
    "print(x.shape, y.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(133,) (133,)\n",
      "(57,) (57,)\n"
     ]
    }
   ],
   "source": [
    "# split train and validation\n",
    "tr_indices = np.random.choice(range(x.shape[0]), size = int(x.shape[0] * .7), replace=False)\n",
    "x_tr = x[tr_indices]\n",
    "y_tr = y[tr_indices]\n",
    "\n",
    "x_val = np.delete(x, tr_indices, axis = 0)\n",
    "y_val = np.delete(y, tr_indices, axis = 0)\n",
    "\n",
    "print(x_tr.shape, y_tr.shape)\n",
    "print(x_val.shape, y_val.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Define the graph of Simple Linear Regression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# create placeholders for X (birth rate) and Y (life expectancy)\n",
    "X = tf.placeholder(dtype = tf.float32, shape = [None])\n",
    "Y = tf.placeholder(dtype = tf.float32, shape = [None])\n",
    "\n",
    "# create weight and bias, initialized to 0 \n",
    "w = tf.get_variable(name = 'weight', initializer = tf.constant(.0))\n",
    "b = tf.get_variable(name = 'bias', initializer = tf.constant(.0))\n",
    "\n",
    "# construct model to predict Y\n",
    "yhat = X * w + b\n",
    "\n",
    "# use the square error as huber loss function\n",
    "residual = tf.abs(Y - yhat)\n",
    "huber_loss = tf.cond(tf.reduce_mean(residual) <= 14.,\n",
    "                     lambda : .5 * tf.reduce_mean(tf.square(residual)),\n",
    "                     lambda : 14. * tf.reduce_mean(residual) - .5 * tf.square(14.))\n",
    "\n",
    "huber_loss_summ = tf.summary.scalar(name = 'huber_loss', tensor = huber_loss) # for tensorboard\n",
    "\n",
    "# using gradient descent with learning rate of 0.01 to minimize loss\n",
    "opt = tf.train.GradientDescentOptimizer(learning_rate=.01)\n",
    "training_op = opt.minimize(huber_loss)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Training"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "23\n"
     ]
    }
   ],
   "source": [
    "epochs = 100\n",
    "batch_size = 8\n",
    "total_step = int(x.shape[0] / batch_size)\n",
    "print(total_step)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_writer = tf.summary.FileWriter(logdir = '../graphs/lecture03/linreg_huber_low_tf_placeholder/train',\n",
    "                                     graph = tf.get_default_graph())\n",
    "val_writer = tf.summary.FileWriter(logdir = '../graphs/lecture03/linreg_huber_low_tf_placeholder/val',\n",
    "                                     graph = tf.get_default_graph())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch :   0, tr_loss : 698.17, val_loss : 652.16\n",
      "epoch :  10, tr_loss : 272.37, val_loss : 317.21\n",
      "epoch :  20, tr_loss : 236.84, val_loss : 237.75\n",
      "epoch :  30, tr_loss : 167.02, val_loss : 180.62\n",
      "epoch :  40, tr_loss : 115.76, val_loss : 116.99\n",
      "epoch :  50, tr_loss : 55.87, val_loss : 64.06\n",
      "epoch :  60, tr_loss : 38.91, val_loss : 41.34\n",
      "epoch :  70, tr_loss : 22.83, val_loss : 28.91\n",
      "epoch :  80, tr_loss : 18.10, val_loss : 20.98\n",
      "epoch :  90, tr_loss : 17.04, val_loss : 13.29\n"
     ]
    }
   ],
   "source": [
    "sess_config = tf.ConfigProto(gpu_options=tf.GPUOptions(allow_growth=True))\n",
    "sess = tf.Session(config = sess_config)\n",
    "sess.run(tf.global_variables_initializer())\n",
    "\n",
    "tr_loss_hist = []\n",
    "val_loss_hist = []\n",
    "\n",
    "for epoch in range(epochs):\n",
    "    avg_tr_loss = 0\n",
    "    avg_val_loss = 0\n",
    "    \n",
    "    for step in range(total_step):\n",
    "        batch_indices = np.random.choice(range(x_tr.shape[0]),\n",
    "                                         size = batch_size, replace = False)\n",
    "        val_indices = np.random.choice(range(x_val.shape[0]),\n",
    "                                       size = batch_size, replace = False)\n",
    "        batch_xs = x_tr[batch_indices]\n",
    "        batch_ys = y_tr[batch_indices]\n",
    "        val_xs = x_val[val_indices]\n",
    "        val_ys = y_val[val_indices]\n",
    "        \n",
    "        _, tr_loss = sess.run(fetches = [training_op, huber_loss],\n",
    "                              feed_dict = {X : batch_xs, Y : batch_ys})\n",
    "        tr_loss_summ = sess.run(huber_loss_summ, feed_dict = {X : batch_xs, Y : batch_ys})\n",
    "\n",
    "        val_loss, val_loss_summ = sess.run(fetches = [huber_loss, huber_loss_summ],\n",
    "                                           feed_dict = {X : val_xs, Y: val_ys})\n",
    "        avg_tr_loss += tr_loss / total_step\n",
    "        avg_val_loss += val_loss / total_step\n",
    "        \n",
    "    train_writer.add_summary(tr_loss_summ, global_step = epoch)\n",
    "    val_writer.add_summary(val_loss_summ, global_step = epoch)\n",
    "    \n",
    "    tr_loss_hist.append(avg_tr_loss)\n",
    "    val_loss_hist.append(avg_val_loss)\n",
    "    \n",
    "    if epoch % 10 == 0:\n",
    "        print('epoch : {:3}, tr_loss : {:.2f}, val_loss : {:.2f}'.format(epoch, avg_tr_loss, avg_val_loss))\n",
    "\n",
    "train_writer.close()\n",
    "val_writer.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Visualization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x11f4011d0>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(tr_loss_hist, label = 'train')\n",
    "plt.plot(val_loss_hist, label = 'validation')\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x11f46ceb8>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "w_out, b_out = sess.run([w, b])\n",
    "plt.plot(data.iloc[:,1], data.iloc[:,2], 'bo', label='Real data')\n",
    "plt.plot(data.iloc[:,1], data.iloc[:,1] * w_out + b_out, 'r', label='Predicted data')\n",
    "plt.legend()"
   ]
  }
 ],
 "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.6.6"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}