{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# CS 20 : TensorFlow for Deep Learning Research\n",
    "## Lecture 03 : Linear and Logistic Regression\n",
    "### Linear Regression with tf.data\n",
    "same contents, but different style with [Lec03_Linear Regression with tf.data.ipynb](https://nbviewer.jupyter.org/github/aisolab/CS20/blob/master/Lec03_Linear%20and%20Logistic%20Regression/Lec03_Linear%20Regression%20with%20tf.data.ipynb)\n",
    "\n",
    "* Creating the input pipeline with `tf.data`\n",
    "* Using `eager execution`  \n",
    "\n",
    "**Reference**\n",
    "\n",
    "* https://jhui.github.io/2017/11/21/TensorFlow-Importing-data/\n",
    "* https://towardsdatascience.com/how-to-use-dataset-in-tensorflow-c758ef9e4428\n",
    "* https://stackoverflow.com/questions/47356764/how-to-use-tensorflow-dataset-api-with-training-and-validation-sets"
   ]
  },
  {
   "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 os, sys\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import tensorflow as tf\n",
    "from pprint import pprint\n",
    "%matplotlib inline\n",
    "\n",
    "print(tf.__version__)\n",
    "tf.enable_eager_execution()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Build input pipeline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['../data/lecture03/example_with_data/train_dir/birth_life_2010_tr_6.txt',\n",
      " '../data/lecture03/example_with_data/train_dir/birth_life_2010_tr_7.txt',\n",
      " '../data/lecture03/example_with_data/train_dir/birth_life_2010_tr_5.txt',\n",
      " '../data/lecture03/example_with_data/train_dir/birth_life_2010_tr_4.txt',\n",
      " '../data/lecture03/example_with_data/train_dir/birth_life_2010_tr_14.txt',\n",
      " '../data/lecture03/example_with_data/train_dir/birth_life_2010_tr_10.txt',\n",
      " '../data/lecture03/example_with_data/train_dir/birth_life_2010_tr_1.txt',\n",
      " '../data/lecture03/example_with_data/train_dir/birth_life_2010_tr_11.txt',\n",
      " '../data/lecture03/example_with_data/train_dir/birth_life_2010_tr_13.txt',\n",
      " '../data/lecture03/example_with_data/train_dir/birth_life_2010_tr_3.txt',\n",
      " '../data/lecture03/example_with_data/train_dir/birth_life_2010_tr_2.txt',\n",
      " '../data/lecture03/example_with_data/train_dir/birth_life_2010_tr_12.txt',\n",
      " '../data/lecture03/example_with_data/train_dir/birth_life_2010_tr_9.txt',\n",
      " '../data/lecture03/example_with_data/train_dir/birth_life_2010_tr_8.txt']\n"
     ]
    }
   ],
   "source": [
    "train_dir = os.listdir('../data/lecture03/example_with_data/train_dir/')\n",
    "train_dir = list(map(lambda path : '../data/lecture03/example_with_data/train_dir/' + path, train_dir))\n",
    "pprint(train_dir, compact = True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "'../data/lecture03/example_with_data/val_dir/birth_life_2010_val.txt'\n"
     ]
    }
   ],
   "source": [
    "val_dir = '../data/lecture03/example_with_data/val_dir/birth_life_2010_val.txt'\n",
    "pprint(val_dir)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# hyper parameters\n",
    "epochs = 100\n",
    "batch_size = 8"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# datasets construction\n",
    "# for training dataset\n",
    "tr_dataset = tf.data.TextLineDataset(filenames = train_dir)\n",
    "tr_dataset = tr_dataset.map(lambda record : tf.decode_csv(records = record,\n",
    "                                                          record_defaults = [[''],[.0],[.0]],\n",
    "                                                          field_delim = '\\t')[1:])\n",
    "tr_dataset = tr_dataset.shuffle(200)\n",
    "tr_dataset = tr_dataset.batch(batch_size = batch_size)\n",
    "\n",
    "# for validation dataset\n",
    "val_dataset = tf.data.TextLineDataset(filenames = val_dir)\n",
    "val_dataset = val_dataset.map(lambda record : tf.decode_csv(records = record,\n",
    "                                                          record_defaults = [[''],[.0],[.0]],\n",
    "                                                          field_delim = '\\t')[1:])\n",
    "val_dataset = val_dataset.batch(batch_size = batch_size)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Define the graph of Simple Linear Regression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# create weight and bias, initialized to 0 \n",
    "w = tf.Variable(initial_value=tf.constant(.0), name='weight')\n",
    "b = tf.Variable(initial_value=tf.constant(.0), name='bias')\n",
    "\n",
    "# construct model to predict Y\n",
    "def model(x):\n",
    "    yhat = x * w + b\n",
    "    return yhat\n",
    "\n",
    "# use the square error as loss function\n",
    "def loss_fn(model, x, y):\n",
    "    loss = tf.reduce_mean(tf.square(y - model(x)))\n",
    "    return loss \n",
    "\n",
    "# using gradient descent with learning rate of 0.01 to minimize loss\n",
    "opt = tf.train.GradientDescentOptimizer(learning_rate=.01)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Training"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# create writer for tensorboard\n",
    "logdir = '../graphs/lecture03/linreg_mse_with_tf_data_de/'\n",
    "summary_writer = tf.contrib.summary.create_file_writer(logdir=logdir)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch :  10, tr_loss : 413.291, val_loss : 406.159\n",
      "epoch :  20, tr_loss : 139.664, val_loss : 132.022\n",
      "epoch :  30, tr_loss : 61.530, val_loss : 61.833\n",
      "epoch :  40, tr_loss : 41.262, val_loss : 44.971\n",
      "epoch :  50, tr_loss : 36.349, val_loss : 39.528\n",
      "epoch :  60, tr_loss : 37.686, val_loss : 37.375\n",
      "epoch :  70, tr_loss : 33.509, val_loss : 37.475\n",
      "epoch :  80, tr_loss : 34.324, val_loss : 41.001\n",
      "epoch :  90, tr_loss : 33.222, val_loss : 38.470\n",
      "epoch : 100, tr_loss : 33.326, val_loss : 39.271\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "# hyper parameters\n",
    "epochs = 100\n",
    "batch_size = 8\n",
    "'''\n",
    "global_step = tf.train.get_or_create_global_step()\n",
    "tr_loss_hist = []\n",
    "val_loss_hist = []\n",
    "\n",
    "for epoch in range(epochs):\n",
    "\n",
    "    avg_tr_loss = 0\n",
    "    avg_val_loss = 0\n",
    "    tr_step = 0\n",
    "    val_step = 0\n",
    "    \n",
    "    with summary_writer.as_default(), tf.contrib.summary.always_record_summaries(): # for tensorboard\n",
    "        # for training\n",
    "        for x_mb, y_mb in tr_dataset:\n",
    "            with tf.GradientTape() as tape:\n",
    "                tr_loss = loss_fn(model=model, x=x_mb, y=y_mb)\n",
    "            tf.contrib.summary.scalar(name='tr_loss', tensor=tr_loss)\n",
    "            avg_tr_loss += tr_loss\n",
    "            tr_step +=1\n",
    "            \n",
    "            grads = tape.gradient(target=tr_loss, sources=[w, b])\n",
    "            opt.apply_gradients(grads_and_vars=zip(grads, [w,b]))\n",
    "        else:\n",
    "            avg_tr_loss /= tr_step\n",
    "            tr_loss_hist.append(avg_tr_loss)\n",
    "        # for validation\n",
    "        for x_mb, y_mb in val_dataset:\n",
    "            val_loss = loss_fn(model=model, x=x_mb, y=y_mb)\n",
    "            tf.contrib.summary.scalar(name='val_loss', tensor=val_loss)\n",
    "            avg_val_loss += val_loss\n",
    "            val_step += 1\n",
    "        else:\n",
    "            avg_val_loss /= val_step\n",
    "            val_loss_hist.append(avg_val_loss)\n",
    "    \n",
    "    if (epoch + 1) % 10 == 0:\n",
    "        print('epoch : {:3}, tr_loss : {:.3f}, val_loss : {:.3f}'.format(epoch + 1, avg_tr_loss, avg_val_loss))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Visualization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x123087a20>"
      ]
     },
     "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 0x1230fc8d0>"
      ]
     },
     "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": [
    "data = pd.read_table('../data/lecture03/example_with_placeholder/birth_life_2010.txt') # loading data for Visualization\n",
    "plt.plot(data.iloc[:,1], data.iloc[:,2], 'bo', label='Real data')\n",
    "plt.plot(data.iloc[:,1], data.iloc[:,1] * w + b, '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
}