{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Linear Regression with Eager API\n",
    "\n",
    "A linear regression implemented using TensorFlow's Eager API.\n",
    "\n",
    "- Author: Aymeric Damien\n",
    "- Project: https://github.com/aymericdamien/TensorFlow-Examples/"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from __future__ import absolute_import, division, print_function\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Set Eager API\n",
    "tf.enable_eager_execution()\n",
    "tfe = tf.contrib.eager"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Training Data\n",
    "train_X = [3.3, 4.4, 5.5, 6.71, 6.93, 4.168, 9.779, 6.182, 7.59, 2.167,\n",
    "           7.042, 10.791, 5.313, 7.997, 5.654, 9.27, 3.1]\n",
    "train_Y = [1.7, 2.76, 2.09, 3.19, 1.694, 1.573, 3.366, 2.596, 2.53, 1.221,\n",
    "           2.827, 3.465, 1.65, 2.904, 2.42, 2.94, 1.3]\n",
    "n_samples = len(train_X)\n",
    "\n",
    "# Parameters\n",
    "learning_rate = 0.01\n",
    "display_step = 100\n",
    "num_steps = 1000"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Weight and Bias\n",
    "W = tfe.Variable(np.random.randn())\n",
    "b = tfe.Variable(np.random.randn())\n",
    "\n",
    "# Linear regression (Wx + b)\n",
    "def linear_regression(inputs):\n",
    "    return inputs * W + b\n",
    "\n",
    "# Mean square error\n",
    "def mean_square_fn(model_fn, inputs, labels):\n",
    "    return tf.reduce_sum(tf.pow(model_fn(inputs) - labels, 2)) / (2 * n_samples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# SGD Optimizer\n",
    "optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)\n",
    "\n",
    "# Compute gradients\n",
    "grad = tfe.implicit_gradients(mean_square_fn)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Initial cost= 31.307329178 W= -0.7870768 b= -0.2507985\n",
      "Epoch: 0001 cost= 9.502781868 W= -0.26173288 b= -0.17560114\n",
      "Epoch: 0100 cost= 0.114994615 W= 0.36224815 b= 0.014603348\n",
      "Epoch: 0200 cost= 0.106785327 W= 0.34959725 b= 0.104292504\n",
      "Epoch: 0300 cost= 0.100346453 W= 0.33839324 b= 0.1837239\n",
      "Epoch: 0400 cost= 0.095296182 W= 0.32847065 b= 0.25407064\n",
      "Epoch: 0500 cost= 0.091335081 W= 0.3196829 b= 0.3163719\n",
      "Epoch: 0600 cost= 0.088228233 W= 0.31190023 b= 0.37154746\n",
      "Epoch: 0700 cost= 0.085791394 W= 0.30500764 b= 0.42041263\n",
      "Epoch: 0800 cost= 0.083880097 W= 0.2989034 b= 0.46368918\n",
      "Epoch: 0900 cost= 0.082380980 W= 0.2934973 b= 0.50201607\n",
      "Epoch: 1000 cost= 0.081205189 W= 0.28870946 b= 0.5359594\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x106892d90>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Initial cost, before optimizing\n",
    "print(\"Initial cost= {:.9f}\".format(\n",
    "    mean_square_fn(linear_regression, train_X, train_Y)),\n",
    "    \"W=\", W.numpy(), \"b=\", b.numpy())\n",
    "\n",
    "# Training\n",
    "for step in range(num_steps):\n",
    "\n",
    "    optimizer.apply_gradients(grad(linear_regression, train_X, train_Y))\n",
    "\n",
    "    if (step + 1) % display_step == 0 or step == 0:\n",
    "        print(\"Epoch:\", '%04d' % (step + 1), \"cost=\",\n",
    "              \"{:.9f}\".format(mean_square_fn(linear_regression, train_X, train_Y)),\n",
    "              \"W=\", W.numpy(), \"b=\", b.numpy())\n",
    "\n",
    "# Graphic display\n",
    "plt.plot(train_X, train_Y, 'ro', label='Original data')\n",
    "plt.plot(train_X, np.array(W * train_X + b), label='Fitted line')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [default]",
   "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.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
