diff --git a/Linear_regression.ipynb b/Linear_regression.ipynb new file mode 100644 index 0000000..9fa4902 --- /dev/null +++ b/Linear_regression.ipynb @@ -0,0 +1,3018 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Linear Regression Example" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Make datasets and test set\n", + "#### data points are sampled from a curve y= x+ 20*sin(x/10).
make sure the shape of the data matrix with which you feed to the tensor correspond to the shape of the tensor" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n/wHrNC+IHicxsAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import tensorflow as tf\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from matplotlib import animation, rc\n", + "from IPython.display import HTML\n", + "%matplotlib inline\n", + "# Define input data\n", + "X_data = np.arange(100, step=2.5)\n", + "y_data = X_data + 20 * np.sin(X_data/10)\n", + "# Plot input data\n", + "plt.scatter(X_data, y_data)\n", + "\n", + "n_samples = int(100/2.5)\n", + "# Tensorflow is picky about shapes, so resize\n", + "X_data = np.reshape(X_data, (n_samples,1))\n", + "y_data = np.reshape(y_data, (n_samples,1))\n", + "\n", + "X_test = np.random.rand(200)*120\n", + "X_test = X_test.reshape(-1, 1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Creating the graph and run it\n", + "#### In Graph building stage, python call tensorflow api to create Tensorflow Nodes and connect those Nodes. (at this moment the graph is static)
Note that in tensorflow Graph, Nodes are called Operations and Edges connect those Nodes are called tensors \n", + "#### A fetch on a tensor would require its preceeding Node to activate, for a Node to activate would require all it's inbound tensors/Edges to be filled with data, recursively all the way to the leaf Nodes (placeholder, variable, constant)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "################Graph building stage################\n", + "# Define placeholders for input\n", + "X = tf.placeholder(tf.float32, shape=(None, 1))\n", + "y = tf.placeholder(tf.float32, shape=(None, 1)) \n", + "\n", + "# Define variables to be learned\n", + "with tf.variable_scope(\"linear_regression\"):\n", + " W = tf.Variable(np.random.rand(1, 1), 'weight', dtype=tf.float32)\n", + " b = tf.Variable(np.random.rand(1, 1), 'bias', dtype=tf.float32)\n", + " \n", + " y_pred = tf.matmul(X, W) + b\n", + " loss = 1./2 * tf.reduce_mean((y - y_pred)**2)\n", + "\n", + "opt = tf.train.AdamOptimizer(10.)\n", + "opt_operation = opt.minimize(loss)\n", + "####################end of building graph###########\n", + "animation_fram = []\n", + "################Run/fetch the graph#################\n", + "with tf.Session() as sess:\n", + " sess.run(tf.global_variables_initializer())\n", + " for _ in xrange(500):\n", + " _, loss_val = sess.run([opt_operation, loss], feed_dict={X: X_data, y: y_data})\n", + " predict = sess.run(y_pred, feed_dict={X: X_test})\n", + " animation_fram.append((X_test, predict, loss_val))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Visualizing the fitting process" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\nLHCY2WPAQOAgM1tL8FS2cUAz4CUzA3jb3S919yVm9gSwlKAJ6zJ3352ovImIZLK+E15m47adEWmJ\nrmWEy+gnAKqPQ0RyyeYdu+h180sRafN+NYg2Lfeq13nMbJG792loPvTMcRGRDFDR+R0umbWMcAoc\nIiJp7JUPP+eiyZEtKyt/N4wmeZaiHClwiIikraq1jGM6teLxUT9MUW6+o8AhIpJmiv76Nm+s+CIi\nLVXNUtEocIiIpIloQ2yvGdyVy07onKIcRafAISKSBtKp87s2Wfs8ji+++IJevXrRq1cv2rZtS35+\nfuX2sccem7DrlpaW8uijjybs/HWxZs0aWrRowe23316ZNnXqVHr06EG3bt249tprK9NXr17NoEGD\n6NGjBwMHDmTt2rUR5xo6dChr165l5MiRdOzYsfIzXLx4MRD8hXTFFVfQuXNnevTowTvvvFP53hde\neIGuXbvSuXNnJk6cmOBSi2SmL7bvrBY0nh99XNoGDSD4j5+pr969e3td3HDDDX7bbbfV6djGmjNn\njg8fPjwp14rlrLPO8rPPPruyzJs2bfL27dv7hg0b3N39/PPP95dfftnd3c8++2yfPHmyu7vPnj3b\nf/rTn1aeZ8eOHd63b193d7/gggv8ySefrHatGTNm+JAhQ7y8vNzfeust79evn7u7l5WVeadOnXzl\nypW+c+dO79Gjhy9ZsiRxhRbJQAXXPlftlQzAQm/EvTdraxw1adGiBQBz587l+OOP5/TTT6dTp04U\nFxczZcoU+vXrR/fu3Vm5ciUAGzdu5KyzzqJv37707duXN954A4BXX3218i/wI488km3btlFcXMzr\nr79Or169uOOOO9i9ezfXXHMNffv2pUePHtx///2V1x4wYADDhw+na9euXHrppZSXlze6bNOnT6dj\nx45069atMu3jjz+mS5cutG4dLIZ50kknMW3aNACWLl3KiSeeCMAJJ5zAM888U/m+uXPnMnDgwBqv\n98wzz3D++edjZhxzzDFs3ryZ9evXM3/+fDp37kynTp3Yc889GTFiRMS5RXLZS0s/r1bL+Oi3Q9O7\nlhEmJwNHuHfffZf77ruPDz74gIcffpiPPvqI+fPnc8kllzBp0iQARo8ezZgxY1iwYAHTpk3jkksu\nAeD222/n7rvvZvHixbz++uvsvffeTJw4keOOO47FixczZswY/va3v7HffvuxYMECFixYwF/+8hdW\nrVoFwPz585k0aRJLly5l5cqV/P3vf6+WvzFjxlQGp/BXtKaf7du3c+utt3LDDTdEpHfu3Jlly5ZR\nWlpKWVkZ06dP55NPPgGgZ8+eldd9+umn2bZtG198EYzmeP755xky5LtncY0bN44ePXowZswYdu4M\nljtYt24d7dt/tz7loYceyrp162Kmi+S6wuIZ/Oz/vpuX0STPKJ04nD2bZs7tOOc7x/v27Uu7dsFC\nxIcddhinnHIKAN27d2fOnDkAvPzyyyxdurTyPVu3bmX79u3079+fq666iqKiIs4880wOPfTQauef\nNWsW7733Hk899RQAW7ZsYfny5ey5557069ePTp06AfCTn/yEf/7zn5x99tkR77/jjjvqXJYbb7yR\nMWPGVNaoKhxwwAHce++9nHvuueTl5XHsscdW1qZuv/12Lr/8ciZPnsyAAQPIz8+nSZPg4YtvvPFG\nZT/JLbfcQtu2bdm1axejRo3i1ltv5frrr69z3kRy3aUPL+KFJZ9FpGVKDaOqnA8czZo1q/x3Xl5e\n5XZeXh5lZcHDCsvLy3n77bfZa6/I9WCKi4sZPnw4M2fOpH///rz44ovVzu/uTJo0icGDIx+jPnfu\nXEILPVaqug1BjaMigIUbMWIExcXFEWnz5s3jqaeeYuzYsWzevJm8vDz22msvLr/8ck477TROO+00\nAEpKSiqDwyGHHFJZ49i+fTvTpk1j//335+OPP6Z9+/bsueeeAJXBtVmzZlx44YWVASU/P7+y9gKw\ndu1a8vPz+fbbb6Omi+Siqs1SPx94GGOHZO5D6HI+cNTFKaecwqRJk7jmmmsAWLx4Mb169WLlypV0\n796d7t27s2DBAj788EPat2/Ptm3bKt87ePBg7r33Xk488UT22GMPPvroo8ob6Pz581m1ahUFBQVM\nnTqVUaNGVbt2fWocr7/+euW/b7zxRlq0aMHll18OwIYNGzj44IP56quvuOeee3jiiScA2LRpE61a\ntSIvL49bbrmFiy66CKjeTLV+/XratWuHuzN9+nSOOOIIAH70ox/x5z//mREjRjBv3jz2228/2rVr\nR+vWrVm+fDmrVq0iPz+fxx9/POWjzUSSLZOG2NaHAkcd/OlPf+Kyyy6jR48elJWVMWDAAO677z7u\nvPNO5syZQ15eHt26dWPo0KHk5eXRpEkTevbsyciRIxk9ejSlpaUcddRRuDutW7dm+vTpQNBMdvnl\nl7NixQpOOOEEfvzjHyesDKNHj+bdd98F4Prrr+d73/seENR8xo0bh5kxYMAA7r77biAYSlvRxwNQ\nVFTExo0bcXd69erFfffdB8CwYcOYOXMmnTt3pnnz5jz44IMANG3alD//+c8MHjyY3bt3c9FFF0V0\n2Itks6++3sWRv4lcxXb6Zf3p1X7/FOUovrSseorMnTuX22+/neeeey7VWalm586d9O/fn0z9bEVS\nKRNqGVpWXeKuWbNmChoi9fTiks/4fw8vikhbevNgmu+ZfbfZ7CtRhhg4cGCtcyREJDNkQi0jnjJn\n4HADVB2WmmpbtmzhtNNOo2fPnnTr1q2yP2DZsmURczRatmzJnXfeGfM8CxYsoGnTppVDfCvs3r2b\nI488klNPPbUybfHixRxzzDH06tWLPn36MH++HuUuEi8XPDC/WtAonTg8q4MGqMaRVHfffTeHH344\n//jHP9i4cSNdu3alqKiIrl27Vq79tHv3bvLz82N2lO/evZtrr722cr5JuLvuuosf/OAHbN26tTJt\n7Nix3HDDDQwdOpSZM2cyduxY5s6dm5DyieSSqgFjSLe23Hde7xTlJrmyusYRTWlpKSeeeCI9evRg\n0KBBrFmzBoAnn3ySI444gp49ezJgwAAAlixZQr9+/ejVqxc9evRg+fLljbq2mbFt2zbcne3bt9Oq\nVSuaNo2M3bNnz+awww6joKAg6jkmTZrEWWedxcEHHxyRvnbtWmbMmFE5qz38mhWBZMuWLRxyyCGN\nKoNIrissnhG1lpErQQNysMbxi1/8ggsuuIALLriABx54gCuuuILp06dz88038+KLL5Kfn8/mzZsB\nuO+++xg9ejRFRUXs2rWL3bt3Vzvfueeey7Jly6qlX3XVVZx//vkRaZdffjk/+tGPOOSQQ9i2bRtT\np04lLy8ydj/++OP85Cc/iZr3devW8fTTTzNnzhwWLFgQse/KK6/k97//fcQcEoA777yTwYMHc/XV\nV1NeXs6bb75Z+4ckItVs+eZbet40KyLt3qKjGNq9XYpylDo5FzjeeuutypnS5513HmPHjgWgf//+\njBw5knPOOYczzzwTgB/+8IdMmDCBtWvXcuaZZ9KlS5dq55s6dWqdr/3iiy/Sq1cvXnnlFVauXMnJ\nJ5/McccdR8uWLQHYtWsXzz77LLfcckvU91955ZXceuut1YLNc889x8EHH0zv3r2rNUPde++93HHH\n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\nROrl/wMEumU5M4Yc1AAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "f, ax = plt.subplots(figsize=(6,4))\n", + "f.suptitle('Linear Regression Example', fontsize=15)\n", + "plt.ylabel('Y')\n", + "plt.xlabel('X')\n", + "ax.set_xlim(0, 120)\n", + "ax.set_ylim(0, 120)\n", + "\n", + "line_d, = ax.plot([], [], label='fit_line')\n", + "dots, = ax.plot([], [], 'bo', label='actual_dots')\n", + "\n", + "frame_text = ax.text(0.02, 0.95,'',horizontalalignment='left',verticalalignment='top', transform=ax.transAxes)\n", + "# ax.legend()\n", + "\n", + "def init():\n", + " line_d.set_data([],[])\n", + " dots.set_data([],[])\n", + " return (line_d,) + (dots,)\n", + "\n", + "def animate(i):\n", + " \n", + " line_d.set_data(animation_fram[i][0], animation_fram[i][1])\n", + "\n", + " dots.set_data(X_data, y_data)\n", + " frame_text.set_text('Timestep = %.1d/%.1d\\nLoss = %.3f' % (i, len(animation_fram), animation_fram[i][2]))\n", + " \n", + " return (line_d,) + (dots,)\n", + "\n", + "anim = animation.FuncAnimation(f, animate, init_func=init,\n", + " frames=len(animation_fram), interval=30, blit=True)\n", + "\n", + "HTML(anim.to_html5_video())\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import tensorflow as tf" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "opt = tf.train.GradientDescentOptimizer(0.01)\n", + "train_op = opt.minimize(loss)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "$$\\theta-\\lambda*\\Delta\\theta$$" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "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.11" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/Logistic_regression.ipynb b/Logistic_regression.ipynb new file mode 100644 index 0000000..056621d --- /dev/null +++ b/Logistic_regression.ipynb @@ -0,0 +1,2097 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Logistic Regression Example" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Make datasets and test set\n", + "#### '+' points are sampled from a gaussian distribution (X, Y) ~ N(3, 6, 1, 1, 0).
'o' points are sampled from a gaussian distribution (X, Y) ~ N(6, 3, 1, 1, 0)
make sure the shape of the data matrix with which you feed to the tensor correspond to the shape of the tensor" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/jerrik/anaconda2/lib/python2.7/site-packages/matplotlib/font_manager.py:273: UserWarning: Matplotlib is building the font cache using fc-list. This may take a moment.\n", + " warnings.warn('Matplotlib is building the font cache using fc-list. This may take a moment.')\n" + ] + }, + { + "data": { + "image/png": "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\nQGnFAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import tensorflow as tf\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from matplotlib import animation, rc\n", + "from IPython.display import HTML\n", + "import matplotlib.cm as cm\n", + "import numpy as np\n", + "%matplotlib inline\n", + "\n", + "dot_num = 100\n", + "x_p = np.random.normal(3., 1, dot_num)\n", + "y_p = np.random.normal(6., 1, dot_num)\n", + "y = np.ones(dot_num)\n", + "C1 = np.array([x_p, y_p, y]).T\n", + "\n", + "x_n = np.random.normal(6., 1, dot_num)\n", + "y_n = np.random.normal(3., 1, dot_num)\n", + "y = np.zeros(dot_num)\n", + "C2 = np.array([x_n, y_n, y]).T\n", + "\n", + "plt.scatter(C1[:, 0], C1[:, 1], c='b', marker='+')\n", + "plt.scatter(C2[:, 0], C2[:, 1], c='g', marker='o')\n", + "\n", + "data_set = np.concatenate((C1, C2), axis=0)\n", + "np.random.shuffle(data_set)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Creating the graph and run it\n", + "#### In Graph building stage, python call tensorflow api to create Tensorflow Nodes and connect those Nodes. (at this moment the graph is static)
Note that in tensorflow Graph, Nodes are called Operations and Edges connect those Nodes are called tensors \n", + "#### A fetch on a tensor would require its preceeding Node to activate, for a Node to activate would require all it's inbound tensors/Edges to be filled with data, recursively all the way to the leaf Nodes (placeholder, variable, constant)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "################Graph building stage################\n", + "# Define placeholders for input\n", + "X = tf.placeholder(tf.float32, shape=(None, 2))\n", + "y = tf.placeholder(tf.float32, shape=(None, 1))\n", + "\n", + "# Define variables to be learned\n", + "with tf.variable_scope(\"Logistic_regression\"):\n", + " W = tf.Variable(np.random.rand(2, 1), 'weight', dtype=tf.float32)\n", + " b = tf.Variable(np.random.rand(1, 1), 'bias', dtype=tf.float32)\n", + " \n", + " logits = tf.matmul(X, W) + b\n", + " pred = tf.sigmoid(logits)\n", + " loss = tf.nn.sigmoid_cross_entropy_with_logits(logits, y)\n", + " loss = tf.reduce_mean(loss)\n", + "\n", + "opt = tf.train.AdamOptimizer(0.01)\n", + "opt_operation = opt.minimize(loss)\n", + "####################end of building graph###########\n", + "animation_fram = []\n", + "\n", + "################Run/fetch the graph#################\n", + "with tf.Session() as sess: ##initialize a graph\n", + " sess.run(tf.initialize_all_variables())\n", + " for _ in xrange(500):\n", + " _, loss_val = sess.run([opt_operation, loss], \n", + " feed_dict={X: data_set[:, :2],\n", + " y: data_set[:, 2].reshape((-1, 1))})\n", + " W_opt, b_opt = sess.run([W, b])\n", + " animation_fram.append((W_opt[0, 0], W_opt[1, 0], b_opt, loss_val))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Visualizing the fitting process" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "f, ax = plt.subplots(figsize=(6,4))\n", + "f.suptitle('Logistic Regression Example', fontsize=15)\n", + "plt.ylabel('Y')\n", + "plt.xlabel('X')\n", + "ax.set_xlim(0, 10)\n", + "ax.set_ylim(0, 10)\n", + "\n", + "line_d, = ax.plot([], [], label='fit_line')\n", + "C1_dots, = ax.plot([], [], '+', c='b', label='actual_dots')\n", + "C2_dots, = ax.plot([], [], 'o', c='g' ,label='actual_dots')\n", + "\n", + "\n", + "frame_text = ax.text(0.02, 0.95,'',horizontalalignment='left',verticalalignment='top', transform=ax.transAxes)\n", + "# ax.legend()\n", + "\n", + "def init():\n", + " line_d.set_data([],[])\n", + " C1_dots.set_data([],[])\n", + " C2_dots.set_data([],[])\n", + " return (line_d,) + (C1_dots,) + (C2_dots,)\n", + "\n", + "def animate(i):\n", + " xx = np.arange(10, step=0.1)\n", + " a = animation_fram[i][0]\n", + " b = animation_fram[i][1]\n", + " c = animation_fram[i][2]\n", + " yy = a/-b * xx +c/-b\n", + " line_d.set_data(xx, yy)\n", + " \n", + " C1_dots.set_data(C1[:, 0], C1[:, 1])\n", + " C2_dots.set_data(C2[:, 0], C2[:, 1])\n", + " \n", + " frame_text.set_text('Timestep = %.1d/%.1d\\nLoss = %.3f' % (i, len(animation_fram), animation_fram[i][3]))\n", + " \n", + " return (line_d,) + (C1_dots,) + (C2_dots,)\n", + "\n", + "anim = animation.FuncAnimation(f, animate, init_func=init,\n", + " frames=len(animation_fram), interval=30, blit=True)\n", + "\n", + "HTML(anim.to_html5_video())\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "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.13" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/cips_tfTutorial.ipynb b/cips_tfTutorial.ipynb new file mode 100644 index 0000000..35335f9 --- /dev/null +++ b/cips_tfTutorial.ipynb @@ -0,0 +1,388 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "30.0\n", + "10.0 3.0\n", + "10.0 10.0\n", + "3.0 3.0\n" + ] + } + ], + "source": [ + "def add(a, b):\n", + " return a+b\n", + "\n", + "def grad_add(grad, a, b):\n", + " return grad, grad\n", + "\n", + "def mul(a, b):\n", + " return a*b\n", + "\n", + "def grad_mul(grad, a, b):\n", + " return grad*b, grad*a\n", + "\n", + "input1, input2, input3, input4 = (1., 2., 6., 4.)\n", + "\n", + "'''inference'''\n", + "dummy1 = add(input1, input2)\n", + "dummy2 = add(input3, input4)\n", + "dummy3 = mul(dummy1, dummy2)\n", + "\n", + "'''caculate gradient'''\n", + "grad3_dummy1, grad3_dummy2 = grad_mul(1, dummy1, dummy2)\n", + "grad2_a, grad2_b = grad_add(grad3_dummy1, input1, input2)\n", + "grad1_a, grad1_b = grad_add(grad3_dummy2, input3, input4)\n", + "\n", + "'''output'''\n", + "print dummy3\n", + "print grad3_dummy1, grad3_dummy2\n", + "print grad2_a, grad2_b\n", + "print grad1_a, grad1_b\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[10.0] [10.0]\n", + "[3.0] [3.0]\n" + ] + } + ], + "source": [ + "import tensorflow as tf\n", + "\n", + "input1 = tf.placeholder(shape=None, dtype=tf.float32, \n", + " name='input1')\n", + "input2 = tf.placeholder(shape=None, dtype=tf.float32, \n", + " name='input2')\n", + "input3 = tf.placeholder(shape=None, dtype=tf.float32, \n", + " name='input3')\n", + "input4 = tf.placeholder(shape=None, dtype=tf.float32, \n", + " name='input4')\n", + "\n", + "'''inference'''\n", + "dummy3 = (input1+input2)*(input3+input4)\n", + "\n", + "'''caculate gradient'''\n", + "input1_grad, input2_grad, input3_grad, input4_grad =(\n", + " tf.gradients(dummy3, input1),\n", + " tf.gradients(dummy3, input2),\n", + " tf.gradients(dummy3, input3),\n", + " tf.gradients(dummy3, input4)\n", + ")\n", + "\n", + "tf.summary.scalar('accuracy', 1.0)\n", + "merged = tf.summary.merge_all()\n", + "\n", + "with tf.Session() as sess:\n", + " train_writer = tf.summary.FileWriter('./stuff',graph=sess.graph)\n", + " sess.run(merged)\n", + " (in_1_grad, in_2_grad, in_3_grad, in_4_grad\n", + " ) = sess.run([input1_grad, input2_grad, \n", + " input3_grad, input4_grad], \n", + " feed_dict={input1:1., input2:2., \n", + " input3:6., input4:4.})\n", + " print in_1_grad, in_2_grad\n", + " print in_3_grad, in_4_grad" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Tensor(\"foo/w/read:0\", shape=(1,), dtype=float32)\n", + "Tensor(\"foo/v/read:0\", shape=(1,), dtype=float32)\n", + "Tensor(\"foo/v/read:0\", shape=(1,), dtype=float32)\n" + ] + } + ], + "source": [ + "import tensorflow as tf\n", + "with tf.variable_scope(\"foo\"):\n", + " v = tf.get_variable(\"v\", [1]) # v.name == \"foo/v:0\"\n", + " w = tf.get_variable(\"w\", [1]) # w.name == \"foo/w:0\"\n", + "with tf.variable_scope(\"foo\", reuse=True):\n", + " v1 = tf.get_variable(\"v\") # The same as v above.\n", + "\n", + "print w\n", + "print v\n", + "print v1" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Tensor(\"foo/w/read:0\", shape=(1,), dtype=float32)\n", + "Tensor(\"foo/v/read:0\", shape=(1,), dtype=float32)\n", + "Tensor(\"foo/v/read:0\", shape=(1,), dtype=float32)\n" + ] + } + ], + "source": [ + "import tensorflow as tf\n", + "with tf.variable_scope(\"foo\") as scope:\n", + " v = tf.get_variable(\"v\", [1]) # v.name == \"foo/v:0\"\n", + " w = tf.get_variable(\"w\", [1]) # w.name == \"foo/w:0\"\n", + " scope.reuse_variables()\n", + " v1 = tf.get_variable(\"v\") # The same as v above.\n", + "\n", + "print w\n", + "print v\n", + "print v1" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "foo/dummy/v:0\n", + "foo/v2:0\n" + ] + } + ], + "source": [ + "import tensorflow as tf\n", + "\n", + "with tf.variable_scope('foo'):\n", + " with tf.variable_scope('dummy') as sp:\n", + " v = tf.get_variable('v', shape=[1, 2])\n", + " v2 = tf.get_variable('v2', shape=[1, 1])\n", + "\n", + "print v.name\n", + "print v2.name\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "foo/dummy/v:0\n", + "foo/dummy/v:0\n", + "foo/v3:0\n", + "[u'foo/v3:0']\n", + "[u'foo/dummy/v:0']\n", + "[array([1, 2], dtype=int32), array([1, 2], dtype=int32)]\n" + ] + } + ], + "source": [ + "import tensorflow as tf\n", + "\n", + "with tf.variable_scope('foo'):\n", + " with tf.variable_scope('dummy') as sp:\n", + " v = tf.get_variable('v', initializer=[1, 2])\n", + " sp.reuse_variables()\n", + " v2 = tf.get_variable('v', initializer=[4, 5], dtype=tf.int32)\n", + " v3 = tf.get_variable('v3', [1, 1])\n", + " \n", + "foo_var_list = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope='foo/v3')\n", + "dummy_var_list = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope='foo/dummy')\n", + "\n", + "print v.name\n", + "print v2.name\n", + "print v3.name\n", + "\n", + "print [o.name for o in foo_var_list]\n", + "print [o.name for o in dummy_var_list]\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(tf.global_variables_initializer())\n", + " print sess.run([v, v2])" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[array([[ 2., 3.]], dtype=float32), array([[ 6.25, 7.25]], dtype=float32)]\n" + ] + } + ], + "source": [ + "import tensorflow as tf\n", + "\n", + "with tf.variable_scope('foo'):\n", + " with tf.variable_scope('dummy') as sp:\n", + " v = tf.get_variable('v', initializer=[[2., 3.]])\n", + " \n", + "dummy_var_list = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope='foo/dummy/v')\n", + "dummy_var = dummy_var_list[0]\n", + "dummy_add = dummy_var+4.25\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(tf.global_variables_initializer())\n", + " print sess.run([v, dummy_add])" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Tensor(\"Const_7:0\", shape=(), dtype=float32) Tensor(\"Const_8:0\", shape=(), dtype=float32)\n", + "[u'foo/dummy/v:0', u'foo/v3:0']\n", + "[u'foo/v3:0']\n" + ] + } + ], + "source": [ + "c1 = tf.constant(1.)\n", + "c2 = tf.constant(2.)\n", + "print c1, c2\n", + "print [o.name for o in tf.global_variables()]\n", + "print [o.name for o in tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='foo/v3')]" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 0.12619646]\n", + "[ 0.12619646]\n", + "[ 0.12619646]\n", + "[ 0.12619646]\n", + "[ 0.12619646]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "aa = np.random.rand(1)\n", + "\n", + "for i in range(5):\n", + " print aa\n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 0. 0.]\n", + " [ 0. 0.]]\n", + "\n", + "[[ 1. 1. 1.]\n", + " [ 1. 1. 1.]\n", + " [ 1. 1. 1.]]\n" + ] + } + ], + "source": [ + "import tensorflow as tf\n", + "choice = tf.placeholder(shape=[], dtype=tf.bool)\n", + "out = tf.cond(choice, lambda: tf.zeros([2, 2]), \n", + " lambda: tf.ones([3, 3]))\n", + "with tf.Session() as sess:\n", + " print sess.run(out, feed_dict={choice: True})\n", + " print \n", + " print sess.run(out, feed_dict={choice: False})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "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.11" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tf_tutorial.ipynb b/tf_tutorial.ipynb new file mode 100644 index 0000000..afb8f99 --- /dev/null +++ b/tf_tutorial.ipynb @@ -0,0 +1,249 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1.0, 2.0, 3.0]\n", + "3.0\n" + ] + } + ], + "source": [ + "import tensorflow as tf\n", + "import numpy as np\n", + "\n", + "a = tf.constant(1., name='const1') #const1 is the name in tensorflow domain, while 'a' is a name in python domain\n", + " #'a' is a refference of a tensor object that tf.constant() return, 'a' don't hold \n", + " #object, so you can always change a's refference to another tensor object\n", + "b = tf.constant(2., name='const2')\n", + "c = tf.add(a, b)\n", + "\n", + "with tf.Session() as sess:\n", + " print sess.run([a, b, c])\n", + " print c.eval()" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3.0\n" + ] + } + ], + "source": [ + "import tensorflow as tf\n", + "import numpy as np\n", + "\"\"\"\n", + "Instead of using tf.add, tf.sub, tf.mul, tf.div, etc. we can use +, -, *, / \n", + "and few other Arithmetic operators director, note that those expressions don't evaluate to a actual value, but a tensor\n", + "Tensorflow have some sort of Operator overriding mechanism that make + have the same effect as tf.add\n", + "\"\"\"\n", + "a = tf.constant(1., name='const1') + tf.constant(2., name='const2') \n", + " \n", + "with tf.Session() as sess:\n", + " print sess.run(a)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-0.39539278]\n", + "[-0.79538769]\n", + "[-0.94243872]\n", + "[-1.35026503]\n", + "[-1.49993551]\n" + ] + } + ], + "source": [ + "# consider tf.random_normal as a random number generator\n", + "#show that the value in tensor is not determined in \n", + "#graph constructing stage,but in running stage\n", + "import tensorflow as tf\n", + "import numpy as np\n", + "\n", + "a = tf.random_normal([1], name='random')\n", + "with tf.Session() as sess:\n", + " for i in range(5):\n", + " print sess.run(a)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "var: 0.0 1.0 4.0\n", + "var: 2.0 3.0 8.0\n", + "var: 4.0 5.0 12.0\n", + "var: 6.0 [7.0, 14.0]\n", + "var: 7.0 [8.0, 16.0]\n", + "var: 8.0 [9.0, 18.0]\n" + ] + } + ], + "source": [ + "#Assign example\n", + "import tensorflow as tf\n", + "import numpy as np\n", + "\n", + "var = tf.Variable(0., name='var')\n", + "const = tf.constant(1.)\n", + "add_op = tf.add(var, const, name='myAdd') # tmp = var + const\n", + "\n", + "#return a tensor, and have a side effect, that is assign add_op to var\n", + "assign_op = tf.assign(var, add_op, name='myAssign') \n", + "\n", + "out1 = assign_op*1\n", + "out2 = assign_op*2\n", + "\n", + "with tf.Session() as sess:\n", + " train_writer = tf.summary.FileWriter('./stuff',graph=sess.graph)\n", + " sess.run(tf.global_variables_initializer())\n", + " for i in range(3):\n", + " print \"var:\", sess.run(var), sess.run(out1), sess.run(out2)\n", + " \n", + " for i in range(3):\n", + " print \"var:\", sess.run(var), sess.run([out1, out2])\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[] \n", + "[array([ 0., 4., 8.], dtype=float32)]\n", + "[array([ 3.75720215, 2.32265329, 3.79678249], dtype=float32)]\n", + "[array([ 4., 8., 12.], dtype=float32)]\n", + "[array([ 3.75720215, 2.32265329, 3.79678249], dtype=float32)]\n", + "[array([ 8., 12., 16.], dtype=float32)]\n", + "[array([ 3.75720215, 2.32265329, 3.79678249], dtype=float32)]\n", + "[array([ 12., 16., 20.], dtype=float32)]\n", + "[array([ 3.75720215, 2.32265329, 3.79678249], dtype=float32)]\n", + "[array([ 16., 20., 24.], dtype=float32)]\n", + "[array([ 3.75720215, 2.32265329, 3.79678249], dtype=float32)]\n", + "[array([ 20., 24., 28.], dtype=float32)]\n", + "[array([ 3.75720215, 2.32265329, 3.79678249], dtype=float32)]\n", + "[array([ 24., 28., 32.], dtype=float32)]\n", + "[array([ 3.75720215, 2.32265329, 3.79678249], dtype=float32)]\n", + "[array([ 28., 32., 36.], dtype=float32)]\n", + "[array([ 3.75720215, 2.32265329, 3.79678249], dtype=float32)]\n", + "[array([ 32., 36., 40.], dtype=float32)]\n", + "[array([ 3.75720215, 2.32265329, 3.79678249], dtype=float32)]\n", + "[array([ 36., 40., 44.], dtype=float32)]\n", + "[array([ 3.75720215, 2.32265329, 3.79678249], dtype=float32)]\n" + ] + } + ], + "source": [ + "#Gradient Computing demo\n", + "import tensorflow as tf\n", + "import numpy as np\n", + "\n", + "a = tf.Variable(np.float32(np.random.rand(3)), 'a')\n", + "b = tf.add(tf.multiply(2., tf.pow(a, 2)), 3) # 2 * x^2 + 3\n", + "# b = 2 * a**2 + 3\n", + "\n", + "grad = tf.gradients(b, a)\n", + "print grad, type(grad)\n", + "with tf.Session() as sess:\n", + " sess.run(tf.global_variables_initializer())\n", + " for i in range(10):\n", + "# feed_dict = {a : np.float32(np.random.rand(3))}\n", + " feed_dict = {a : [i, i+1, i+2]}\n", + " print sess.run(grad, feed_dict=feed_dict)\n", + " print sess.run(grad)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 0.03614243]\n", + "####################\n", + "[-1.28610408]\n", + "####################\n", + "[ 1.40038896]\n", + "####################\n" + ] + } + ], + "source": [ + "import tensorflow as tf\n", + "import numpy as np\n", + "\n", + "aa = tf.random_normal([1])\n", + "# bb = tf.constant(aa) #Wrong Wrong Wrong\n", + "with tf.Session() as sess:\n", + " for i in range(3):\n", + " print sess.run(aa)\n", + " print '#'*20" + ] + } + ], + "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.11" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +}