├── Chapter01 └── Least squares example.ipynb ├── Chapter02 ├── Comparing accuracy for training and test sets.ipynb ├── MNIST dataset sample.ipynb ├── MNIST softmax estimation.ipynb └── Maximum likelihood estimation example.ipynb ├── Chapter03 ├── Double layer network example.ipynb ├── MNIST single layer network with TensorBoard.ipynb ├── MNIST single layer network.ipynb └── Single layer network example.ipynb ├── Chapter04 ├── MNIST dynamic filter classification with TensorBoard.ipynb ├── MNIST dynamic filter classification.ipynb ├── MNIST dynamic filter result.ipynb ├── ORENIST classification example.ipynb ├── ORENIST dynamic filter example.ipynb ├── ORENIST filter example.ipynb └── ORENIST.data ├── Chapter05 ├── CIFAR-10 dataset samples.ipynb ├── Handwriting recognizer.ipynb └── MNIST double layer CNN classification.ipynb ├── README.md └── 텐서플로 최신 버전 지원 가이드.pdf /Chapter01/Least squares example.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "**[LSE-01]** 모듈을 임포트 한다." 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import tensorflow as tf\n", 19 | "import numpy as np\n", 20 | "import matplotlib.pyplot as plt" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "**[LSE-02]** Placeholder x를 정의한다." 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 2, 33 | "metadata": { 34 | "collapsed": true 35 | }, 36 | "outputs": [], 37 | "source": [ 38 | "x = tf.placeholder(tf.float32, [None, 5])" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": {}, 44 | "source": [ 45 | "**[LSE-03]** Variable w를 정의한다." 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 3, 51 | "metadata": { 52 | "collapsed": true 53 | }, 54 | "outputs": [], 55 | "source": [ 56 | "w = tf.Variable(tf.zeros([5, 1]))" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "**[LSE-04]** 계산식 y를 정의한다." 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 4, 69 | "metadata": { 70 | "collapsed": true 71 | }, 72 | "outputs": [], 73 | "source": [ 74 | "y = tf.matmul(x, w)" 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "metadata": {}, 80 | "source": [ 81 | "**[LSE-05]** Placeholder t를 정의한다." 82 | ] 83 | }, 84 | { 85 | "cell_type": "code", 86 | "execution_count": 5, 87 | "metadata": { 88 | "collapsed": true 89 | }, 90 | "outputs": [], 91 | "source": [ 92 | "t = tf.placeholder(tf.float32, [None, 1])" 93 | ] 94 | }, 95 | { 96 | "cell_type": "markdown", 97 | "metadata": {}, 98 | "source": [ 99 | "**[LSE-06]** 오차 함수 loss를 정의한다." 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": 6, 105 | "metadata": { 106 | "collapsed": false 107 | }, 108 | "outputs": [], 109 | "source": [ 110 | "loss = tf.reduce_sum(tf.square(y-t))" 111 | ] 112 | }, 113 | { 114 | "cell_type": "markdown", 115 | "metadata": {}, 116 | "source": [ 117 | "**[LSE-07]** 트레이닝 알고리즘 train_step을 정의한다." 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 7, 123 | "metadata": { 124 | "collapsed": true 125 | }, 126 | "outputs": [], 127 | "source": [ 128 | "train_step = tf.train.AdamOptimizer().minimize(loss)" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": {}, 134 | "source": [ 135 | "**[LSE-08]** 세션을 준비하고 Variable을 초기화한다." 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": 8, 141 | "metadata": { 142 | "collapsed": true 143 | }, 144 | "outputs": [], 145 | "source": [ 146 | "sess = tf.Session()\n", 147 | "sess.run(tf.initialize_all_variables())" 148 | ] 149 | }, 150 | { 151 | "cell_type": "markdown", 152 | "metadata": {}, 153 | "source": [ 154 | "**[LSE-09]** 트레이닝 세트 데이터를 준비한다." 155 | ] 156 | }, 157 | { 158 | "cell_type": "code", 159 | "execution_count": 9, 160 | "metadata": { 161 | "collapsed": false 162 | }, 163 | "outputs": [], 164 | "source": [ 165 | "train_t = np.array([5.2, 5.7, 8.6, 14.9, 18.2, 20.4,\n", 166 | " 25.5, 26.4, 22.8, 17.5, 11.1, 6.6])\n", 167 | "train_t = train_t.reshape([12,1])\n", 168 | "\n", 169 | "train_x = np.zeros([12, 5])\n", 170 | "for row, month in enumerate(range(1, 13)):\n", 171 | " for col, n in enumerate(range(0, 5)):\n", 172 | " train_x[row][col] = month**n" 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "metadata": {}, 178 | "source": [ 179 | "**[LSE-10]** 경사 하강법을 이용한 파라미터 최적화를 100000회 반복한다." 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": 10, 185 | "metadata": { 186 | "collapsed": false 187 | }, 188 | "outputs": [ 189 | { 190 | "name": "stdout", 191 | "output_type": "stream", 192 | "text": [ 193 | "Step: 10000, Loss: 31.014391\n", 194 | "Step: 20000, Loss: 29.295158\n", 195 | "Step: 30000, Loss: 28.033054\n", 196 | "Step: 40000, Loss: 26.855808\n", 197 | "Step: 50000, Loss: 25.771938\n", 198 | "Step: 60000, Loss: 26.711918\n", 199 | "Step: 70000, Loss: 24.436256\n", 200 | "Step: 80000, Loss: 22.975143\n", 201 | "Step: 90000, Loss: 22.194229\n", 202 | "Step: 100000, Loss: 21.434664\n" 203 | ] 204 | } 205 | ], 206 | "source": [ 207 | "i = 0\n", 208 | "for _ in range(100000):\n", 209 | " i += 1\n", 210 | " sess.run(train_step, feed_dict={x:train_x, t:train_t})\n", 211 | " if i % 10000 == 0:\n", 212 | " loss_val = sess.run(loss, feed_dict={x:train_x, t:train_t})\n", 213 | " print ('Step: %d, Loss: %f' % (i, loss_val))" 214 | ] 215 | }, 216 | { 217 | "cell_type": "markdown", 218 | "metadata": {}, 219 | "source": [ 220 | "**[LSE-11]** 다시 100000회 반복한다." 221 | ] 222 | }, 223 | { 224 | "cell_type": "code", 225 | "execution_count": 11, 226 | "metadata": { 227 | "collapsed": false 228 | }, 229 | "outputs": [ 230 | { 231 | "name": "stdout", 232 | "output_type": "stream", 233 | "text": [ 234 | "Step: 110000, Loss: 20.749628\n", 235 | "Step: 120000, Loss: 20.167929\n", 236 | "Step: 130000, Loss: 19.527676\n", 237 | "Step: 140000, Loss: 18.983555\n", 238 | "Step: 150000, Loss: 18.480526\n", 239 | "Step: 160000, Loss: 18.012512\n", 240 | "Step: 170000, Loss: 17.615368\n", 241 | "Step: 180000, Loss: 17.179623\n", 242 | "Step: 190000, Loss: 16.879869\n", 243 | "Step: 200000, Loss: 20.717033\n" 244 | ] 245 | } 246 | ], 247 | "source": [ 248 | "for _ in range(100000):\n", 249 | " i += 1\n", 250 | " sess.run(train_step, feed_dict={x:train_x, t:train_t})\n", 251 | " if i % 10000 == 0:\n", 252 | " loss_val = sess.run(loss, feed_dict={x:train_x, t:train_t})\n", 253 | " print ('Step: %d, Loss: %f' % (i, loss_val))" 254 | ] 255 | }, 256 | { 257 | "cell_type": "markdown", 258 | "metadata": {}, 259 | "source": [ 260 | "**[LSE-12]** 트레이닝 후 파라미터 값을 확인한다." 261 | ] 262 | }, 263 | { 264 | "cell_type": "code", 265 | "execution_count": 12, 266 | "metadata": { 267 | "collapsed": false 268 | }, 269 | "outputs": [ 270 | { 271 | "name": "stdout", 272 | "output_type": "stream", 273 | "text": [ 274 | "[[ 6.10566282]\n", 275 | " [-4.04159737]\n", 276 | " [ 2.51030278]\n", 277 | " [-0.2817387 ]\n", 278 | " [ 0.00828196]]\n" 279 | ] 280 | } 281 | ], 282 | "source": [ 283 | "w_val = sess.run(w)\n", 284 | "print w_val" 285 | ] 286 | }, 287 | { 288 | "cell_type": "markdown", 289 | "metadata": {}, 290 | "source": [ 291 | "**[LSE-13]** 트레이닝 후 파라미터를 이용해 예측기온을 계산하는 함수를 정의한다." 292 | ] 293 | }, 294 | { 295 | "cell_type": "code", 296 | "execution_count": 13, 297 | "metadata": { 298 | "collapsed": false 299 | }, 300 | "outputs": [], 301 | "source": [ 302 | "def predict(x):\n", 303 | " result = 0.0\n", 304 | " for n in range(0, 5):\n", 305 | " result += w_val[n][0] * x**n\n", 306 | " return result" 307 | ] 308 | }, 309 | { 310 | "cell_type": "markdown", 311 | "metadata": {}, 312 | "source": [ 313 | "**[LSE-14]** 예측기온 그래프를 그린다." 314 | ] 315 | }, 316 | { 317 | "cell_type": "code", 318 | "execution_count": 14, 319 | "metadata": { 320 | "collapsed": false 321 | }, 322 | "outputs": [ 323 | { 324 | "data": { 325 | "text/plain": [ 326 | "[]" 327 | ] 328 | }, 329 | "execution_count": 14, 330 | "metadata": {}, 331 | "output_type": "execute_result" 332 | }, 333 | { 334 | "data": { 335 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAEACAYAAACj0I2EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3X2c1WP+x/HXpxtMUcK4CzPsYhKhdZ+biULYWkIS6yas\nX6x+uVm3q2kl1u3a1JImujMbYatVJBolfpp0S2WjneSm6SC6Uc3UXL8/rhOVGXNm5pzzPed73s/H\n4zyc+c73nPM5mvnMdT7f67o+5pxDRETSX4OgAxARkfhQQhcRCQkldBGRkFBCFxEJCSV0EZGQUEIX\nEQmJGhO6me1oZu+b2Rwz+8jMBkSPtzCzyWb2sZm9bmbNEx+uiIhUx2KZh25mTZxzP5hZQ2AGcAvQ\nGfjGOfeQmd0OtHDO3ZHYcEVEpDoxlVyccz9E7+4YfcwqoAswPHp8OPC7uEcnIiIxiymhm1kDM5sD\nrACKnXMLgb2cc2UAzrkVwJ6JC1NERGrSKJaTnHOVwNFm1gx43czyge1rNdpDQEQkQDEl9C2cc6vN\nbCJwDFBmZns558rMbG9gZVWPMTMlehGROnDOWW3Oj2WWyx5bZrCYWRbQEZgDjAeujJ52BTDuF4JK\n+q1v376BvG6QN73nzLjpPWfGrS5iGaHvAww3M8P/ARjpnHszWlN/wcyuBpYBF9cpAhERiYsaE7pz\nbgHQtorj3wIdEhGUiIjUXmhXiubn5wcdQtLpPWcGvWepTkwLi+r1AmYu0a8hIhI2ZoaL90VRERFJ\nD0roIiIhoYQuIhISSugiIiGhhC4iEhJK6CIiIaGELiISEkroIiIhoYQuIhISSugiIiGhhC4iEhJK\n6CIiIaGELiISEkroIiIhoYQuIhISSugiIiGhhC4iEhJK6CJpJBKJUFJSQiQSCToUSUFK6CJpoqho\nDDk5eXTseD05OXkUFY0JOiRJMeopKpIGIpEIOTl5rF8/FWgDzCcrqz3Lli0mOzs76PAkAdRTVCSk\nSktL2WGHXHwyB2hD48Y5lJaWBheUpBwldJE0kJubS3l5KTA/emQ+FRXLyM3NDS4oSTlK6CJpIDs7\nm8LCwWRltadZs7ZkZbWnsHCwyi2yDdXQRdJIJBKhtLSU3NxcJfOQq0sNXQldpA6UWCXRdFFUJAk0\nfVBSVY0jdDPbDxgB7AVUAkOccwPNrC9wLbAyeupdzrnXqni8RugSGpo+KMlSlxF6oxjO2QTc7Jyb\n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\nTkSuQmCC\n", 336 | "text/plain": [ 337 | "" 338 | ] 339 | }, 340 | "metadata": {}, 341 | "output_type": "display_data" 342 | } 343 | ], 344 | "source": [ 345 | "fig = plt.figure()\n", 346 | "subplot = fig.add_subplot(1,1,1)\n", 347 | "subplot.set_xlim(1,12)\n", 348 | "subplot.scatter(range(1,13), train_t)\n", 349 | "linex = np.linspace(1,12,100)\n", 350 | "liney = predict(linex)\n", 351 | "subplot.plot(linex, liney)" 352 | ] 353 | } 354 | ], 355 | "metadata": { 356 | "kernelspec": { 357 | "display_name": "Python 2", 358 | "language": "python", 359 | "name": "python2" 360 | }, 361 | "language_info": { 362 | "codemirror_mode": { 363 | "name": "ipython", 364 | "version": 2 365 | }, 366 | "file_extension": ".py", 367 | "mimetype": "text/x-python", 368 | "name": "python", 369 | "nbconvert_exporter": "python", 370 | "pygments_lexer": "ipython2", 371 | "version": "2.7.5" 372 | } 373 | }, 374 | "nbformat": 4, 375 | "nbformat_minor": 0 376 | } 377 | -------------------------------------------------------------------------------- /Chapter02/Comparing accuracy for training and test sets.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "**[CAF-01]** 모듈을 임포트하고 난수의 시드를 설정한다." 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import tensorflow as tf\n", 19 | "import numpy as np\n", 20 | "import matplotlib.pyplot as plt\n", 21 | "from numpy.random import multivariate_normal, permutation\n", 22 | "import pandas as pd\n", 23 | "from pandas import DataFrame, Series\n", 24 | "\n", 25 | "np.random.seed(20160531)" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": {}, 31 | "source": [ 32 | "**[CAF-02]** 트레이닝 세트 데이터를 준비하고 20%의 데이터를 테스트 세트로 분리한다." 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 2, 38 | "metadata": { 39 | "collapsed": false 40 | }, 41 | "outputs": [], 42 | "source": [ 43 | "n0, mu0, variance0 = 800, [10, 11], 20\n", 44 | "data0 = multivariate_normal(mu0, np.eye(2)*variance0 ,n0)\n", 45 | "df0 = DataFrame(data0, columns=['x','y'])\n", 46 | "df0['t'] = 0\n", 47 | "\n", 48 | "n1, mu1, variance1 = 600, [18, 20], 22\n", 49 | "data1 = multivariate_normal(mu1, np.eye(2)*variance1 ,n1)\n", 50 | "df1 = DataFrame(data1, columns=['x','y'])\n", 51 | "df1['t'] = 1\n", 52 | "\n", 53 | "df = pd.concat([df0, df1], ignore_index=True)\n", 54 | "df = df.reindex(permutation(df.index)).reset_index(drop=True)\n", 55 | "\n", 56 | "num_data = int(len(df)*0.8)\n", 57 | "train_set = df[:num_data]\n", 58 | "test_set = df[num_data:]" 59 | ] 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "metadata": {}, 64 | "source": [ 65 | "**[CAF-03]** (x, y)와 t를 각각 모은 것을 NumPy의 array 오브젝트로 추출해둔다." 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 3, 71 | "metadata": { 72 | "collapsed": false 73 | }, 74 | "outputs": [], 75 | "source": [ 76 | "train_x = train_set[['x','y']].as_matrix()\n", 77 | "train_t = train_set['t'].as_matrix().reshape([len(train_set), 1])\n", 78 | "test_x = test_set[['x','y']].as_matrix()\n", 79 | "test_t = test_set['t'].as_matrix().reshape([len(test_set), 1])" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": {}, 85 | "source": [ 86 | "**[CAF-04]** 각종 계산식을 정의한다." 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 4, 92 | "metadata": { 93 | "collapsed": false 94 | }, 95 | "outputs": [], 96 | "source": [ 97 | "x = tf.placeholder(tf.float32, [None, 2])\n", 98 | "w = tf.Variable(tf.zeros([2, 1]))\n", 99 | "w0 = tf.Variable(tf.zeros([1]))\n", 100 | "f = tf.matmul(x, w) + w0\n", 101 | "p = tf.sigmoid(f)\n", 102 | "\n", 103 | "t = tf.placeholder(tf.float32, [None, 1])\n", 104 | "loss = -tf.reduce_sum(t*tf.log(p) + (1-t)*tf.log(1-p))\n", 105 | "train_step = tf.train.AdamOptimizer().minimize(loss)\n", 106 | "\n", 107 | "correct_prediction = tf.equal(tf.sign(p-0.5), tf.sign(t-0.5))\n", 108 | "accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))" 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": {}, 114 | "source": [ 115 | "**[CAF-05]** 세션을 준비하고 Variable을 초기화한다." 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 5, 121 | "metadata": { 122 | "collapsed": true 123 | }, 124 | "outputs": [], 125 | "source": [ 126 | "sess = tf.Session()\n", 127 | "sess.run(tf.initialize_all_variables())" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "metadata": {}, 133 | "source": [ 134 | "**[CAF-06]** 경사 하강법에 의한 파라미터 최적화를 2500회 반복하면서 트레이닝 세트와 테스트 세트에 대한 정답률 변화를 기록한다." 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": 6, 140 | "metadata": { 141 | "collapsed": false 142 | }, 143 | "outputs": [], 144 | "source": [ 145 | "train_accuracy = []\n", 146 | "test_accuracy = []\n", 147 | "for _ in range(2500):\n", 148 | " sess.run(train_step, feed_dict={x:train_x, t:train_t})\n", 149 | " acc_val = sess.run(accuracy, feed_dict={x:train_x, t:train_t})\n", 150 | " train_accuracy.append(acc_val)\n", 151 | " acc_val = sess.run(accuracy, feed_dict={x:test_x, t:test_t})\n", 152 | " test_accuracy.append(acc_val)" 153 | ] 154 | }, 155 | { 156 | "cell_type": "markdown", 157 | "metadata": {}, 158 | "source": [ 159 | "**[CAF-07]** 결과를 그래프로 출력한다." 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 7, 165 | "metadata": { 166 | "collapsed": false 167 | }, 168 | "outputs": [ 169 | { 170 | "data": { 171 | "text/plain": [ 172 | "" 173 | ] 174 | }, 175 | "execution_count": 7, 176 | "metadata": {}, 177 | "output_type": "execute_result" 178 | }, 179 | { 180 | "data": { 181 | "image/png": "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\ngg==\n", 182 | "text/plain": [ 183 | "" 184 | ] 185 | }, 186 | "metadata": {}, 187 | "output_type": "display_data" 188 | } 189 | ], 190 | "source": [ 191 | "fig = plt.figure(figsize=(8,6))\n", 192 | "subplot = fig.add_subplot(1,1,1)\n", 193 | "subplot.plot(range(len(train_accuracy)), train_accuracy,\n", 194 | " linewidth=2, label='Training set')\n", 195 | "subplot.plot(range(len(test_accuracy)), test_accuracy,\n", 196 | " linewidth=2, label='Test set')\n", 197 | "subplot.legend(loc='upper left')" 198 | ] 199 | } 200 | ], 201 | "metadata": { 202 | "kernelspec": { 203 | "display_name": "Python 2", 204 | "language": "python", 205 | "name": "python2" 206 | }, 207 | "language_info": { 208 | "codemirror_mode": { 209 | "name": "ipython", 210 | "version": 2 211 | }, 212 | "file_extension": ".py", 213 | "mimetype": "text/x-python", 214 | "name": "python", 215 | "nbconvert_exporter": "python", 216 | "pygments_lexer": "ipython2", 217 | "version": "2.7.5" 218 | } 219 | }, 220 | "nbformat": 4, 221 | "nbformat_minor": 0 222 | } 223 | -------------------------------------------------------------------------------- /Chapter02/MNIST dataset sample.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "**[MDS-01]** 모듈을 임포트한다." 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import numpy as np\n", 19 | "import matplotlib.pyplot as plt\n", 20 | "from tensorflow.examples.tutorials.mnist import input_data" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "**[MDS-02]** MNIST 데이터 세트를 다운로드해서 오브젝트에 저장한다." 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 2, 33 | "metadata": { 34 | "collapsed": false 35 | }, 36 | "outputs": [ 37 | { 38 | "name": "stdout", 39 | "output_type": "stream", 40 | "text": [ 41 | "Successfully downloaded train-images-idx3-ubyte.gz 9912422 bytes.\n", 42 | "Extracting /tmp/data/train-images-idx3-ubyte.gz\n", 43 | "Successfully downloaded train-labels-idx1-ubyte.gz 28881 bytes.\n", 44 | "Extracting /tmp/data/train-labels-idx1-ubyte.gz\n", 45 | "Successfully downloaded t10k-images-idx3-ubyte.gz 1648877 bytes.\n", 46 | "Extracting /tmp/data/t10k-images-idx3-ubyte.gz\n", 47 | "Successfully downloaded t10k-labels-idx1-ubyte.gz 4542 bytes.\n", 48 | "Extracting /tmp/data/t10k-labels-idx1-ubyte.gz\n" 49 | ] 50 | } 51 | ], 52 | "source": [ 53 | "mnist = input_data.read_data_sets(\"/tmp/data/\", one_hot=True)" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": {}, 59 | "source": [ 60 | "**[MDS-03]** 트레이닝 세트에서 10개의 데이터를 추출하고 이미지 데이터와 라벨을 각각의 변수에 저장한다." 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 3, 66 | "metadata": { 67 | "collapsed": true 68 | }, 69 | "outputs": [], 70 | "source": [ 71 | "images, labels = mnist.train.next_batch(10)" 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": {}, 77 | "source": [ 78 | "**[MDS-04]** 첫 번째 이미지 데이터를 확인한다. 각 픽셀의 농도가 나열된 리스트(array 오브젝트)로 되어 있다." 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 4, 84 | "metadata": { 85 | "collapsed": false, 86 | "scrolled": true 87 | }, 88 | "outputs": [ 89 | { 90 | "name": "stdout", 91 | "output_type": "stream", 92 | "text": [ 93 | "[ 0. 0. 0. 0. 0. 0. 0.\n", 94 | " 0. 0. 0. 0. 0. 0. 0.\n", 95 | " 0. 0. 0. 0. 0. 0. 0.\n", 96 | " 0. 0. 0. 0. 0. 0. 0.\n", 97 | " 0. 0. 0. 0. 0. 0. 0.\n", 98 | " 0. 0. 0. 0. 0. 0. 0.\n", 99 | " 0. 0. 0. 0. 0. 0. 0.\n", 100 | " 0. 0. 0. 0. 0. 0. 0.\n", 101 | " 0. 0. 0. 0. 0. 0. 0.\n", 102 | " 0. 0. 0. 0. 0. 0. 0.\n", 103 | " 0. 0. 0. 0. 0. 0. 0.\n", 104 | " 0. 0. 0. 0. 0. 0. 0.\n", 105 | " 0. 0. 0. 0. 0. 0. 0.\n", 106 | " 0. 0. 0. 0. 0. 0. 0.\n", 107 | " 0. 0. 0. 0. 0. 0. 0.\n", 108 | " 0. 0. 0. 0. 0. 0. 0.\n", 109 | " 0. 0. 0. 0. 0. 0. 0.\n", 110 | " 0. 0. 0. 0. 0. 0. 0.\n", 111 | " 0. 0. 0. 0. 0. 0. 0.\n", 112 | " 0. 0. 0. 0. 0. 0. 0.\n", 113 | " 0. 0. 0. 0. 0. 0. 0.\n", 114 | " 0. 0. 0. 0. 0. 0. 0.\n", 115 | " 0. 0. 0. 0. 0. 0. 0.\n", 116 | " 0. 0. 0. 0. 0. 0. 0.\n", 117 | " 0. 0. 0. 0. 0. 0. 0.\n", 118 | " 0. 0. 0. 0. 0. 0. 0.\n", 119 | " 0. 0. 0. 0. 0. 0. 0.\n", 120 | " 0. 0. 0. 0. 0. 0. 0.\n", 121 | " 0. 0. 0. 0. 0. 0. 0.\n", 122 | " 0. 0. 0. 0. 0.38039219 0.37647063\n", 123 | " 0.3019608 0.46274513 0.2392157 0. 0. 0. 0.\n", 124 | " 0. 0. 0. 0. 0. 0. 0.\n", 125 | " 0. 0. 0. 0. 0.35294119 0.5411765\n", 126 | " 0.92156869 0.92156869 0.92156869 0.92156869 0.92156869 0.92156869\n", 127 | " 0.98431379 0.98431379 0.97254908 0.99607849 0.96078438 0.92156869\n", 128 | " 0.74509805 0.08235294 0. 0. 0. 0. 0.\n", 129 | " 0. 0. 0. 0. 0. 0.\n", 130 | " 0.54901963 0.98431379 0.99607849 0.99607849 0.99607849 0.99607849\n", 131 | " 0.99607849 0.99607849 0.99607849 0.99607849 0.99607849 0.99607849\n", 132 | " 0.99607849 0.99607849 0.99607849 0.99607849 0.74117649 0.09019608\n", 133 | " 0. 0. 0. 0. 0. 0. 0.\n", 134 | " 0. 0. 0. 0.88627458 0.99607849 0.81568635\n", 135 | " 0.78039223 0.78039223 0.78039223 0.78039223 0.54509807 0.2392157\n", 136 | " 0.2392157 0.2392157 0.2392157 0.2392157 0.50196081 0.8705883\n", 137 | " 0.99607849 0.99607849 0.74117649 0.08235294 0. 0. 0.\n", 138 | " 0. 0. 0. 0. 0. 0.\n", 139 | " 0.14901961 0.32156864 0.0509804 0. 0. 0. 0.\n", 140 | " 0. 0. 0. 0. 0. 0. 0.\n", 141 | " 0.13333334 0.83529419 0.99607849 0.99607849 0.45098042 0. 0.\n", 142 | " 0. 0. 0. 0. 0. 0. 0.\n", 143 | " 0. 0. 0. 0. 0. 0. 0.\n", 144 | " 0. 0. 0. 0. 0. 0. 0.\n", 145 | " 0. 0.32941177 0.99607849 0.99607849 0.91764712 0. 0.\n", 146 | " 0. 0. 0. 0. 0. 0. 0.\n", 147 | " 0. 0. 0. 0. 0. 0. 0.\n", 148 | " 0. 0. 0. 0. 0. 0. 0.\n", 149 | " 0. 0.32941177 0.99607849 0.99607849 0.91764712 0. 0.\n", 150 | " 0. 0. 0. 0. 0. 0. 0.\n", 151 | " 0. 0. 0. 0. 0. 0. 0.\n", 152 | " 0. 0. 0. 0. 0. 0. 0.\n", 153 | " 0.41568631 0.6156863 0.99607849 0.99607849 0.95294124 0.20000002\n", 154 | " 0. 0. 0. 0. 0. 0. 0.\n", 155 | " 0. 0. 0. 0. 0. 0. 0.\n", 156 | " 0. 0. 0. 0.09803922 0.45882356 0.89411771\n", 157 | " 0.89411771 0.89411771 0.99215692 0.99607849 0.99607849 0.99607849\n", 158 | " 0.99607849 0.94117653 0. 0. 0. 0. 0.\n", 159 | " 0. 0. 0. 0. 0. 0. 0.\n", 160 | " 0. 0. 0. 0.26666668 0.4666667 0.86274517\n", 161 | " 0.99607849 0.99607849 0.99607849 0.99607849 0.99607849 0.99607849\n", 162 | " 0.99607849 0.99607849 0.99607849 0.55686277 0. 0. 0.\n", 163 | " 0. 0. 0. 0. 0. 0. 0.\n", 164 | " 0. 0. 0. 0.14509805 0.73333335 0.99215692\n", 165 | " 0.99607849 0.99607849 0.99607849 0.87450987 0.80784321 0.80784321\n", 166 | " 0.29411766 0.26666668 0.84313732 0.99607849 0.99607849 0.45882356\n", 167 | " 0. 0. 0. 0. 0. 0. 0.\n", 168 | " 0. 0. 0. 0. 0. 0.44313729\n", 169 | " 0.8588236 0.99607849 0.94901967 0.89019614 0.45098042 0.34901962\n", 170 | " 0.12156864 0. 0. 0. 0. 0.7843138\n", 171 | " 0.99607849 0.9450981 0.16078432 0. 0. 0. 0.\n", 172 | " 0. 0. 0. 0. 0. 0. 0.\n", 173 | " 0. 0.66274512 0.99607849 0.6901961 0.24313727 0. 0.\n", 174 | " 0. 0. 0. 0. 0. 0.18823531\n", 175 | " 0.90588242 0.99607849 0.91764712 0. 0. 0. 0.\n", 176 | " 0. 0. 0. 0. 0. 0. 0.\n", 177 | " 0. 0. 0.07058824 0.48627454 0. 0. 0.\n", 178 | " 0. 0. 0. 0. 0. 0.\n", 179 | " 0.32941177 0.99607849 0.99607849 0.65098041 0. 0. 0.\n", 180 | " 0. 0. 0. 0. 0. 0. 0.\n", 181 | " 0. 0. 0. 0. 0. 0. 0.\n", 182 | " 0. 0. 0. 0. 0. 0. 0.\n", 183 | " 0.54509807 0.99607849 0.9333334 0.22352943 0. 0. 0.\n", 184 | " 0. 0. 0. 0. 0. 0. 0.\n", 185 | " 0. 0. 0. 0. 0. 0. 0.\n", 186 | " 0. 0. 0. 0. 0. 0.\n", 187 | " 0.82352948 0.98039222 0.99607849 0.65882355 0. 0. 0.\n", 188 | " 0. 0. 0. 0. 0. 0. 0.\n", 189 | " 0. 0. 0. 0. 0. 0. 0.\n", 190 | " 0. 0. 0. 0. 0. 0. 0.\n", 191 | " 0.94901967 0.99607849 0.93725497 0.22352943 0. 0. 0.\n", 192 | " 0. 0. 0. 0. 0. 0. 0.\n", 193 | " 0. 0. 0. 0. 0. 0. 0.\n", 194 | " 0. 0. 0. 0. 0. 0.\n", 195 | " 0.34901962 0.98431379 0.9450981 0.33725491 0. 0. 0.\n", 196 | " 0. 0. 0. 0. 0. 0. 0.\n", 197 | " 0. 0. 0. 0. 0. 0. 0.\n", 198 | " 0. 0. 0. 0. 0. 0.\n", 199 | " 0.01960784 0.80784321 0.96470594 0.6156863 0. 0. 0.\n", 200 | " 0. 0. 0. 0. 0. 0. 0.\n", 201 | " 0. 0. 0. 0. 0. 0. 0.\n", 202 | " 0. 0. 0. 0. 0. 0. 0.\n", 203 | " 0.01568628 0.45882356 0.27058825 0. 0. 0. 0.\n", 204 | " 0. 0. 0. 0. 0. 0. 0.\n", 205 | " 0. 0. 0. 0. 0. 0. 0.\n", 206 | " 0. 0. 0. 0. 0. 0. 0.\n", 207 | " 0. 0. 0. 0. 0. 0. 0.\n", 208 | " 0. 0. 0. 0. 0. 0. 0. ]\n" 209 | ] 210 | } 211 | ], 212 | "source": [ 213 | "print images[0]" 214 | ] 215 | }, 216 | { 217 | "cell_type": "markdown", 218 | "metadata": {}, 219 | "source": [ 220 | "**[MDS-05]** 해당 라벨을 확인한다. 첫 번째 요소를 0번째로 볼 때 앞에서부터 7번째 요소가 1로 되어 있으므로, 숫자 '7'의 이미지라는 것을 나타낸다." 221 | ] 222 | }, 223 | { 224 | "cell_type": "code", 225 | "execution_count": 5, 226 | "metadata": { 227 | "collapsed": false, 228 | "scrolled": true 229 | }, 230 | "outputs": [ 231 | { 232 | "name": "stdout", 233 | "output_type": "stream", 234 | "text": [ 235 | "[ 0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]\n" 236 | ] 237 | } 238 | ], 239 | "source": [ 240 | "print labels[0]" 241 | ] 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "metadata": {}, 246 | "source": [ 247 | "**[MDS-06]** 이미지 데이터를 실제 이미지로 출력해본다." 248 | ] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "execution_count": 6, 253 | "metadata": { 254 | "collapsed": false 255 | }, 256 | "outputs": [ 257 | { 258 | "data": { 259 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAcwAAADkCAYAAAAVUxRpAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xu8jVX+B/DPN8ot10SUFCqaJKWLcivpMs1QRNTEdBHT\nvegilCFUKqULMtNVGTVEYybdRkRTmKnm5UdSuQyO3BLKtZ7fH8f6+m5n73PW2efs/ez97M/79ZrX\nfFpn23v12O111nevZy0JggBERERUuIPC7gAREVE24IBJRETkgQMmERGRBw6YREREHjhgEhEReeCA\nSURE5IEDJhERkYesGjBFZJuIbN33v20isldEngy7X1EmIq+ISJ6I/CAi34jIwLD7lAtE5DgR2SEi\nL4fdl1wgIt1FZLGIbBeRZSJyTth9iioRuUlEFojIThF5Puz+FEfZsDtQHEEQVHZZRCoByAPweng9\nygkjAfQOgmCniBwPYI6ILAyC4J2wOxZxTwOYH3YncoGIdED++7xbEAQLRKRO2H2KuDUAhgG4EECF\nkPtSLFk1YB7gcgDrgyCYF3ZHoiwIgsXmHwXAHgAbQupOThCR7gC+B7AYQKOQu5MLhgAYGgTBAgAI\ngiAv3O5EWxAE0wBARE4HcGTI3SmWrCrJHqAnAJar0kBEnhGRHwEsAjA8CIL/hN2nqBKRKgD+COBO\n5P+CQikkIgcBaAGg1r5S7CoReUpEyoXdN8o8WTlgikh9AG0AvBR2X3JBEAQ3ATgUwPkAHtz3myGl\nxlAAE4IgWBt2R3JEbQAHA+gC4BwApwBoDmBQmJ2izJSVAyaAqwHMDYJgZdgdyRVBvtkA3gDQI+z+\nRJGInIL8X0qeCLsvOWTHvv8fEwTB+iAINgN4HMCvQ+wTZahs/Q7zagAjwu5EjioL4KewOxFRbQHU\nB7BKRAT5s/oyInJiEAQtwu1aNAVBsEVEVh/YHEpnKONl3QxTRM4GUBfAX8PuS9SJyOEicoWIVBKR\ng0TkQgBdAUwPu28RNR5AQ+SXBZsBGAdgBoALwuxUDngBwC373u/VAdwB4G8h9ymyRKSMiJQHUAZA\nWREpJyJlwu6Xj2ycYfYEMCUIgh/D7kgOCAD8AcBY5C9AWQbgareakEpXEAQ7Aex0/ywi2wHs3Fcm\npNQZBqAmgK+QX6KdDFawUmkQgAewfyZ/FfIXug0NrUeehAdIExERFS3rSrJERERh4IBJRETkgQMm\nERGRBw6YREREHgpdJSsiXBGUhCAIkt7SjNc8Oclec17v5PB6pxc/U9Iv3jUv8rYSrqItnvz7zUuG\n17x4SnrNeb2Lh9c7vfiZkn6JrjlLskRERB44YBIREXnggElEROSBAyYREZEHDphEREQesnHzdSKi\nlPrll1809+/fHwDw9NNPa9vHH3+suUULnryWKzjDJCIi8sABk4iIyANLskREANavX6/5/vvv1zx+\n/PgCj12+fLlmlmST17t3b80TJ07UPG/ePADAqaeemvY+FYYzTCIiIg8cMImIiDywJEuFWrlypeYJ\nEyZoHj58uGa376Ldr7JJkyaaH3zwQc2dO3dOST+JkpGXl6d51KhRmuOVYdu0aaP5zDPPTG3HckT9\n+vU179y5U/OyZcsAsCRLRESUlThgEhEReWBJltSGDRsAACNHjtS2V199VfPGjRs12+Nv4h2Fs3Tp\nUs39+vXT7MpaNWvWLIUeZ5/du3drbt++PQBg7ty5cR9brVo1zf/9738116tXL0W9yw179+7VPGLE\nCM12YwLr5ptvBgA89thj2nbIIYekqHe5xZZkrZdeegkAcMUVV6SzO0XiDJOIiMgDB0wiIiIPGVuS\nfeGFFwDElvsOO+wwzUuWLNHcsmVLza1bt05D76LDrmAdPHgwgNhrble+2vajjz5a8+GHH17geW35\ndsWKFZpdSXbx4sUl6HV2sWXY6667TnO8Uuyll16q+d5779Vct27dpF77u+++AwDUrl07qT8fRffd\nd5/mRGXYvn37an7qqadS3ieKlaklb84wiYiIPJRohvnaa69p/vzzzzW72WFJbNmypUBbmTJlNO/a\ntUtzhQoVNFeqVAkA0LRpU22bPHmy5nizoVw2ffp0zW4GGW8RDwCceOKJmj/88EPN8RbwfPTRR5rb\ntm2r2S4GyhV2sYjd/su56aabND/66KOay5cvn9Tr2UVW7r9Fu9Xb7bffntTzZrshQ4YAiL3G1i23\n3KLZ/p1R6rz55ptx23v06JHmnvjhDJOIiMgDB0wiIiIPYhd1FPihSBDv567kM2bMGG2z9zZlmnPP\nPVfzpEmTNKdiIYSIIAiC+DVNvz8f95qXJrtg6owzztDsFlXZsrUttz7++OOan3zySc1uEYVdCGTF\nu2dz3Lhx2nbDDTcU718gzvMne81Tdb0XLVqk2V7jHTt2aK5cuTIAYPPmzdpWtmxy35IsWLBA80UX\n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\n9eqVht5lP1tydaXYRGVYW1o99NBDNbvP740bN2rbL7/8orl///6aq1atCgC49tprtW3t2rVJ9b0o\nnGESERF54IBJRETkIatKsgMHDtQ8atQozfFWVyXSpk0bzbNnzy7w83fffVfztm3bNHOVIfDhhx+G\n3YWs9/jjj2seMGCA959r3Lix5ttuu63Az23p6ueff9b89ddfAwD69u0b93mjXp61Je7JkycDiC2t\nHnLIIZrt58vChQs1syRbPPaz2ZVi7XXu2rWrZrvCtXnz5gWe6/XXX9f80EMPababH+zcubPAn6tb\nt25xu+2FM0wiIiIPGTvDdAt87G999rdzq1KlSprvvPNOAMBll12mbUcffbTmKlWqaHZfEr/66qva\nVrNmTc1ly2bs5UkbuyDKLoogf3aWY38zLkq9evU0P/fcc5pbtWpV7D64xXDA/q31gNiZlJ0ZZLPd\nu3drtve1PvLIIwCAX/3qV9o2evRozR06dNBsF7X973//A7B/kSAQu1ilRYsWpdHtyJg0aVKBNvue\nffnll72fq1u3bppr1aqluX379oX+OXf/cWnjDJOIiMgDB0wiIiIPGVtzdGXSRGWiE044QbP9Yrhp\n06ber2G/iHYaNWqk2ZZdcpXd9d9mKpxdeGPfw+5kl0TsorQpU6ZoPuywwwr9c5dcconm5cuXa37l\nlVcK9Gfr1q2abXkym+3atUvz9ddfr9luE+g+G+z91aeeemrc5zvqqKM0uwV/9lo1adJE83vvvZdk\nr6PJfk64RZil8T477rjjNNeuXVvzSSedVOCx9p7N0sQZJhERkQcOmERERB4ytiTr7rmx91iecsop\nmmfOnKnZTs/j+emnnzS7e7GA/StA7crYqVOnJtnj3HXEEUcAiC1j5boFCxZoHjRoUKGPPfvsszX/\n7W9/01yce39tafH555/X7O41tmXaqLBl2AceeECzLcOefPLJmt1WhO796uuNN94AAKxZs0bb7Nc5\nP/74o2a7Yj9X2TsU3AHR9nPXbkdYFLuK++6779a8fft2zcOHDwcQ+3XGQQelZi7IGSYREZEHDphE\nREQeMrYk69it7uzWSInKsG51lD115He/+53mL7/8UrMr99oVhhTL3tidiCt7nXXWWanuTkZzK1KB\n/WWiwrhS7AcffKBt5cqVK/2ORZQtXz/88MOa7UYl9qub4pZinS1bthRoq1atmmaWYWPZkutXX30F\nAFi6dKm22S0h7dZ4c+bM0ez++7Eny9jStzVr1iwAwMcff6xtO3bsSKrvReEMk4iIyEPGzzAtuzVS\nIm5m6bNd1UUXXQSg6HvjctnixYuLfMyll16ahp5kLvdb8H333adtdoGIZRcmuBlSac8qly1bpjne\nb+Xu/EAAaNCgQam+djps2rQJAHDXXXdpmz1L0W2WDgB16tRJ6jXy8vI0//Wvf03qOXKVneG7xVjd\nu3fXNrdF4YG5OIdonHHGGZovvPBCALH3adrtH/v16+fd96JwhklEROSBAyYREZGHjC3J2i/VHVvO\natasmWY7FY9XPrElr1tuuUXz0KFDAQDly5cvWWdzXK4vmurSpQuAxGVYq0ePHppTdcaqLUmuX7++\nwM+PPPJIzfa/qWzhTl5ZsWKFttmzFC+++GLv57JbBtot80aMGKH522+/TaKXucsu3kl0wpSvtm3b\nan766ac1N2zYUHM6F8pxhklEROSBAyYREZGHjC3J/vnPfwYQuxO9XfFn77mxBxvHW101ZswYzb17\n9y7VfkaRvZ/QHjxs2VWJZcqUSXmfMo09Icfe2+vYe/NatmypOVXl63Xr1mm2h03HU7du3ZT0IUzu\nkGdg/1Z2QPwTh9566y3N9u/RvtePOeYYzffccw+A2Hs9k72nM6qmTZum+f7779e8aNEi7+ewq2Td\nZ/bNN9+cVH/sc5UmzjCJiIg8cMAkIiLykFElWXd6CAC89tprAIo/tXaPtzfTswzrx20B5srhQOyJ\nEJbd0squuswVdoXm7t27C/zcfpXw7rvvprw/EyZM0BxvswK7ktCVGLPVscceCyD2hJI//vGPmrt1\n6+b9XPXq1dM8bNgwzX379tXsyr22JGtPmMlVdgX2bbfdptmWx91XZPb917FjR83uBBkgtiResWLF\nEvWtqI0PksUZJhERkQcOmERERB5CKcnaG4GvvfZaze6wW2D/lDrR1NruJdiuXTvNr776KgDgn//8\np7a99957mjt06JBkr6PPlWTt34Nlyyr2xmEqqFOnTil/Dft1hb0BPx57kkz79u1T1qd0cJ8JQ4YM\n0bYTTzxRs12xabmVrbZk63PCjttv1x5gP2XKFM1FHRAeJbbcajePseVUuyGHuzb2c/6www7TfOON\nN2q2G264fZZ///vfa1txDoX+wx/+4P3Y4uAMk4iIyEPaZpj23qiePXtqTrSoxDnzzDM123vY7G8m\nNWrU0Ox+e7SnldgvpH1O38hVRZ0hV716dc29evVKdXey2jnnnJPy1/j73/+u2W3zmMh5552X6u6E\nys4ai7Pox8e2bdsAAJs3b9Y2O0vKJQ8++KBmO6u0C//sfe9FnWT07LPPal6+fLlmd6+sW/wJxJ5r\nXBQ7PpQmzjCJiIg8cMAkIiLykPKSrLvPJlEZ1p5KcvLJJ2seMGAAAODcc8/VtkMOOaTI13NfzNvt\nmezJA/Pnz9dsFw5RbOk6HndQKxXNvv9mzZpV4ufbuHGjZnefrL0PMRG3OOvqq68ucR9y1YYNGwAA\nq1at0rbLLrssrO6Eavr06XHbbem0VatWST23XSjn7l0ePny4thWnJJsqnGESERF54IBJRETkIeUl\n2S+++AJAbBm2fv36mu09ko0aNSrx67ltyj799FNt27t3b9xM+8tNAPD9998X+LldXWkPcKXC5eXl\nabYHSxe1jaAt+7l7igFg7NixmlevXu3dj0mTJgGIPX2DiufDDz8s0FazZs30dyQD2Ht/bbZ3KiTL\nrm4ePXo0gNjt97Zu3aq5SpUqJX69ZHCGSURE5IEDJhERkYe0bVxgp++XX3655tIow9qpuntuW+ql\nxOwKzoULFxb4uT01oGzZ/W8XW9q27bnCrjqdPHkyAOCzzz7Ttq+++kqzLWsXVbratGmT5q+//tq7\nP/Zrju7du2u2p6ZQcuyGBbnObolpV24/9thjmt0dDkDxPt/tQfTujgi3XScQe+qPHUPisaeglObq\nfs4wiYiIPHDAJCIi8pDyWprb0b58+fLalmi15cCBAzXbDQ0cW65aunSp5iuvvFKzW2VoTzmxJxk0\nb97cu+8EzJgxQ3OFChU0Dx48WHNR+5hGUZ06dTS7Exns+9CuCl+2bFmpvvbBBx8MAGjSpIm2ubIw\nAJxwwgml+npEjt1cwN6J8OKLL2q2+4a7rwR8yqJPPvmkZrdPrV2N/Nvf/ta7n/3799fMkiwREVGa\npXyG6Ub3UaNGadutt96q2X5Z/Pzzz2tu06ZNgeeaOXOmZvsbvF1Q5GaW9pSTCRMmaLazJIpdhFK1\nalUAsacQWG5mAxR9P2EucduknXbaadpmT8WxCxeSZaskbku8rl27lvh5KTl2G89c0qdPH81PPPGE\nZnu/5Pbt2zW7WaidjSYS73Pcfs7Y83iLcvrpp3s/tjg4wyQiIvLAAZOIiMhD2m6gswsUGjdurNmW\nq+x2Yol2xY/HPt9VV10FALj77ru1zeeUk1x1/vnna3aLsew9hu70FwDo16+f5kw4OSDTzJ07V/Pa\ntWs125MTlLVVAAABS0lEQVQcpkyZotmVqUaOHKlt9l40y5Zf7T2XFI7jjjsu7C6Ewi7GXLBggWb7\ntde0adM0L1q0yPu527Ztq9ktLnKf58Vlv94rTZxhEhEReeCASURE5EHsyqQCPxQJCvt5afjuu+80\nu/vZrPfff19z7dq1NXfu3FmzLb+GTUQQBIEU/ciEfz7l1zxqSnLNeb2LL9eu96OPPgoAuOuuu7TN\nroK2XzelAj9T0i/RNecMk4iIyAMHTCIiIg+hHzNhy6x2pRURUSaxhxZXrlw5xJ5QWDjDJCIi8hD6\nop+o4Rf06Zdri1DCxuudXvxMST8u+iEiIioBDphEREQeOGASERF54IBJRETkgQMmERGRhyLvw3QH\neVL68JqnF693evF6px+veeko9LYSIiIiyseSLBERkQcOmERERB44YBIREXnggElEROSBAyYREZGH\n/webpSRLN1BZRQAAAABJRU5ErkJggg==\n", 260 | "text/plain": [ 261 | "" 262 | ] 263 | }, 264 | "metadata": {}, 265 | "output_type": "display_data" 266 | } 267 | ], 268 | "source": [ 269 | "fig = plt.figure(figsize=(8,4))\n", 270 | "for c, (image, label) in enumerate(zip(images, labels)):\n", 271 | " subplot = fig.add_subplot(2,5,c+1)\n", 272 | " subplot.set_xticks([])\n", 273 | " subplot.set_yticks([])\n", 274 | " subplot.set_title('%d' % np.argmax(label))\n", 275 | " subplot.imshow(image.reshape((28,28)), vmin=0, vmax=1,\n", 276 | " cmap=plt.cm.gray_r, interpolation=\"nearest\")" 277 | ] 278 | } 279 | ], 280 | "metadata": { 281 | "kernelspec": { 282 | "display_name": "Python 2", 283 | "language": "python", 284 | "name": "python2" 285 | }, 286 | "language_info": { 287 | "codemirror_mode": { 288 | "name": "ipython", 289 | "version": 2 290 | }, 291 | "file_extension": ".py", 292 | "mimetype": "text/x-python", 293 | "name": "python", 294 | "nbconvert_exporter": "python", 295 | "pygments_lexer": "ipython2", 296 | "version": "2.7.5" 297 | } 298 | }, 299 | "nbformat": 4, 300 | "nbformat_minor": 0 301 | } 302 | -------------------------------------------------------------------------------- /Chapter03/Double layer network example.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "**[DNE-01]** 모듈을 임포트하고 난수의 시드를 설정한다." 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import tensorflow as tf\n", 19 | "import numpy as np\n", 20 | "import matplotlib.pyplot as plt\n", 21 | "from numpy.random import multivariate_normal, permutation\n", 22 | "import pandas as pd\n", 23 | "from pandas import DataFrame, Series\n", 24 | "\n", 25 | "np.random.seed(20160615)\n", 26 | "tf.set_random_seed(20160615)" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": {}, 32 | "source": [ 33 | "**[DNE-02]** 트레이닝 세트 데이터를 생성한다." 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 2, 39 | "metadata": { 40 | "collapsed": false 41 | }, 42 | "outputs": [], 43 | "source": [ 44 | "def generate_datablock(n, mu, var, t):\n", 45 | " data = multivariate_normal(mu, np.eye(2)*var, n)\n", 46 | " df = DataFrame(data, columns=['x1','x2'])\n", 47 | " df['t'] = t\n", 48 | " return df\n", 49 | "\n", 50 | "df0 = generate_datablock(30, [-7,-7], 18, 1)\n", 51 | "df1 = generate_datablock(30, [-7,7], 18, 0)\n", 52 | "df2 = generate_datablock(30, [7,-7], 18, 0)\n", 53 | "df3 = generate_datablock(30, [7,7], 18, 1)\n", 54 | "\n", 55 | "df = pd.concat([df0, df1, df2, df3], ignore_index=True)\n", 56 | "train_set = df.reindex(permutation(df.index)).reset_index(drop=True)" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "**[DNE-03]** (x1, x2)와 t를 각각 모은 것을 NumPy의 array 오브젝트로 추출해둔다." 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 3, 69 | "metadata": { 70 | "collapsed": true 71 | }, 72 | "outputs": [], 73 | "source": [ 74 | "train_x = train_set[['x1','x2']].as_matrix()\n", 75 | "train_t = train_set['t'].as_matrix().reshape([len(train_set), 1])" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": {}, 81 | "source": [ 82 | "**[DNE-04]** 2계층 신경망을 이용한 이항 분류기 모델을 정의한다." 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 4, 88 | "metadata": { 89 | "collapsed": false 90 | }, 91 | "outputs": [], 92 | "source": [ 93 | "num_units1 = 2\n", 94 | "num_units2 = 2\n", 95 | "\n", 96 | "x = tf.placeholder(tf.float32, [None, 2])\n", 97 | "\n", 98 | "w1 = tf.Variable(tf.truncated_normal([2, num_units1]))\n", 99 | "b1 = tf.Variable(tf.zeros([num_units1]))\n", 100 | "hidden1 = tf.nn.tanh(tf.matmul(x, w1) + b1)\n", 101 | "\n", 102 | "w2 = tf.Variable(tf.truncated_normal([num_units1, num_units2]))\n", 103 | "b2 = tf.Variable(tf.zeros([num_units2]))\n", 104 | "hidden2 = tf.nn.tanh(tf.matmul(hidden1, w2) + b2)\n", 105 | "\n", 106 | "w0 = tf.Variable(tf.zeros([num_units2, 1]))\n", 107 | "b0 = tf.Variable(tf.zeros([1]))\n", 108 | "p = tf.nn.sigmoid(tf.matmul(hidden2, w0) + b0)" 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": {}, 114 | "source": [ 115 | "**[DNE-05]** 오차 함수 loss, 트레이닝 알고리즘 train_step, 정답률 accuracy를 정의한다." 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 5, 121 | "metadata": { 122 | "collapsed": true 123 | }, 124 | "outputs": [], 125 | "source": [ 126 | "t = tf.placeholder(tf.float32, [None, 1])\n", 127 | "loss = -tf.reduce_sum(t*tf.log(p) + (1-t)*tf.log(1-p))\n", 128 | "train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss)\n", 129 | "correct_prediction = tf.equal(tf.sign(p-0.5), tf.sign(t-0.5))\n", 130 | "accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))" 131 | ] 132 | }, 133 | { 134 | "cell_type": "markdown", 135 | "metadata": {}, 136 | "source": [ 137 | "**[DNE-06]** 세션을 준비하고 Variable을 초기화한다." 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": 6, 143 | "metadata": { 144 | "collapsed": false 145 | }, 146 | "outputs": [], 147 | "source": [ 148 | "sess = tf.InteractiveSession()\n", 149 | "sess.run(tf.initialize_all_variables())" 150 | ] 151 | }, 152 | { 153 | "cell_type": "markdown", 154 | "metadata": {}, 155 | "source": [ 156 | "**[DNE-07]** 파라미터 최적화를 2000회 반복한다." 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": 7, 162 | "metadata": { 163 | "collapsed": false, 164 | "scrolled": false 165 | }, 166 | "outputs": [ 167 | { 168 | "name": "stdout", 169 | "output_type": "stream", 170 | "text": [ 171 | "Step: 100, Loss: 83.176933, Accuracy: 0.508333\n", 172 | "Step: 200, Loss: 83.176178, Accuracy: 0.508333\n", 173 | "Step: 300, Loss: 83.174591, Accuracy: 0.508333\n", 174 | "Step: 400, Loss: 83.171082, Accuracy: 0.500000\n", 175 | "Step: 500, Loss: 83.162636, Accuracy: 0.508333\n", 176 | "Step: 600, Loss: 83.140877, Accuracy: 0.516667\n", 177 | "Step: 700, Loss: 83.075996, Accuracy: 0.541667\n", 178 | "Step: 800, Loss: 82.822495, Accuracy: 0.541667\n", 179 | "Step: 900, Loss: 81.475693, Accuracy: 0.625000\n", 180 | "Step: 1000, Loss: 75.140419, Accuracy: 0.658333\n", 181 | "Step: 1100, Loss: 59.051060, Accuracy: 0.866667\n", 182 | "Step: 1200, Loss: 46.646378, Accuracy: 0.900000\n", 183 | "Step: 1300, Loss: 41.770844, Accuracy: 0.900000\n", 184 | "Step: 1400, Loss: 39.639244, Accuracy: 0.900000\n", 185 | "Step: 1500, Loss: 38.510742, Accuracy: 0.900000\n", 186 | "Step: 1600, Loss: 37.788445, Accuracy: 0.900000\n", 187 | "Step: 1700, Loss: 37.159111, Accuracy: 0.900000\n", 188 | "Step: 1800, Loss: 36.648502, Accuracy: 0.900000\n", 189 | "Step: 1900, Loss: 36.529396, Accuracy: 0.891667\n", 190 | "Step: 2000, Loss: 36.352604, Accuracy: 0.891667\n" 191 | ] 192 | } 193 | ], 194 | "source": [ 195 | "i = 0\n", 196 | "for _ in range(2000):\n", 197 | " i += 1\n", 198 | " sess.run(train_step, feed_dict={x:train_x, t:train_t})\n", 199 | " if i % 100 == 0:\n", 200 | " loss_val, acc_val = sess.run(\n", 201 | " [loss, accuracy], feed_dict={x:train_x, t:train_t})\n", 202 | " print ('Step: %d, Loss: %f, Accuracy: %f'\n", 203 | " % (i, loss_val, acc_val))" 204 | ] 205 | }, 206 | { 207 | "cell_type": "markdown", 208 | "metadata": {}, 209 | "source": [ 210 | "**[DNE-08]** 얻어진 확률을 색의 농담으로 그림에 표시한다." 211 | ] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "execution_count": 8, 216 | "metadata": { 217 | "collapsed": false 218 | }, 219 | "outputs": [ 220 | { 221 | "data": { 222 | "text/plain": [ 223 | "" 224 | ] 225 | }, 226 | "execution_count": 8, 227 | "metadata": {}, 228 | "output_type": "execute_result" 229 | }, 230 | { 231 | "data": { 232 | "image/png": "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\n8AfFNeLEfZwWfic7CT2DRPR+Wi5FK/hC8P1gEfmhDUrcapPTA6Ze3FeJmgCrib6a+Ku5dOSDY2rC\nrzZeoHb/oOGVe8ROXfnoFOz42o0EXnRsyUp7lPhC8N3ADwIu9ydLSC6VqqoqX7lU7NZp9v75En9R\nC18vGkIp/FJ56TnUOgA/YVYcREIhzdYpWl7t3iOpFKzV74bQ23XH6LkYRctaFfxQhWV6OflHL+xQ\n2t+0aQtqas7CZZfdjtraGdiy5Qlb9Vt5XisTqJwuq9ZeM+1Sq0vNn653LzW0rHstK1+6Rr5Vvncb\nLdeTmhtKhEyG4dFHv5yTsOzRR78M5WQnM/fXEs2xv5oiWLfuS2hvrwJjDO3tVVi37ktj7q33txB9\n6f2CUzun9j9h5RWNRlXfq52T9tXeR0V6QRV8YeH7zSICnG9TMpnEihV35uSlX768EY2NDbYtfS8G\nTEWvESnnRPu1REXEzSJi3SuFQctVpParTu8589U5iN4nGgUuvbQZmzdfi/PP3499++Zi6dKnc6xu\nkV9LVtoTjQKXX96CjRuvwbx5b2Dv3nNw3XXPGCZLE7XCnbLMrbhttK43em90zCy+EHwvyLcLRJog\npcxL39nZqSv4nHMkk0l0dnaacgO55WKxW87JDkD+j6/lo9f6ckjllCItveQWlZFrR0v09drrJHbq\nVbu2trYb8+a9gV/+8mLMn78HtbXdUAquVdE3uq62thsXXPAb7Nx5IS655FVMn34AgPEvFTOCa7WM\n3v+V2XOigq5V3urfPJSC77U/Ww2tCVKVlZW6dW/ZshU33/xVxGIjE6fWrn0IixcvdKXdRmXtiL1T\ndatdY/af38j6Uv7Elou+mpUvtUVE9O1g5jntfCZtbZXYu3cu5s/fg71756Kmpgs1NV2m6rdqdb//\n/jT8+tdn45JLXsWvf302amu7R0XfXD0iHY5VkVYrZ2S9S/tmBN9psQdCJvhOf8mcqE+qY/LkyVi7\n9iHcfPPHE5/Wrn1I1WKXrkkmk7j55q/muIFuvrkRjY31uteJtsnM9U6Lvd17iVj3Wtdo/QpQc+ko\nLXy54OdD9N1yn2iVy2QYXnqpAV/4wjOoqelCbW03XnyxAbfc8l+aaQ1E7isiyJkMwwsvXIzrr38u\nK/QvvHAxbr99s+rArdn65cdFBN1MGatCLlreKdH3xcSr4eHhMcf9ZKU76SMXdc9wzvH666/jyiu/\n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\nxICOefyksgAAAABJRU5ErkJggg==\n", 233 | "text/plain": [ 234 | "" 235 | ] 236 | }, 237 | "metadata": {}, 238 | "output_type": "display_data" 239 | } 240 | ], 241 | "source": [ 242 | "train_set1 = train_set[train_set['t']==1]\n", 243 | "train_set2 = train_set[train_set['t']==0]\n", 244 | "\n", 245 | "fig = plt.figure(figsize=(6,6))\n", 246 | "subplot = fig.add_subplot(1,1,1)\n", 247 | "subplot.set_ylim([-15,15])\n", 248 | "subplot.set_xlim([-15,15])\n", 249 | "subplot.scatter(train_set1.x1, train_set1.x2, marker='x')\n", 250 | "subplot.scatter(train_set2.x1, train_set2.x2, marker='o')\n", 251 | "\n", 252 | "locations = []\n", 253 | "for x2 in np.linspace(-15,15,100):\n", 254 | " for x1 in np.linspace(-15,15,100):\n", 255 | " locations.append((x1,x2))\n", 256 | "p_vals = sess.run(p, feed_dict={x:locations})\n", 257 | "p_vals = p_vals.reshape((100,100))\n", 258 | "subplot.imshow(p_vals, origin='lower', extent=(-15,15,-15,15),\n", 259 | " cmap=plt.cm.gray_r, alpha=0.5)" 260 | ] 261 | } 262 | ], 263 | "metadata": { 264 | "kernelspec": { 265 | "display_name": "Python 2", 266 | "language": "python", 267 | "name": "python2" 268 | }, 269 | "language_info": { 270 | "codemirror_mode": { 271 | "name": "ipython", 272 | "version": 2 273 | }, 274 | "file_extension": ".py", 275 | "mimetype": "text/x-python", 276 | "name": "python", 277 | "nbconvert_exporter": "python", 278 | "pygments_lexer": "ipython2", 279 | "version": "2.7.5" 280 | } 281 | }, 282 | "nbformat": 4, 283 | "nbformat_minor": 0 284 | } 285 | -------------------------------------------------------------------------------- /Chapter03/MNIST single layer network with TensorBoard.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "**[MST-01]** 모듈을 임포트하고 난수의 시드를 설정한다." 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import tensorflow as tf\n", 19 | "import numpy as np\n", 20 | "import matplotlib.pyplot as plt\n", 21 | "from tensorflow.examples.tutorials.mnist import input_data\n", 22 | "\n", 23 | "np.random.seed(20160612)\n", 24 | "tf.set_random_seed(20160612)" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "**[MST-02]** MNIST 데이터 세트를 준비한다." 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 2, 37 | "metadata": { 38 | "collapsed": false 39 | }, 40 | "outputs": [ 41 | { 42 | "name": "stdout", 43 | "output_type": "stream", 44 | "text": [ 45 | "Extracting /tmp/data/train-images-idx3-ubyte.gz\n", 46 | "Extracting /tmp/data/train-labels-idx1-ubyte.gz\n", 47 | "Extracting /tmp/data/t10k-images-idx3-ubyte.gz\n", 48 | "Extracting /tmp/data/t10k-labels-idx1-ubyte.gz\n" 49 | ] 50 | } 51 | ], 52 | "source": [ 53 | "mnist = input_data.read_data_sets(\"/tmp/data/\", one_hot=True)" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": {}, 59 | "source": [ 60 | "**[MST-03]** 단층 신경망을 표현하는 클래스를 정의한다." 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 3, 66 | "metadata": { 67 | "collapsed": false 68 | }, 69 | "outputs": [], 70 | "source": [ 71 | "class SingleLayerNetwork:\n", 72 | " def __init__(self, num_units):\n", 73 | " with tf.Graph().as_default():\n", 74 | " self.prepare_model(num_units)\n", 75 | " self.prepare_session()\n", 76 | "\n", 77 | " def prepare_model(self, num_units):\n", 78 | " with tf.name_scope('input'):\n", 79 | " x = tf.placeholder(tf.float32, [None, 784], name='input')\n", 80 | " \n", 81 | " with tf.name_scope('hidden'):\n", 82 | " w1 = tf.Variable(tf.truncated_normal([784, num_units]),\n", 83 | " name='weights') \n", 84 | " b1 = tf.Variable(tf.zeros([num_units]), name='biases')\n", 85 | " hidden1 = tf.nn.relu(tf.matmul(x, w1) + b1, name='hidden1')\n", 86 | " \n", 87 | " with tf.name_scope('output'):\n", 88 | " w0 = tf.Variable(tf.zeros([num_units, 10]), name='weights')\n", 89 | " b0 = tf.Variable(tf.zeros([10]), name='biases')\n", 90 | " p = tf.nn.softmax(tf.matmul(hidden1, w0) + b0, name='softmax')\n", 91 | "\n", 92 | " with tf.name_scope('optimizer'):\n", 93 | " t = tf.placeholder(tf.float32, [None, 10], name='labels')\n", 94 | " loss = -tf.reduce_sum(t * tf.log(p), name='loss')\n", 95 | " train_step = tf.train.AdamOptimizer().minimize(loss)\n", 96 | "\n", 97 | " with tf.name_scope('evaluator'):\n", 98 | " correct_prediction = tf.equal(tf.argmax(p, 1), tf.argmax(t, 1))\n", 99 | " accuracy = tf.reduce_mean(tf.cast(correct_prediction,\n", 100 | " tf.float32), name='accuracy')\n", 101 | "\n", 102 | " tf.scalar_summary(\"loss\", loss)\n", 103 | " tf.scalar_summary(\"accuracy\", accuracy)\n", 104 | " tf.histogram_summary(\"weights_hidden\", w1)\n", 105 | " tf.histogram_summary(\"biases_hidden\", b1)\n", 106 | " tf.histogram_summary(\"weights_output\", w0)\n", 107 | " tf.histogram_summary(\"biases_output\", b0)\n", 108 | " \n", 109 | " self.x, self.t, self.p = x, t, p\n", 110 | " self.train_step = train_step\n", 111 | " self.loss = loss\n", 112 | " self.accuracy = accuracy\n", 113 | " \n", 114 | " def prepare_session(self):\n", 115 | " sess = tf.InteractiveSession()\n", 116 | " sess.run(tf.initialize_all_variables())\n", 117 | " summary = tf.merge_all_summaries()\n", 118 | " writer = tf.train.SummaryWriter(\"/tmp/mnist_sl_logs\", sess.graph)\n", 119 | " \n", 120 | " self.sess = sess\n", 121 | " self.summary = summary\n", 122 | " self.writer = writer" 123 | ] 124 | }, 125 | { 126 | "cell_type": "markdown", 127 | "metadata": {}, 128 | "source": [ 129 | "**[MST-04]** 텐서보드용 데이터 출력 디렉토리를 삭제해서 초기화해둔다." 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": 4, 135 | "metadata": { 136 | "collapsed": true 137 | }, 138 | "outputs": [], 139 | "source": [ 140 | "!rm -rf /tmp/mnist_sl_logs" 141 | ] 142 | }, 143 | { 144 | "cell_type": "markdown", 145 | "metadata": {}, 146 | "source": [ 147 | "**[MST-05]** 파라미터 최적화를 2000회 반복한다. 테스트 세트에 대해 약 97%의 정답률을 얻을 수 있다." 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": 5, 153 | "metadata": { 154 | "collapsed": false 155 | }, 156 | "outputs": [ 157 | { 158 | "name": "stdout", 159 | "output_type": "stream", 160 | "text": [ 161 | "Step: 100, Loss: 3184.660156, Accuracy: 0.901100\n", 162 | "Step: 200, Loss: 2317.262207, Accuracy: 0.931200\n", 163 | "Step: 300, Loss: 1844.382080, Accuracy: 0.944200\n", 164 | "Step: 400, Loss: 1852.014038, Accuracy: 0.942600\n", 165 | "Step: 500, Loss: 1652.209106, Accuracy: 0.946800\n", 166 | "Step: 600, Loss: 1368.317261, Accuracy: 0.956900\n", 167 | "Step: 700, Loss: 1287.111450, Accuracy: 0.960100\n", 168 | "Step: 800, Loss: 1182.710205, Accuracy: 0.962600\n", 169 | "Step: 900, Loss: 1126.482056, Accuracy: 0.965800\n", 170 | "Step: 1000, Loss: 1357.330322, Accuracy: 0.959800\n", 171 | "Step: 1100, Loss: 1068.415649, Accuracy: 0.967500\n", 172 | "Step: 1200, Loss: 1094.205078, Accuracy: 0.967600\n", 173 | "Step: 1300, Loss: 1215.297729, Accuracy: 0.961900\n", 174 | "Step: 1400, Loss: 1033.312012, Accuracy: 0.970100\n", 175 | "Step: 1500, Loss: 1163.462158, Accuracy: 0.964600\n", 176 | "Step: 1600, Loss: 1092.042358, Accuracy: 0.965700\n", 177 | "Step: 1700, Loss: 939.083984, Accuracy: 0.970300\n", 178 | "Step: 1800, Loss: 971.933289, Accuracy: 0.969600\n", 179 | "Step: 1900, Loss: 1001.808167, Accuracy: 0.970000\n", 180 | "Step: 2000, Loss: 971.080200, Accuracy: 0.970800\n" 181 | ] 182 | } 183 | ], 184 | "source": [ 185 | "nn = SingleLayerNetwork(1024)\n", 186 | "\n", 187 | "i = 0\n", 188 | "for _ in range(2000):\n", 189 | " i += 1\n", 190 | " batch_xs, batch_ts = mnist.train.next_batch(100)\n", 191 | " nn.sess.run(nn.train_step, feed_dict={nn.x: batch_xs, nn.t: batch_ts})\n", 192 | " if i % 100 == 0:\n", 193 | " summary, loss_val, acc_val = nn.sess.run(\n", 194 | " [nn.summary, nn.loss, nn.accuracy],\n", 195 | " feed_dict={nn.x:mnist.test.images, nn.t: mnist.test.labels})\n", 196 | " print ('Step: %d, Loss: %f, Accuracy: %f'\n", 197 | " % (i, loss_val, acc_val))\n", 198 | " nn.writer.add_summary(summary, i)" 199 | ] 200 | } 201 | ], 202 | "metadata": { 203 | "kernelspec": { 204 | "display_name": "Python 2", 205 | "language": "python", 206 | "name": "python2" 207 | }, 208 | "language_info": { 209 | "codemirror_mode": { 210 | "name": "ipython", 211 | "version": 2 212 | }, 213 | "file_extension": ".py", 214 | "mimetype": "text/x-python", 215 | "name": "python", 216 | "nbconvert_exporter": "python", 217 | "pygments_lexer": "ipython2", 218 | "version": "2.7.5" 219 | } 220 | }, 221 | "nbformat": 4, 222 | "nbformat_minor": 0 223 | } 224 | -------------------------------------------------------------------------------- /Chapter03/Single layer network example.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "**[SNE-01]** 모듈을 임포트하고 난수의 시드를 설정한다." 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import tensorflow as tf\n", 19 | "import numpy as np\n", 20 | "import matplotlib.pyplot as plt\n", 21 | "from numpy.random import multivariate_normal, permutation\n", 22 | "import pandas as pd\n", 23 | "from pandas import DataFrame, Series\n", 24 | "\n", 25 | "np.random.seed(20160614)\n", 26 | "tf.set_random_seed(20160614)" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": {}, 32 | "source": [ 33 | "**[SNE-02]** 트레이닝 세트 데이터를 생성한다." 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 2, 39 | "metadata": { 40 | "collapsed": false 41 | }, 42 | "outputs": [], 43 | "source": [ 44 | "def generate_datablock(n, mu, var, t):\n", 45 | " data = multivariate_normal(mu, np.eye(2)*var, n)\n", 46 | " df = DataFrame(data, columns=['x1','x2'])\n", 47 | " df['t'] = t\n", 48 | " return df\n", 49 | "\n", 50 | "df0 = generate_datablock(15, [7,7], 22, 0)\n", 51 | "df1 = generate_datablock(15, [22,7], 22, 0)\n", 52 | "df2 = generate_datablock(10, [7,22], 22, 0)\n", 53 | "df3 = generate_datablock(25, [20,20], 22, 1)\n", 54 | "\n", 55 | "df = pd.concat([df0, df1, df2, df3], ignore_index=True)\n", 56 | "train_set = df.reindex(permutation(df.index)).reset_index(drop=True)" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "**[SNE-03]** (x1, x2)와 t를 각각 모은 것을 NumPy의 array 오브젝트로 추출해둔다." 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 3, 69 | "metadata": { 70 | "collapsed": true 71 | }, 72 | "outputs": [], 73 | "source": [ 74 | "train_x = train_set[['x1','x2']].as_matrix()\n", 75 | "train_t = train_set['t'].as_matrix().reshape([len(train_set), 1])" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": {}, 81 | "source": [ 82 | "**[SNE-04]** 단층 신경망을 이용한 이항 분류기 모델을 정의한다." 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 4, 88 | "metadata": { 89 | "collapsed": false 90 | }, 91 | "outputs": [], 92 | "source": [ 93 | "num_units = 2\n", 94 | "mult = train_x.flatten().mean()\n", 95 | "\n", 96 | "x = tf.placeholder(tf.float32, [None, 2])\n", 97 | "\n", 98 | "w1 = tf.Variable(tf.truncated_normal([2, num_units]))\n", 99 | "b1 = tf.Variable(tf.zeros([num_units]))\n", 100 | "hidden1 = tf.nn.tanh(tf.matmul(x, w1) + b1*mult)\n", 101 | "\n", 102 | "w0 = tf.Variable(tf.zeros([num_units, 1]))\n", 103 | "b0 = tf.Variable(tf.zeros([1]))\n", 104 | "p = tf.nn.sigmoid(tf.matmul(hidden1, w0) + b0*mult)" 105 | ] 106 | }, 107 | { 108 | "cell_type": "markdown", 109 | "metadata": {}, 110 | "source": [ 111 | "**[SNE-05]** 오차 함수 loss, 트레이닝 알고리즘 train_step, 정답률 accuracy를 정의한다." 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": 5, 117 | "metadata": { 118 | "collapsed": false 119 | }, 120 | "outputs": [], 121 | "source": [ 122 | "t = tf.placeholder(tf.float32, [None, 1])\n", 123 | "loss = -tf.reduce_sum(t*tf.log(p) + (1-t)*tf.log(1-p))\n", 124 | "train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss)\n", 125 | "correct_prediction = tf.equal(tf.sign(p-0.5), tf.sign(t-0.5))\n", 126 | "accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))" 127 | ] 128 | }, 129 | { 130 | "cell_type": "markdown", 131 | "metadata": {}, 132 | "source": [ 133 | "**[SNE-06]** 세션을 준비하고 Variable을 초기화한다." 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": 6, 139 | "metadata": { 140 | "collapsed": false 141 | }, 142 | "outputs": [], 143 | "source": [ 144 | "sess = tf.InteractiveSession()\n", 145 | "sess.run(tf.initialize_all_variables())" 146 | ] 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "metadata": {}, 151 | "source": [ 152 | "**[SNE-07]** 파라미터 최적화를 1000회 반복한다." 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": 7, 158 | "metadata": { 159 | "collapsed": false, 160 | "scrolled": true 161 | }, 162 | "outputs": [ 163 | { 164 | "name": "stdout", 165 | "output_type": "stream", 166 | "text": [ 167 | "Step: 100, Loss: 44.921848, Accuracy: 0.430769\n", 168 | "Step: 200, Loss: 39.270321, Accuracy: 0.676923\n", 169 | "Step: 300, Loss: 51.999702, Accuracy: 0.584615\n", 170 | "Step: 400, Loss: 21.701561, Accuracy: 0.907692\n", 171 | "Step: 500, Loss: 12.708739, Accuracy: 0.953846\n", 172 | "Step: 600, Loss: 11.935550, Accuracy: 0.953846\n", 173 | "Step: 700, Loss: 11.454470, Accuracy: 0.953846\n", 174 | "Step: 800, Loss: 10.915851, Accuracy: 0.953846\n", 175 | "Step: 900, Loss: 10.570508, Accuracy: 0.953846\n", 176 | "Step: 1000, Loss: 11.822164, Accuracy: 0.953846\n" 177 | ] 178 | } 179 | ], 180 | "source": [ 181 | "i = 0\n", 182 | "for _ in range(1000):\n", 183 | " i += 1\n", 184 | " sess.run(train_step, feed_dict={x:train_x, t:train_t})\n", 185 | " if i % 100 == 0:\n", 186 | " loss_val, acc_val = sess.run(\n", 187 | " [loss, accuracy], feed_dict={x:train_x, t:train_t})\n", 188 | " print ('Step: %d, Loss: %f, Accuracy: %f'\n", 189 | " % (i, loss_val, acc_val))" 190 | ] 191 | }, 192 | { 193 | "cell_type": "markdown", 194 | "metadata": {}, 195 | "source": [ 196 | "**[SNE-08]** 얻어진 확률을 색의 농담으로 그림에 표시한다." 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": 8, 202 | "metadata": { 203 | "collapsed": false 204 | }, 205 | "outputs": [ 206 | { 207 | "data": { 208 | "text/plain": [ 209 | "" 210 | ] 211 | }, 212 | "execution_count": 8, 213 | "metadata": {}, 214 | "output_type": "execute_result" 215 | }, 216 | { 217 | "data": { 218 | "image/png": "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\nNTHkn7QAAAAASUVORK5CYII=\n", 219 | "text/plain": [ 220 | "" 221 | ] 222 | }, 223 | "metadata": {}, 224 | "output_type": "display_data" 225 | } 226 | ], 227 | "source": [ 228 | "train_set1 = train_set[train_set['t']==1]\n", 229 | "train_set2 = train_set[train_set['t']==0]\n", 230 | "\n", 231 | "fig = plt.figure(figsize=(6,6))\n", 232 | "subplot = fig.add_subplot(1,1,1)\n", 233 | "subplot.set_ylim([0,30])\n", 234 | "subplot.set_xlim([0,30])\n", 235 | "subplot.scatter(train_set1.x1, train_set1.x2, marker='x')\n", 236 | "subplot.scatter(train_set2.x1, train_set2.x2, marker='o')\n", 237 | "\n", 238 | "locations = []\n", 239 | "for x2 in np.linspace(0,30,100):\n", 240 | " for x1 in np.linspace(0,30,100):\n", 241 | " locations.append((x1,x2))\n", 242 | "p_vals = sess.run(p, feed_dict={x:locations})\n", 243 | "p_vals = p_vals.reshape((100,100))\n", 244 | "subplot.imshow(p_vals, origin='lower', extent=(0,30,0,30),\n", 245 | " cmap=plt.cm.gray_r, alpha=0.5)" 246 | ] 247 | } 248 | ], 249 | "metadata": { 250 | "kernelspec": { 251 | "display_name": "Python 2", 252 | "language": "python", 253 | "name": "python2" 254 | }, 255 | "language_info": { 256 | "codemirror_mode": { 257 | "name": "ipython", 258 | "version": 2 259 | }, 260 | "file_extension": ".py", 261 | "mimetype": "text/x-python", 262 | "name": "python", 263 | "nbconvert_exporter": "python", 264 | "pygments_lexer": "ipython2", 265 | "version": "2.7.5" 266 | } 267 | }, 268 | "nbformat": 4, 269 | "nbformat_minor": 0 270 | } 271 | -------------------------------------------------------------------------------- /Chapter04/MNIST dynamic filter classification with TensorBoard.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "**[MDT-01]** 필요한 모듈을 임포트하고 난수의 시드를 설정한다." 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import tensorflow as tf\n", 19 | "import numpy as np\n", 20 | "import matplotlib.pyplot as plt\n", 21 | "from tensorflow.examples.tutorials.mnist import input_data\n", 22 | "\n", 23 | "np.random.seed(20160703)\n", 24 | "tf.set_random_seed(20160703)" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "**[MDT-02]** MNIST 데이터 세트를 준비한다." 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 2, 37 | "metadata": { 38 | "collapsed": false 39 | }, 40 | "outputs": [ 41 | { 42 | "name": "stdout", 43 | "output_type": "stream", 44 | "text": [ 45 | "Extracting /tmp/data/train-images-idx3-ubyte.gz\n", 46 | "Extracting /tmp/data/train-labels-idx1-ubyte.gz\n", 47 | "Extracting /tmp/data/t10k-images-idx3-ubyte.gz\n", 48 | "Extracting /tmp/data/t10k-labels-idx1-ubyte.gz\n" 49 | ] 50 | } 51 | ], 52 | "source": [ 53 | "mnist = input_data.read_data_sets(\"/tmp/data/\", one_hot=True)" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": {}, 59 | "source": [ 60 | "**[MDT-03]** 합성곱 필터가 한 계층인 CNN을 표현하는 클래스를 정의한다." 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 3, 66 | "metadata": { 67 | "collapsed": false 68 | }, 69 | "outputs": [], 70 | "source": [ 71 | "class SingleCNN:\n", 72 | " def __init__(self, num_filters, num_units):\n", 73 | " with tf.Graph().as_default():\n", 74 | " self.prepare_model(num_filters, num_units)\n", 75 | " self.prepare_session()\n", 76 | "\n", 77 | " def prepare_model(self, num_filters, num_units):\n", 78 | " num_units1 = 14*14*num_filters\n", 79 | " num_units2 = num_units\n", 80 | " \n", 81 | " with tf.name_scope('input'):\n", 82 | " x = tf.placeholder(tf.float32, [None, 784], name='input')\n", 83 | " x_image = tf.reshape(x, [-1,28,28,1])\n", 84 | "\n", 85 | " with tf.name_scope('convolution'):\n", 86 | " W_conv = tf.Variable(\n", 87 | " tf.truncated_normal([5,5,1,num_filters], stddev=0.1),\n", 88 | " name='conv-filter')\n", 89 | " h_conv = tf.nn.conv2d(\n", 90 | " x_image, W_conv, strides=[1,1,1,1], padding='SAME',\n", 91 | " name='filter-output')\n", 92 | "\n", 93 | " with tf.name_scope('pooling'): \n", 94 | " h_pool =tf.nn.max_pool(h_conv, ksize=[1,2,2,1],\n", 95 | " strides=[1,2,2,1], padding='SAME',\n", 96 | " name='max-pool')\n", 97 | " h_pool_flat = tf.reshape(h_pool, [-1, 14*14*num_filters],\n", 98 | " name='pool-output')\n", 99 | "\n", 100 | " with tf.name_scope('fully-connected'):\n", 101 | " w2 = tf.Variable(tf.truncated_normal([num_units1, num_units2]))\n", 102 | " b2 = tf.Variable(tf.zeros([num_units2]))\n", 103 | " hidden2 = tf.nn.relu(tf.matmul(h_pool_flat, w2) + b2,\n", 104 | " name='fc-output')\n", 105 | "\n", 106 | " with tf.name_scope('softmax'):\n", 107 | " w0 = tf.Variable(tf.zeros([num_units2, 10]))\n", 108 | " b0 = tf.Variable(tf.zeros([10]))\n", 109 | " p = tf.nn.softmax(tf.matmul(hidden2, w0) + b0,\n", 110 | " name='softmax-output')\n", 111 | " \n", 112 | " with tf.name_scope('optimizer'):\n", 113 | " t = tf.placeholder(tf.float32, [None, 10], name='labels')\n", 114 | " loss = -tf.reduce_sum(t * tf.log(p), name='loss')\n", 115 | " train_step = tf.train.AdamOptimizer(0.0005).minimize(loss)\n", 116 | " \n", 117 | " with tf.name_scope('evaluator'):\n", 118 | " correct_prediction = tf.equal(tf.argmax(p, 1), tf.argmax(t, 1))\n", 119 | " accuracy = tf.reduce_mean(tf.cast(correct_prediction,\n", 120 | " tf.float32), name='accuracy')\n", 121 | " \n", 122 | " tf.scalar_summary(\"loss\", loss)\n", 123 | " tf.scalar_summary(\"accuracy\", accuracy)\n", 124 | " tf.histogram_summary(\"convolution_filters\", W_conv)\n", 125 | " \n", 126 | " self.x, self.t, self.p = x, t, p\n", 127 | " self.train_step = train_step\n", 128 | " self.loss = loss\n", 129 | " self.accuracy = accuracy\n", 130 | " \n", 131 | " def prepare_session(self):\n", 132 | " sess = tf.InteractiveSession()\n", 133 | " sess.run(tf.initialize_all_variables())\n", 134 | " summary = tf.merge_all_summaries()\n", 135 | " writer = tf.train.SummaryWriter(\"/tmp/mnist_df_logs\", sess.graph)\n", 136 | " \n", 137 | " self.sess = sess\n", 138 | " self.summary = summary\n", 139 | " self.writer = writer" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": {}, 145 | "source": [ 146 | "**[MDT-04]** 텐서보드용 데이터 출력 디렉토리를 삭제해서 초기화해둔다." 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 4, 152 | "metadata": { 153 | "collapsed": true 154 | }, 155 | "outputs": [], 156 | "source": [ 157 | "!rm -rf /tmp/mnist_df_logs" 158 | ] 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "metadata": {}, 163 | "source": [ 164 | "**[MDT-05]** 파라미터 최적화를 4000회 반복한다. 테스트 세트에 대해 약 98%의 정답률을 얻을 수 있다." 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 5, 170 | "metadata": { 171 | "collapsed": false 172 | }, 173 | "outputs": [ 174 | { 175 | "name": "stdout", 176 | "output_type": "stream", 177 | "text": [ 178 | "Step: 50, Loss: 3614.847412, Accuracy: 0.891500\n", 179 | "Step: 100, Loss: 2609.521973, Accuracy: 0.922700\n", 180 | "Step: 150, Loss: 1977.392700, Accuracy: 0.943000\n", 181 | "Step: 200, Loss: 1977.111572, Accuracy: 0.941900\n", 182 | "Step: 250, Loss: 1608.331543, Accuracy: 0.953100\n", 183 | "Step: 300, Loss: 1486.694580, Accuracy: 0.956700\n", 184 | "Step: 350, Loss: 1481.067627, Accuracy: 0.957400\n", 185 | "Step: 400, Loss: 1354.234863, Accuracy: 0.958500\n", 186 | "Step: 450, Loss: 1235.755615, Accuracy: 0.961800\n", 187 | "Step: 500, Loss: 1264.820312, Accuracy: 0.960200\n", 188 | "Step: 550, Loss: 1222.289795, Accuracy: 0.960700\n", 189 | "Step: 600, Loss: 1129.764160, Accuracy: 0.964200\n", 190 | "Step: 650, Loss: 922.128540, Accuracy: 0.970400\n", 191 | "Step: 700, Loss: 926.749451, Accuracy: 0.971600\n", 192 | "Step: 750, Loss: 850.130981, Accuracy: 0.973300\n", 193 | "Step: 800, Loss: 1006.377136, Accuracy: 0.968500\n", 194 | "Step: 850, Loss: 902.848633, Accuracy: 0.971600\n", 195 | "Step: 900, Loss: 879.976135, Accuracy: 0.973400\n", 196 | "Step: 950, Loss: 790.658813, Accuracy: 0.974500\n", 197 | "Step: 1000, Loss: 772.311646, Accuracy: 0.976400\n", 198 | "Step: 1050, Loss: 864.686768, Accuracy: 0.973400\n", 199 | "Step: 1100, Loss: 978.713928, Accuracy: 0.970500\n", 200 | "Step: 1150, Loss: 818.460205, Accuracy: 0.974500\n", 201 | "Step: 1200, Loss: 713.533203, Accuracy: 0.978000\n", 202 | "Step: 1250, Loss: 766.665405, Accuracy: 0.977500\n", 203 | "Step: 1300, Loss: 713.059326, Accuracy: 0.977900\n", 204 | "Step: 1350, Loss: 732.855713, Accuracy: 0.978200\n", 205 | "Step: 1400, Loss: 785.117920, Accuracy: 0.976200\n", 206 | "Step: 1450, Loss: 702.009766, Accuracy: 0.978200\n", 207 | "Step: 1500, Loss: 730.830994, Accuracy: 0.977600\n", 208 | "Step: 1550, Loss: 675.383972, Accuracy: 0.979400\n", 209 | "Step: 1600, Loss: 748.971619, Accuracy: 0.976100\n", 210 | "Step: 1650, Loss: 771.830017, Accuracy: 0.976100\n", 211 | "Step: 1700, Loss: 639.565613, Accuracy: 0.980300\n", 212 | "Step: 1750, Loss: 683.713196, Accuracy: 0.979300\n", 213 | "Step: 1800, Loss: 703.339600, Accuracy: 0.979600\n", 214 | "Step: 1850, Loss: 873.175293, Accuracy: 0.975100\n", 215 | "Step: 1900, Loss: 746.795959, Accuracy: 0.976100\n", 216 | "Step: 1950, Loss: 660.269104, Accuracy: 0.981900\n", 217 | "Step: 2000, Loss: 679.535522, Accuracy: 0.978800\n", 218 | "Step: 2050, Loss: 684.502258, Accuracy: 0.980800\n", 219 | "Step: 2100, Loss: 653.159485, Accuracy: 0.980300\n", 220 | "Step: 2150, Loss: 697.510498, Accuracy: 0.978000\n", 221 | "Step: 2200, Loss: 760.059631, Accuracy: 0.976500\n", 222 | "Step: 2250, Loss: 584.984192, Accuracy: 0.982200\n", 223 | "Step: 2300, Loss: 691.510559, Accuracy: 0.978800\n", 224 | "Step: 2350, Loss: 591.455200, Accuracy: 0.981300\n", 225 | "Step: 2400, Loss: 616.852417, Accuracy: 0.980700\n", 226 | "Step: 2450, Loss: 635.980469, Accuracy: 0.981400\n", 227 | "Step: 2500, Loss: 560.255432, Accuracy: 0.983500\n", 228 | "Step: 2550, Loss: 661.358276, Accuracy: 0.980700\n", 229 | "Step: 2600, Loss: 643.725891, Accuracy: 0.980300\n", 230 | "Step: 2650, Loss: 617.790283, Accuracy: 0.981200\n", 231 | "Step: 2700, Loss: 722.376465, Accuracy: 0.978500\n", 232 | "Step: 2750, Loss: 643.536377, Accuracy: 0.981200\n", 233 | "Step: 2800, Loss: 566.617554, Accuracy: 0.982500\n", 234 | "Step: 2850, Loss: 568.770386, Accuracy: 0.982900\n", 235 | "Step: 2900, Loss: 601.478210, Accuracy: 0.982700\n", 236 | "Step: 2950, Loss: 543.404175, Accuracy: 0.983500\n", 237 | "Step: 3000, Loss: 575.665955, Accuracy: 0.983100\n", 238 | "Step: 3050, Loss: 702.199829, Accuracy: 0.979400\n", 239 | "Step: 3100, Loss: 608.132996, Accuracy: 0.982500\n", 240 | "Step: 3150, Loss: 590.421326, Accuracy: 0.982800\n", 241 | "Step: 3200, Loss: 601.763428, Accuracy: 0.982400\n", 242 | "Step: 3250, Loss: 587.208557, Accuracy: 0.983300\n", 243 | "Step: 3300, Loss: 641.174927, Accuracy: 0.981000\n", 244 | "Step: 3350, Loss: 580.049927, Accuracy: 0.982500\n", 245 | "Step: 3400, Loss: 623.968872, Accuracy: 0.981500\n", 246 | "Step: 3450, Loss: 650.404968, Accuracy: 0.982100\n", 247 | "Step: 3500, Loss: 610.692810, Accuracy: 0.982800\n", 248 | "Step: 3550, Loss: 641.231934, Accuracy: 0.982500\n", 249 | "Step: 3600, Loss: 603.037048, Accuracy: 0.982100\n", 250 | "Step: 3650, Loss: 656.173950, Accuracy: 0.980400\n", 251 | "Step: 3700, Loss: 714.270569, Accuracy: 0.980300\n", 252 | "Step: 3750, Loss: 694.605713, Accuracy: 0.982600\n", 253 | "Step: 3800, Loss: 692.162842, Accuracy: 0.981700\n", 254 | "Step: 3850, Loss: 670.902039, Accuracy: 0.981600\n", 255 | "Step: 3900, Loss: 666.686890, Accuracy: 0.981700\n", 256 | "Step: 3950, Loss: 649.617554, Accuracy: 0.981500\n", 257 | "Step: 4000, Loss: 635.322693, Accuracy: 0.983000\n" 258 | ] 259 | } 260 | ], 261 | "source": [ 262 | "cnn = SingleCNN(16, 1024)\n", 263 | "\n", 264 | "i = 0\n", 265 | "for _ in range(4000):\n", 266 | " i += 1\n", 267 | " batch_xs, batch_ts = mnist.train.next_batch(100)\n", 268 | " cnn.sess.run(cnn.train_step, feed_dict={cnn.x:batch_xs, cnn.t:batch_ts})\n", 269 | " if i % 50 == 0:\n", 270 | " summary, loss_val, acc_val = cnn.sess.run(\n", 271 | " [cnn.summary, cnn.loss, cnn.accuracy],\n", 272 | " feed_dict={cnn.x:mnist.test.images, cnn.t:mnist.test.labels})\n", 273 | " print ('Step: %d, Loss: %f, Accuracy: %f'\n", 274 | " % (i, loss_val, acc_val))\n", 275 | " cnn.writer.add_summary(summary, i)" 276 | ] 277 | } 278 | ], 279 | "metadata": { 280 | "kernelspec": { 281 | "display_name": "Python 2", 282 | "language": "python", 283 | "name": "python2" 284 | }, 285 | "language_info": { 286 | "codemirror_mode": { 287 | "name": "ipython", 288 | "version": 2 289 | }, 290 | "file_extension": ".py", 291 | "mimetype": "text/x-python", 292 | "name": "python", 293 | "nbconvert_exporter": "python", 294 | "pygments_lexer": "ipython2", 295 | "version": "2.7.5" 296 | } 297 | }, 298 | "nbformat": 4, 299 | "nbformat_minor": 0 300 | } 301 | -------------------------------------------------------------------------------- /Chapter04/MNIST dynamic filter classification.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "**[MDC-01]** 필요한 모듈을 임포트하고 난수의 시드를 설정한다." 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import tensorflow as tf\n", 19 | "import numpy as np\n", 20 | "import matplotlib.pyplot as plt\n", 21 | "from tensorflow.examples.tutorials.mnist import input_data\n", 22 | "\n", 23 | "np.random.seed(20160703)\n", 24 | "tf.set_random_seed(20160703)" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "**[MDC-02]** MNIST 데이터 세트를 준비한다." 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 2, 37 | "metadata": { 38 | "collapsed": false 39 | }, 40 | "outputs": [ 41 | { 42 | "name": "stdout", 43 | "output_type": "stream", 44 | "text": [ 45 | "Extracting /tmp/data/train-images-idx3-ubyte.gz\n", 46 | "Extracting /tmp/data/train-labels-idx1-ubyte.gz\n", 47 | "Extracting /tmp/data/t10k-images-idx3-ubyte.gz\n", 48 | "Extracting /tmp/data/t10k-labels-idx1-ubyte.gz\n" 49 | ] 50 | } 51 | ], 52 | "source": [ 53 | "mnist = input_data.read_data_sets(\"/tmp/data/\", one_hot=True)" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": {}, 59 | "source": [ 60 | "**[MDC-03]** 필터에 해당하는 Variable을 준비하고 입력 데이터에 필터와 풀링 계층을 적용하는 계산식을 정의한다." 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 3, 66 | "metadata": { 67 | "collapsed": false 68 | }, 69 | "outputs": [], 70 | "source": [ 71 | "num_filters = 16\n", 72 | "\n", 73 | "x = tf.placeholder(tf.float32, [None, 784])\n", 74 | "x_image = tf.reshape(x, [-1,28,28,1])\n", 75 | "\n", 76 | "W_conv = tf.Variable(tf.truncated_normal([5,5,1,num_filters],\n", 77 | " stddev=0.1))\n", 78 | "h_conv = tf.nn.conv2d(x_image, W_conv,\n", 79 | " strides=[1,1,1,1], padding='SAME')\n", 80 | "h_pool =tf.nn.max_pool(h_conv, ksize=[1,2,2,1],\n", 81 | " strides=[1,2,2,1], padding='SAME')" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "**[MDC-04]** 풀링 계층의 출력을 전 결합층을 경유해서 소프트맥스 함수로 입력하는 계산식을 정의한다." 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": 4, 94 | "metadata": { 95 | "collapsed": false 96 | }, 97 | "outputs": [], 98 | "source": [ 99 | "h_pool_flat = tf.reshape(h_pool, [-1, 14*14*num_filters])\n", 100 | "\n", 101 | "num_units1 = 14*14*num_filters\n", 102 | "num_units2 = 1024\n", 103 | "\n", 104 | "w2 = tf.Variable(tf.truncated_normal([num_units1, num_units2]))\n", 105 | "b2 = tf.Variable(tf.zeros([num_units2]))\n", 106 | "hidden2 = tf.nn.relu(tf.matmul(h_pool_flat, w2) + b2)\n", 107 | "\n", 108 | "w0 = tf.Variable(tf.zeros([num_units2, 10]))\n", 109 | "b0 = tf.Variable(tf.zeros([10]))\n", 110 | "p = tf.nn.softmax(tf.matmul(hidden2, w0) + b0)" 111 | ] 112 | }, 113 | { 114 | "cell_type": "markdown", 115 | "metadata": {}, 116 | "source": [ 117 | "**[MDC-05]** 오차 함수 loss, 트레이닝 알고리즘 train_step, 정답률 accuracy를 정의한다." 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 5, 123 | "metadata": { 124 | "collapsed": false 125 | }, 126 | "outputs": [], 127 | "source": [ 128 | "t = tf.placeholder(tf.float32, [None, 10])\n", 129 | "loss = -tf.reduce_sum(t * tf.log(p))\n", 130 | "train_step = tf.train.AdamOptimizer(0.0005).minimize(loss)\n", 131 | "correct_prediction = tf.equal(tf.argmax(p, 1), tf.argmax(t, 1))\n", 132 | "accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))" 133 | ] 134 | }, 135 | { 136 | "cell_type": "markdown", 137 | "metadata": {}, 138 | "source": [ 139 | "**[MDC-06]** 세션을 준비하고 Variable을 초기화한다." 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": 6, 145 | "metadata": { 146 | "collapsed": false, 147 | "scrolled": false 148 | }, 149 | "outputs": [], 150 | "source": [ 151 | "sess = tf.InteractiveSession()\n", 152 | "sess.run(tf.initialize_all_variables())\n", 153 | "saver = tf.train.Saver()" 154 | ] 155 | }, 156 | { 157 | "cell_type": "markdown", 158 | "metadata": {}, 159 | "source": [ 160 | "**[MDC-07]** 파라미터 최적화를 4000회 반복한다\n", 161 | "\n", 162 | "최종적으로 테스트 세트에 대해 약 98%의 정답률을 얻을 수 있다." 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": 7, 168 | "metadata": { 169 | "collapsed": false 170 | }, 171 | "outputs": [ 172 | { 173 | "name": "stdout", 174 | "output_type": "stream", 175 | "text": [ 176 | "Step: 100, Loss: 2726.630615, Accuracy: 0.917900\n", 177 | "Step: 200, Loss: 2016.798096, Accuracy: 0.943700\n", 178 | "Step: 300, Loss: 1600.125977, Accuracy: 0.953200\n", 179 | "Step: 400, Loss: 1449.618408, Accuracy: 0.955600\n", 180 | "Step: 500, Loss: 1362.578125, Accuracy: 0.956200\n", 181 | "Step: 600, Loss: 1135.334595, Accuracy: 0.965200\n", 182 | "Step: 700, Loss: 999.617493, Accuracy: 0.969300\n", 183 | "Step: 800, Loss: 972.449707, Accuracy: 0.970200\n", 184 | "Step: 900, Loss: 941.483398, Accuracy: 0.968800\n", 185 | "Step: 1000, Loss: 886.782104, Accuracy: 0.973500\n", 186 | "Step: 1100, Loss: 921.191101, Accuracy: 0.973200\n", 187 | "Step: 1200, Loss: 691.343445, Accuracy: 0.978000\n", 188 | "Step: 1300, Loss: 727.946289, Accuracy: 0.977300\n", 189 | "Step: 1400, Loss: 761.936218, Accuracy: 0.976200\n", 190 | "Step: 1500, Loss: 742.681763, Accuracy: 0.978200\n", 191 | "Step: 1600, Loss: 924.516724, Accuracy: 0.971500\n", 192 | "Step: 1700, Loss: 670.436218, Accuracy: 0.980800\n", 193 | "Step: 1800, Loss: 655.680481, Accuracy: 0.980500\n", 194 | "Step: 1900, Loss: 792.281738, Accuracy: 0.975600\n", 195 | "Step: 2000, Loss: 723.777954, Accuracy: 0.978200\n", 196 | "Step: 2100, Loss: 635.388245, Accuracy: 0.980800\n", 197 | "Step: 2200, Loss: 747.225708, Accuracy: 0.977300\n", 198 | "Step: 2300, Loss: 701.824646, Accuracy: 0.980000\n", 199 | "Step: 2400, Loss: 669.409058, Accuracy: 0.979800\n", 200 | "Step: 2500, Loss: 701.669739, Accuracy: 0.980200\n", 201 | "Step: 2600, Loss: 793.589294, Accuracy: 0.976700\n", 202 | "Step: 2700, Loss: 677.845093, Accuracy: 0.980900\n", 203 | "Step: 2800, Loss: 654.192322, Accuracy: 0.981800\n", 204 | "Step: 2900, Loss: 667.308777, Accuracy: 0.980400\n", 205 | "Step: 3000, Loss: 765.483276, Accuracy: 0.976600\n", 206 | "Step: 3100, Loss: 646.766357, Accuracy: 0.981300\n", 207 | "Step: 3200, Loss: 693.853271, Accuracy: 0.980300\n", 208 | "Step: 3300, Loss: 738.400208, Accuracy: 0.980700\n", 209 | "Step: 3400, Loss: 708.065308, Accuracy: 0.980700\n", 210 | "Step: 3500, Loss: 701.663330, Accuracy: 0.980300\n", 211 | "Step: 3600, Loss: 656.354309, Accuracy: 0.981400\n", 212 | "Step: 3700, Loss: 671.281555, Accuracy: 0.981300\n", 213 | "Step: 3800, Loss: 731.150269, Accuracy: 0.981000\n", 214 | "Step: 3900, Loss: 708.207214, Accuracy: 0.982400\n", 215 | "Step: 4000, Loss: 708.660156, Accuracy: 0.980400\n" 216 | ] 217 | } 218 | ], 219 | "source": [ 220 | "i = 0\n", 221 | "for _ in range(4000):\n", 222 | " i += 1\n", 223 | " batch_xs, batch_ts = mnist.train.next_batch(100)\n", 224 | " sess.run(train_step, feed_dict={x: batch_xs, t: batch_ts})\n", 225 | " if i % 100 == 0:\n", 226 | " loss_val, acc_val = sess.run([loss, accuracy],\n", 227 | " feed_dict={x:mnist.test.images, t:mnist.test.labels})\n", 228 | " print ('Step: %d, Loss: %f, Accuracy: %f'\n", 229 | " % (i, loss_val, acc_val))\n", 230 | " saver.save(sess, 'mdc_session', global_step=i)" 231 | ] 232 | }, 233 | { 234 | "cell_type": "markdown", 235 | "metadata": {}, 236 | "source": [ 237 | "**[MDC-08]** 세션 정보를 저장한 파일이 생성되고 있음을 확인한다." 238 | ] 239 | }, 240 | { 241 | "cell_type": "code", 242 | "execution_count": 8, 243 | "metadata": { 244 | "collapsed": false 245 | }, 246 | "outputs": [ 247 | { 248 | "name": "stdout", 249 | "output_type": "stream", 250 | "text": [ 251 | "mdc_session-3600 mdc_session-3800 mdc_session-4000\r\n", 252 | "mdc_session-3600.meta mdc_session-3800.meta mdc_session-4000.meta\r\n", 253 | "mdc_session-3700 mdc_session-3900\r\n", 254 | "mdc_session-3700.meta mdc_session-3900.meta\r\n" 255 | ] 256 | } 257 | ], 258 | "source": [ 259 | "!ls mdc_session*" 260 | ] 261 | } 262 | ], 263 | "metadata": { 264 | "kernelspec": { 265 | "display_name": "Python 2", 266 | "language": "python", 267 | "name": "python2" 268 | }, 269 | "language_info": { 270 | "codemirror_mode": { 271 | "name": "ipython", 272 | "version": 2 273 | }, 274 | "file_extension": ".py", 275 | "mimetype": "text/x-python", 276 | "name": "python", 277 | "nbconvert_exporter": "python", 278 | "pygments_lexer": "ipython2", 279 | "version": "2.7.5" 280 | } 281 | }, 282 | "nbformat": 4, 283 | "nbformat_minor": 0 284 | } 285 | -------------------------------------------------------------------------------- /Chapter04/ORENIST classification example.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "**[OCE-01]** 필요한 모듈을 임포트하고 난수의 시드를 설정한다." 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import tensorflow as tf\n", 19 | "import numpy as np\n", 20 | "import matplotlib.pyplot as plt\n", 21 | "import cPickle as pickle\n", 22 | "\n", 23 | "np.random.seed(20160703)\n", 24 | "tf.set_random_seed(20160703)" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "**[OCE-02]** 데이터 파일 'ORENIST.data'에서 이미지와 라벨 데이터를 읽어들인다." 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 2, 37 | "metadata": { 38 | "collapsed": true 39 | }, 40 | "outputs": [], 41 | "source": [ 42 | "with open('ORENIST.data', 'rb') as file:\n", 43 | " images, labels = pickle.load(file)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "**[OCE-03]** 필터 정보를 저장한 다차원 리스트를 만드는 함수를 준비한다." 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 3, 56 | "metadata": { 57 | "collapsed": true 58 | }, 59 | "outputs": [], 60 | "source": [ 61 | "def edge_filter():\n", 62 | " filter0 = np.array(\n", 63 | " [[ 2, 1, 0,-1,-2],\n", 64 | " [ 3, 2, 0,-2,-3],\n", 65 | " [ 4, 3, 0,-3,-4],\n", 66 | " [ 3, 2, 0,-2,-3],\n", 67 | " [ 2, 1, 0,-1,-2]]) / 23.0\n", 68 | " filter1 = np.array(\n", 69 | " [[ 2, 3, 4, 3, 2],\n", 70 | " [ 1, 2, 3, 2, 1],\n", 71 | " [ 0, 0, 0, 0, 0],\n", 72 | " [-1,-2,-3,-2,-1],\n", 73 | " [-2,-3,-4,-3,-2]]) / 23.0\n", 74 | " \n", 75 | " filter_array = np.zeros([5,5,1,2])\n", 76 | " filter_array[:,:,0,0] = filter0\n", 77 | " filter_array[:,:,0,1] = filter1\n", 78 | "\n", 79 | " return tf.constant(filter_array, dtype=tf.float32)" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": {}, 85 | "source": [ 86 | "**[OCE-04]** 이미지 데이터에 필터와 풀링 계층을 적용하는 계산식을 준비한다." 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 4, 92 | "metadata": { 93 | "collapsed": false 94 | }, 95 | "outputs": [], 96 | "source": [ 97 | "x = tf.placeholder(tf.float32, [None, 784])\n", 98 | "x_image = tf.reshape(x, [-1,28,28,1])\n", 99 | "\n", 100 | "W_conv = edge_filter()\n", 101 | "h_conv = tf.abs(tf.nn.conv2d(x_image, W_conv,\n", 102 | " strides=[1,1,1,1], padding='SAME'))\n", 103 | "h_conv_cutoff = tf.nn.relu(h_conv-0.2)\n", 104 | "\n", 105 | "h_pool =tf.nn.max_pool(h_conv_cutoff, ksize=[1,2,2,1],\n", 106 | " strides=[1,2,2,1], padding='SAME')" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "**[OCE-05]** 풀링 계층의 출력을 전 결합층과 소프트맥스 함수로 된 '확장된 출력 계층'으로 입력하는 계산식을 준비한다." 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": 5, 119 | "metadata": { 120 | "collapsed": false 121 | }, 122 | "outputs": [], 123 | "source": [ 124 | "h_pool_flat = tf.reshape(h_pool, [-1, 392])\n", 125 | "\n", 126 | "num_units1 = 392\n", 127 | "num_units2 = 2\n", 128 | "\n", 129 | "w2 = tf.Variable(tf.truncated_normal([num_units1, num_units2]))\n", 130 | "b2 = tf.Variable(tf.zeros([num_units2]))\n", 131 | "hidden2 = tf.nn.tanh(tf.matmul(h_pool_flat, w2) + b2)\n", 132 | "\n", 133 | "w0 = tf.Variable(tf.zeros([num_units2, 3]))\n", 134 | "b0 = tf.Variable(tf.zeros([3]))\n", 135 | "p = tf.nn.softmax(tf.matmul(hidden2, w0) + b0)" 136 | ] 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "metadata": {}, 141 | "source": [ 142 | "**[OCE-06]** 오차 함수 loss, 트레이닝 알고리즘 train_step, 정답률 accuracy를 정의한다." 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": 6, 148 | "metadata": { 149 | "collapsed": false 150 | }, 151 | "outputs": [], 152 | "source": [ 153 | "t = tf.placeholder(tf.float32, [None, 3])\n", 154 | "loss = -tf.reduce_sum(t * tf.log(p))\n", 155 | "train_step = tf.train.AdamOptimizer().minimize(loss)\n", 156 | "correct_prediction = tf.equal(tf.argmax(p, 1), tf.argmax(t, 1))\n", 157 | "accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))" 158 | ] 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "metadata": {}, 163 | "source": [ 164 | "**[OCE-07]** 세션을 준비하고 Variable을 초기화한다." 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 7, 170 | "metadata": { 171 | "collapsed": false, 172 | "scrolled": false 173 | }, 174 | "outputs": [], 175 | "source": [ 176 | "sess = tf.InteractiveSession()\n", 177 | "sess.run(tf.initialize_all_variables())" 178 | ] 179 | }, 180 | { 181 | "cell_type": "markdown", 182 | "metadata": {}, 183 | "source": [ 184 | "**[OCE-08]** 파라미터 최적화를 200회 반복한다.\n", 185 | "\n", 186 | "대략 100회 반복하면 100%의 정답률이 달성된다." 187 | ] 188 | }, 189 | { 190 | "cell_type": "code", 191 | "execution_count": 8, 192 | "metadata": { 193 | "collapsed": false 194 | }, 195 | "outputs": [ 196 | { 197 | "name": "stdout", 198 | "output_type": "stream", 199 | "text": [ 200 | "Step: 10, Loss: 97.706993, Accuracy: 0.788889\n", 201 | "Step: 20, Loss: 96.378815, Accuracy: 0.822222\n", 202 | "Step: 30, Loss: 94.918198, Accuracy: 0.833333\n", 203 | "Step: 40, Loss: 93.346489, Accuracy: 0.911111\n", 204 | "Step: 50, Loss: 91.696594, Accuracy: 0.922222\n", 205 | "Step: 60, Loss: 89.997673, Accuracy: 0.933333\n", 206 | "Step: 70, Loss: 88.272461, Accuracy: 0.966667\n", 207 | "Step: 80, Loss: 86.562065, Accuracy: 0.988889\n", 208 | "Step: 90, Loss: 84.892670, Accuracy: 1.000000\n", 209 | "Step: 100, Loss: 83.274239, Accuracy: 1.000000\n", 210 | "Step: 110, Loss: 81.711754, Accuracy: 1.000000\n", 211 | "Step: 120, Loss: 80.205574, Accuracy: 1.000000\n", 212 | "Step: 130, Loss: 78.751511, Accuracy: 1.000000\n", 213 | "Step: 140, Loss: 77.344215, Accuracy: 1.000000\n", 214 | "Step: 150, Loss: 75.978912, Accuracy: 1.000000\n", 215 | "Step: 160, Loss: 74.651871, Accuracy: 1.000000\n", 216 | "Step: 170, Loss: 73.360245, Accuracy: 1.000000\n", 217 | "Step: 180, Loss: 72.101730, Accuracy: 1.000000\n", 218 | "Step: 190, Loss: 70.874496, Accuracy: 1.000000\n", 219 | "Step: 200, Loss: 69.676971, Accuracy: 1.000000\n" 220 | ] 221 | } 222 | ], 223 | "source": [ 224 | "i = 0\n", 225 | "for _ in range(200):\n", 226 | " i += 1\n", 227 | " sess.run(train_step, feed_dict={x:images, t:labels})\n", 228 | " if i % 10 == 0:\n", 229 | " loss_val, acc_val = sess.run(\n", 230 | " [loss, accuracy], feed_dict={x:images, t:labels})\n", 231 | " print ('Step: %d, Loss: %f, Accuracy: %f'\n", 232 | " % (i, loss_val, acc_val))" 233 | ] 234 | }, 235 | { 236 | "cell_type": "markdown", 237 | "metadata": {}, 238 | "source": [ 239 | "**[OCE-09]** 각각의 데이터의 특징변수 (z1, z2)를 산포도로 나타낸다." 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": 9, 245 | "metadata": { 246 | "collapsed": false, 247 | "scrolled": true 248 | }, 249 | "outputs": [ 250 | { 251 | "data": { 252 | "text/plain": [ 253 | "" 254 | ] 255 | }, 256 | "execution_count": 9, 257 | "metadata": {}, 258 | "output_type": "execute_result" 259 | }, 260 | { 261 | "data": { 262 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAUkAAAE4CAYAAADW9AHMAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAADxlJREFUeJzt3F2sZXV5x/HvbzrlQptQaGQkKNSoaDRp0IsRY5PZSWMd\nmsbBhNSXC6sXSmy9Myk0kszhTm56YdFQG2IgqUFv1AEkHYxsDTEqERBtGBjTigPiaIKYUk1D4OnF\n2ZDD9OznvOx19svw/SQn7Jf/WethMfNl7b3XOakqJEmb27foASRpmRlJSWoYSUlqGElJahhJSWoY\nSUlqDBLJJDcnOZ3koSnPH0rydJL7J1/XDbFfSdpr+wfazheBfwZubdZ8p6reO9D+JGkuBjmTrKp7\ngd9ssSxD7EuS5mme70m+M8mDSe5M8pY57leSdm2ol9tb+SFwcVX9LskVwNeAS+e0b0natblEsqqe\n2XD7riSfT3J+VT115tok/jC5pD1RVTt+22/Il9thyvuOSQ5suH0QyGaBfEFVrdzX0aNHFz7Dy232\nVZ17lWdf1bmrdn/uNciZZJIvASPgT5L8HDgKnLPeu/oCcFWSTwDPAr8H3j/EfiVprw0Syar60BbP\nfw743BD7kqR58iduBjIajRY9wq6t6uyrOjes7uyrOvcsMstr9b2QpJZtJkmrLwm14A9uJOmsYyQl\nqWEkJalhJCWpYSQlqWEkJalhJCWpYSQlqWEkJalhJCWpYSQlqWEkJalhJCWpYSQlqWEkJalhJCWp\nYSQlqWEkJalhJCWpYSQlqWEkJalhJCWpYSQlqWEkJalhJCWpYSQlqWEkJalhJCWpYSQlqWEkJalh\nJCWpYSQlqWEkJamxf9EDnC0SOHQIRqP1+2tri5xG0lBSVYue4SWS1LLNtB3JS++v4L+CdFZLQlVl\n65Uv5cttSWoMEskkNyc5neShZs1nk5xM8mCSy4bYryTttaHOJL8IvGfak0muAF5fVW8ErgZuGmi/\nkrSnBolkVd0L/KZZcgS4dbL2+8C5SQ4MsW9J2kvzek/yIuDUhvtPTB6TpKW2lJcArW24fmY0GjF6\n4bqaBTvzE+zdrD161MuDtFzW1uD664fZ1jJd1TEejxmPxzNvZ7BLgJJcAtxeVX+2yXM3AfdU1Zcn\n908Ah6rq9CZrl/YSoH37dveHIIHnnx9+HknbtwyXAGXytZljwIcBklwOPL1ZIJfdxRfP9/skLd5Q\nlwB9CfgucGmSnyf5aJKrk3wcoKq+AfxXkp8C/wL83RD7nbePfGS+3ydp8fyJm4H4EzfScluGl9tn\nvbW19Rhu9nWmjc/5QY20ujyTHIhnktJy2+2Z5FJeArSqNv4WIElnB88kB5J49igtM9+TlKQ9YCQl\nqWEkJalhJAdy9OiiJ5C0F/zgRtLLgh/cSNIeMJKS1DCSktQwkpLUMJKS1DCSktQwkpLUMJKS1DCS\nktQwkpLUMJKS1DCSktQwkpLUMJKS1DCSktQwkpLUMJKS1DCSktQwkpLUMJKS1DCSktQwkpLUMJKS\n1DCSktQwkpLUMJKS1DCSktQwkpLUGCSSSQ4nOZHk0STXbPL8oSRPJ7l/8nXdEPuVpL22f9YNJNkH\n3Aj8BfAL4L4kX6+qE2cs/U5VvXfW/UnSPA1xJnkQOFlVj1XVs8BtwJFN1mWAfUnSXA0RyYuAUxvu\nPz557EzvTPJgkjuTvGWA/UrSnpv55fY2/RC4uKp+l+QK4GvApXPatyTt2hCRfAK4eMP910wee1FV\nPbPh9l1JPp/k/Kp6arMNrq2tvXh7NBoxGo0GGFPSy8l4PGY8Hs+8nVTVbBtI/gB4hPUPbp4EfgB8\nsKoe3rDmQFWdntw+CHylqv50yvZq1pkk6UxJqKodfzYy85lkVT2X5JPAcdbf47y5qh5OcvX60/UF\n4KoknwCeBX4PvH/W/UrSPMx8Jjk0zyQl7YXdnkn6EzeS1DCSktQwkpLUMJKS1DCSktQwkpLUMJKS\n1DCSktQwkpLUMJKS1DCSktQwkpLUMJKS1DCSktQwkpLUMJKS1DCSktQwkpLUMJKS1DCSktQwkpLU\nMJKS1DCSktQwkpLUMJKS1DCSktQwkpLUMJKS1DCSktQwkpLUMJKS1DCSktQwkpLUMJKS1DCSktQw\nkpLUMJKS1DCSktQYJJJJDic5keTRJNdMWfPZJCeTPJjksiH2K0l7beZIJtkH3Ai8B3gr8MEkbz5j\nzRXA66vqjcDVwE2z7leS5mGIM8mDwMmqeqyqngVuA46cseYIcCtAVX0fODfJgQH2LUl7aohIXgSc\n2nD/8clj3ZonNlkjSUtn/6IH2Mza2tqLt0ejEaPRaGGzSFpN4/GY8Xg883ZSVbNtILkcWKuqw5P7\n1wJVVTdsWHMTcE9VfXly/wRwqKpOb7K9mnUmSTpTEqoqO/2+IV5u3we8IcklSc4BPgAcO2PNMeDD\n8GJUn94skJK0bGZ+uV1VzyX5JHCc9ejeXFUPJ7l6/en6QlV9I8lfJfkp8D/AR2fdryTNw8wvt4fm\ny21Je2GRL7cl6axlJCWpYSQlqWEkJalhJCWpYSQlqWEkJalhJCWpYSQlqWEkJalhJCWpYSQlqWEk\nJalhJCWpYSQlqWEkJalhJCWpYSQlqWEkJalhJCWpYSQlqWEkJalhJCWpYSQlqWEkJalhJCWpYSQl\nqWEkJalhJCWpYSQlqWEkJalhJCWpYSQlqWEkJalhJCWpYSQlqWEkJamxf5ZvTnIe8GXgEuBnwN9U\n1W83Wfcz4LfA88CzVXVwlv1K0rzMeiZ5LfDNqnoT8C3gH6esex4YVdXbDKSkVTJrJI8At0xu3wJc\nOWVdBtiXJM3drOG6oKpOA1TVL4ELpqwr4O4k9yX52Iz7lKS52fI9ySR3Awc2PsR69K7bZHlN2cy7\nqurJJK9iPZYPV9W9O55WkuZsy0hW1bunPZfkdJIDVXU6yauBX03ZxpOTf/46yVeBg8DUSK6trb14\nezQaMRqNthpTkl5iPB4zHo9n3k6qpp38beObkxuAp6rqhiTXAOdV1bVnrHkFsK+qnknySuA4cH1V\nHZ+yzZplJknaTBKqKjv+vhkjeT7wFeC1wGOsXwL0dJILgX+tqr9O8jrgq6y/FN8P/FtVfabZppGU\nNLiFRHIvGElJe2G3kfSyHElqGElJahhJSWoYSUlqGElJahhJSWoYSUlqGElJahhJSWoYSUlqGElJ\nahhJSWoYSUlqGElJahhJSWoYSUlqGElJahhJSWoYSUlqGElJahhJSWoYSUlqGElJahhJSWoYSUlq\nGElJahhJSWoYSUlqGElJahjJgaytLXoCSXshVbXoGV4iSS3bTNuRwAqOLb1sJKGqstPv80xSkhpG\nUpIaRlKSGkZSkhpGUpIaRlKSGkZSkhozRTLJVUl+kuS5JG9v1h1OciLJo0mumWWfkjRPs55J/hh4\nH/DtaQuS7ANuBN4DvBX4YJI3z7hfSZqL/bN8c1U9ApCku4r9IHCyqh6brL0NOAKcmGXfkjQP83hP\n8iLg1Ib7j08ek6Slt+WZZJK7gQMbHwIK+HRV3b4XQ61t+G0Ro9GI0Wi0F7uRdBYbj8eMx+OZtzPI\nL7hIcg/wqaq6f5PnLgfWqurw5P61QFXVDVO25S+4kDS4ZfgFF9N2fh/whiSXJDkH+ABwbMD9StKe\nmfUSoCuTnAIuB+5Ictfk8QuT3AFQVc8BnwSOA/8B3FZVD882tiTNh79PciC+3JaW2zK83Jaks46R\nlKSGkZSkhpEciO9HSmcnIylJDSMpSQ0jKUkNIylJDSMpSQ0jKUkNIylJDSMpSQ0jKUkNIylJDSMp\nSQ0jKUkNIylJDSMpSQ0jKUkNIylJDSMpSQ0jKUkNIylJDSMpSQ0jKUkNIylJDSMpSQ0jKUkNIylJ\nDSMpSQ0jKUkNIylJDSMpSQ0jKUkNIylJDSMpSQ0jKUmNmSKZ5KokP0nyXJK3N+t+luRHSR5I8oNZ\n9ilJ8zTrmeSPgfcB395i3fPAqKreVlUHZ9znUhqPx4seYddWdfZVnRtWd/ZVnXsWM0Wyqh6pqpNA\ntliaWfe17Fb5D8+qzr6qc8Pqzr6qc89iXuEq4O4k9yX52Jz2KUkz27/VgiR3Awc2PsR69D5dVbdv\ncz/vqqonk7yK9Vg+XFX37nxcSZqvVNXsG0nuAT5VVfdvY+1R4L+r6p+mPD/7QJK0iara6q3B/2fL\nM8kd2HTnSV4B7KuqZ5K8EvhL4PppG9nNv4Qk7ZVZLwG6Mskp4HLgjiR3TR6/MMkdk2UHgHuTPAB8\nD7i9qo7Psl9JmpdBXm5L0tlqoZflrPLF6DuY/XCSE0keTXLNPGecMs95SY4neSTJvyc5d8q6pTnm\n2zmGST6b5GSSB5NcNu8ZN7PV3EkOJXk6yf2Tr+sWMeeZktyc5HSSh5o1S3e8YevZd3XMq2phX8Cb\ngDcC3wLe3qz7T+C8Rc66m9lZ/5/QT4FLgD8EHgTevOC5bwD+YXL7GuAzy3zMt3MMgSuAOye33wF8\nb0XmPgQcW/Ssm8z+58BlwENTnl+6472D2Xd8zBd6JlkrfDH6Nmc/CJysqseq6lngNuDIXAac7ghw\ny+T2LcCVU9YtyzHfzjE8AtwKUFXfB85NcoDF2u5/+6X7oLLWL8/7TbNkGY83sK3ZYYfHfBn+EmzH\nql6MfhFwasP9xyePLdIFVXUaoKp+CVwwZd2yHPPtHMMz1zyxyZp52+5/+3dOXrLemeQt8xltZst4\nvHdiR8d8yEuANrXKF6MPNPvcNXNv9v7LtE/u/AGAvfdD4OKq+l2SK4CvAZcueKaz3Y6P+Z5Hsqre\nPcA2npz889dJvsr6S5k9/ws7wOxPABdvuP+ayWN7qpt78qb2gao6neTVwK+mbGMhx3wT2zmGTwCv\n3WLNvG05d1U9s+H2XUk+n+T8qnpqTjPu1jIe723ZzTFfppfbUy9GT/JHk9svXIz+k3kOtg3T3uO4\nD3hDkkuSnAN8ADg2v7E2dQz4yOT23wJfP3PBkh3z7RzDY8CHAZJcDjz9wlsKC7Tl3Bvfx0tykPVL\n8pYlkGH6n+tlPN4bTZ19V8d8wZ9EXcn6exu/B54E7po8fiFwx+T261j/ZPAB1n8127WL/gRtu7NP\n7h8GHgFOLsPswPnANyczHQf+eNmP+WbHELga+PiGNTey/mnyj2iulFimuYG/Z/1/Pg8A3wXeseiZ\nJ3N9CfgF8L/Az4GPrsLx3s7suznmXkwuSY1lerktSUvHSEpSw0hKUsNISlLDSEpSw0hKUsNISlLD\nSEpS4/8AsuLUa0xZJpcAAAAASUVORK5CYII=\n", 263 | "text/plain": [ 264 | "" 265 | ] 266 | }, 267 | "metadata": {}, 268 | "output_type": "display_data" 269 | } 270 | ], 271 | "source": [ 272 | "hidden2_vals = sess.run(hidden2, feed_dict={x:images})\n", 273 | "\n", 274 | "z1_vals = [[],[],[]]\n", 275 | "z2_vals = [[],[],[]]\n", 276 | "\n", 277 | "for hidden2_val, label in zip(hidden2_vals, labels):\n", 278 | " label_num = np.argmax(label)\n", 279 | " z1_vals[label_num].append(hidden2_val[0])\n", 280 | " z2_vals[label_num].append(hidden2_val[1])\n", 281 | " \n", 282 | "fig = plt.figure(figsize=(5,5))\n", 283 | "subplot = fig.add_subplot(1,1,1)\n", 284 | "subplot.scatter(z1_vals[0], z2_vals[0], s=200, marker='|')\n", 285 | "subplot.scatter(z1_vals[1], z2_vals[1], s=200, marker='_')\n", 286 | "subplot.scatter(z1_vals[2], z2_vals[2], s=200, marker='+')" 287 | ] 288 | } 289 | ], 290 | "metadata": { 291 | "kernelspec": { 292 | "display_name": "Python 2", 293 | "language": "python", 294 | "name": "python2" 295 | }, 296 | "language_info": { 297 | "codemirror_mode": { 298 | "name": "ipython", 299 | "version": 2 300 | }, 301 | "file_extension": ".py", 302 | "mimetype": "text/x-python", 303 | "name": "python", 304 | "nbconvert_exporter": "python", 305 | "pygments_lexer": "ipython2", 306 | "version": "2.7.5" 307 | } 308 | }, 309 | "nbformat": 4, 310 | "nbformat_minor": 0 311 | } 312 | -------------------------------------------------------------------------------- /Chapter05/MNIST double layer CNN classification.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "**[CNN-01]** 필요한 모듈을 임포트하고 난수의 시드를 설정한다." 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import tensorflow as tf\n", 19 | "import numpy as np\n", 20 | "import matplotlib.pyplot as plt\n", 21 | "from tensorflow.examples.tutorials.mnist import input_data\n", 22 | "\n", 23 | "np.random.seed(20160704)\n", 24 | "tf.set_random_seed(20160704)" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "**[CNN-02]** MNIST 데이터 세트를 준비한다." 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 2, 37 | "metadata": { 38 | "collapsed": false 39 | }, 40 | "outputs": [ 41 | { 42 | "name": "stdout", 43 | "output_type": "stream", 44 | "text": [ 45 | "Extracting /tmp/data/train-images-idx3-ubyte.gz\n", 46 | "Extracting /tmp/data/train-labels-idx1-ubyte.gz\n", 47 | "Extracting /tmp/data/t10k-images-idx3-ubyte.gz\n", 48 | "Extracting /tmp/data/t10k-labels-idx1-ubyte.gz\n" 49 | ] 50 | } 51 | ], 52 | "source": [ 53 | "mnist = input_data.read_data_sets(\"/tmp/data/\", one_hot=True)" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": {}, 59 | "source": [ 60 | "**[CNN-03]** 첫 번째 단계의 합성곱 필터와 풀링 계층을 정의한다." 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 3, 66 | "metadata": { 67 | "collapsed": false 68 | }, 69 | "outputs": [], 70 | "source": [ 71 | "num_filters1 = 32\n", 72 | "\n", 73 | "x = tf.placeholder(tf.float32, [None, 784])\n", 74 | "x_image = tf.reshape(x, [-1,28,28,1])\n", 75 | "\n", 76 | "W_conv1 = tf.Variable(tf.truncated_normal([5,5,1,num_filters1],\n", 77 | " stddev=0.1))\n", 78 | "h_conv1 = tf.nn.conv2d(x_image, W_conv1,\n", 79 | " strides=[1,1,1,1], padding='SAME')\n", 80 | "\n", 81 | "b_conv1 = tf.Variable(tf.constant(0.1, shape=[num_filters1]))\n", 82 | "h_conv1_cutoff = tf.nn.relu(h_conv1 + b_conv1)\n", 83 | "\n", 84 | "h_pool1 = tf.nn.max_pool(h_conv1_cutoff, ksize=[1,2,2,1],\n", 85 | " strides=[1,2,2,1], padding='SAME')" 86 | ] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "metadata": {}, 91 | "source": [ 92 | "**[CNN-04]** 두 번째 단계의 합성곱 필터와 풀링 계층을 정의한다." 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": 4, 98 | "metadata": { 99 | "collapsed": false 100 | }, 101 | "outputs": [], 102 | "source": [ 103 | "num_filters2 = 64\n", 104 | "\n", 105 | "W_conv2 = tf.Variable(\n", 106 | " tf.truncated_normal([5,5,num_filters1,num_filters2],\n", 107 | " stddev=0.1))\n", 108 | "h_conv2 = tf.nn.conv2d(h_pool1, W_conv2,\n", 109 | " strides=[1,1,1,1], padding='SAME')\n", 110 | "\n", 111 | "b_conv2 = tf.Variable(tf.constant(0.1, shape=[num_filters2]))\n", 112 | "h_conv2_cutoff = tf.nn.relu(h_conv2 + b_conv2)\n", 113 | "\n", 114 | "h_pool2 = tf.nn.max_pool(h_conv2_cutoff, ksize=[1,2,2,1],\n", 115 | " strides=[1,2,2,1], padding='SAME')" 116 | ] 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "metadata": {}, 121 | "source": [ 122 | "**[CNN-05]** 전 결합층, 드롭아웃 계층, 소프트맥스 함수를 정의한다." 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 5, 128 | "metadata": { 129 | "collapsed": false 130 | }, 131 | "outputs": [], 132 | "source": [ 133 | "h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*num_filters2])\n", 134 | "\n", 135 | "num_units1 = 7*7*num_filters2\n", 136 | "num_units2 = 1024\n", 137 | "\n", 138 | "w2 = tf.Variable(tf.truncated_normal([num_units1, num_units2]))\n", 139 | "b2 = tf.Variable(tf.constant(0.1, shape=[num_units2]))\n", 140 | "hidden2 = tf.nn.relu(tf.matmul(h_pool2_flat, w2) + b2)\n", 141 | "\n", 142 | "keep_prob = tf.placeholder(tf.float32)\n", 143 | "hidden2_drop = tf.nn.dropout(hidden2, keep_prob)\n", 144 | "\n", 145 | "w0 = tf.Variable(tf.zeros([num_units2, 10]))\n", 146 | "b0 = tf.Variable(tf.zeros([10]))\n", 147 | "p = tf.nn.softmax(tf.matmul(hidden2_drop, w0) + b0)" 148 | ] 149 | }, 150 | { 151 | "cell_type": "markdown", 152 | "metadata": {}, 153 | "source": [ 154 | "**[CNN-06]** 오차 함수 loss, 트레이닝 알고리즘 train_step, 정답률 accuracy을 정의한다." 155 | ] 156 | }, 157 | { 158 | "cell_type": "code", 159 | "execution_count": 6, 160 | "metadata": { 161 | "collapsed": true 162 | }, 163 | "outputs": [], 164 | "source": [ 165 | "t = tf.placeholder(tf.float32, [None, 10])\n", 166 | "loss = -tf.reduce_sum(t * tf.log(p))\n", 167 | "train_step = tf.train.AdamOptimizer(0.0001).minimize(loss)\n", 168 | "correct_prediction = tf.equal(tf.argmax(p, 1), tf.argmax(t, 1))\n", 169 | "accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))" 170 | ] 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "metadata": {}, 175 | "source": [ 176 | "**[CNN-07]** 세션을 준비하고 Variable을 초기화한다." 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": 7, 182 | "metadata": { 183 | "collapsed": true 184 | }, 185 | "outputs": [], 186 | "source": [ 187 | "sess = tf.InteractiveSession()\n", 188 | "sess.run(tf.initialize_all_variables())\n", 189 | "saver = tf.train.Saver()" 190 | ] 191 | }, 192 | { 193 | "cell_type": "markdown", 194 | "metadata": {}, 195 | "source": [ 196 | "**[CNN-08]** 파라미터 최적화를 20000회 반복한다.\n", 197 | "\n", 198 | "최종적으로 테스트 세트에 대해 약 99%의 정답률을 얻을 수 있다." 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": 8, 204 | "metadata": { 205 | "collapsed": false 206 | }, 207 | "outputs": [ 208 | { 209 | "name": "stdout", 210 | "output_type": "stream", 211 | "text": [ 212 | "Step: 500, Loss: 1539.889160, Accuracy: 0.955600\n", 213 | "Step: 1000, Loss: 972.987549, Accuracy: 0.971700\n", 214 | "Step: 1500, Loss: 789.961914, Accuracy: 0.974000\n", 215 | "Step: 2000, Loss: 643.896973, Accuracy: 0.978400\n", 216 | "Step: 2500, Loss: 602.963257, Accuracy: 0.980900\n", 217 | "Step: 3000, Loss: 555.896484, Accuracy: 0.981900\n", 218 | "Step: 3500, Loss: 457.530762, Accuracy: 0.985300\n", 219 | "Step: 4000, Loss: 430.855194, Accuracy: 0.987000\n", 220 | "Step: 4500, Loss: 404.523743, Accuracy: 0.986600\n", 221 | "Step: 5000, Loss: 407.742065, Accuracy: 0.987100\n", 222 | "Step: 5500, Loss: 374.555054, Accuracy: 0.988300\n", 223 | "Step: 6000, Loss: 382.756165, Accuracy: 0.986900\n", 224 | "Step: 6500, Loss: 355.421509, Accuracy: 0.988000\n", 225 | "Step: 7000, Loss: 355.007141, Accuracy: 0.988900\n", 226 | "Step: 7500, Loss: 327.024780, Accuracy: 0.989300\n", 227 | "Step: 8000, Loss: 340.774933, Accuracy: 0.988000\n", 228 | "Step: 8500, Loss: 347.032379, Accuracy: 0.988300\n", 229 | "Step: 9000, Loss: 311.977875, Accuracy: 0.990400\n", 230 | "Step: 9500, Loss: 337.671753, Accuracy: 0.988700\n", 231 | "Step: 10000, Loss: 319.527100, Accuracy: 0.989600\n", 232 | "Step: 10500, Loss: 293.324158, Accuracy: 0.990500\n", 233 | "Step: 11000, Loss: 288.691833, Accuracy: 0.990200\n", 234 | "Step: 11500, Loss: 294.355652, Accuracy: 0.990100\n", 235 | "Step: 12000, Loss: 308.601837, Accuracy: 0.990600\n", 236 | "Step: 12500, Loss: 300.200623, Accuracy: 0.989800\n", 237 | "Step: 13000, Loss: 294.467682, Accuracy: 0.991200\n", 238 | "Step: 13500, Loss: 273.863708, Accuracy: 0.991600\n", 239 | "Step: 14000, Loss: 282.099548, Accuracy: 0.990800\n", 240 | "Step: 14500, Loss: 274.422974, Accuracy: 0.991200\n", 241 | "Step: 15000, Loss: 269.755096, Accuracy: 0.991300\n", 242 | "Step: 15500, Loss: 273.898376, Accuracy: 0.991600\n", 243 | "Step: 16000, Loss: 253.827591, Accuracy: 0.991900\n", 244 | "Step: 16500, Loss: 273.175781, Accuracy: 0.991500\n", 245 | "Step: 17000, Loss: 278.549866, Accuracy: 0.990100\n", 246 | "Step: 17500, Loss: 278.320190, Accuracy: 0.991500\n", 247 | "Step: 18000, Loss: 258.416412, Accuracy: 0.991200\n", 248 | "Step: 18500, Loss: 285.394806, Accuracy: 0.990900\n", 249 | "Step: 19000, Loss: 290.716187, Accuracy: 0.991000\n", 250 | "Step: 19500, Loss: 272.024597, Accuracy: 0.991600\n", 251 | "Step: 20000, Loss: 269.107910, Accuracy: 0.991800\n" 252 | ] 253 | } 254 | ], 255 | "source": [ 256 | "i = 0\n", 257 | "for _ in range(20000):\n", 258 | " i += 1\n", 259 | " batch_xs, batch_ts = mnist.train.next_batch(50)\n", 260 | " sess.run(train_step,\n", 261 | " feed_dict={x:batch_xs, t:batch_ts, keep_prob:0.5})\n", 262 | " if i % 500 == 0:\n", 263 | " loss_vals, acc_vals = [], []\n", 264 | " for c in range(4):\n", 265 | " start = len(mnist.test.labels) / 4 * c\n", 266 | " end = len(mnist.test.labels) / 4 * (c+1)\n", 267 | " loss_val, acc_val = sess.run([loss, accuracy],\n", 268 | " feed_dict={x:mnist.test.images[start:end],\n", 269 | " t:mnist.test.labels[start:end],\n", 270 | " keep_prob:1.0})\n", 271 | " loss_vals.append(loss_val)\n", 272 | " acc_vals.append(acc_val)\n", 273 | " loss_val = np.sum(loss_vals)\n", 274 | " acc_val = np.mean(acc_vals)\n", 275 | " print ('Step: %d, Loss: %f, Accuracy: %f'\n", 276 | " % (i, loss_val, acc_val))\n", 277 | " saver.save(sess, 'cnn_session', global_step=i)" 278 | ] 279 | }, 280 | { 281 | "cell_type": "markdown", 282 | "metadata": {}, 283 | "source": [ 284 | "**[CNN-09]** 세션 정보를 저장한 파일이 생성되고 있음을 확인한다." 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "execution_count": 9, 290 | "metadata": { 291 | "collapsed": false 292 | }, 293 | "outputs": [ 294 | { 295 | "name": "stdout", 296 | "output_type": "stream", 297 | "text": [ 298 | "cnn_session-18000\tcnn_session-19000\tcnn_session-20000\r\n", 299 | "cnn_session-18000.meta\tcnn_session-19000.meta\tcnn_session-20000.meta\r\n", 300 | "cnn_session-18500\tcnn_session-19500\r\n", 301 | "cnn_session-18500.meta\tcnn_session-19500.meta\r\n" 302 | ] 303 | } 304 | ], 305 | "source": [ 306 | "!ls cnn_session*" 307 | ] 308 | } 309 | ], 310 | "metadata": { 311 | "kernelspec": { 312 | "display_name": "Python 2", 313 | "language": "python", 314 | "name": "python2" 315 | }, 316 | "language_info": { 317 | "codemirror_mode": { 318 | "name": "ipython", 319 | "version": 2 320 | }, 321 | "file_extension": ".py", 322 | "mimetype": "text/x-python", 323 | "name": "python", 324 | "nbconvert_exporter": "python", 325 | "pygments_lexer": "ipython2", 326 | "version": "2.7.5" 327 | } 328 | }, 329 | "nbformat": 4, 330 | "nbformat_minor": 0 331 | } 332 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # 텐서플로로 시작하는 딥러닝 3 | 4 | ![텐서플로로 시작하는 딥러닝 표지](http://image.kyobobook.co.kr/images/book/large/876/l9791185890876.jpg) 5 | 6 | **출판사** 제이펍 7 | **원출판사** 마이나비출판(マイナビ出版) 8 | **원서명** TensorFlowで学ぶディープラーニング入門(원서 ISBN: 9784839960889) 9 | **저자명** 나카이 에츠지 10 | **역자명** 진명조 11 | **출판일** 2017년 7월 12일 12 | **페이지** 256쪽 13 | **시리즈** I♥A.I. 05 14 | **ISBN** 979-11-85890-87-6 (93000) 15 | 16 | [### 도서 소개 페이지 바로 가기 ###](http://jpub.tistory.com/695) 17 | 18 | 19 | -------------------------------------------------------------------------------- /텐서플로 최신 버전 지원 가이드.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jpub/TensorflowDeeplearning/aee360988bb348b3649ff7a9678e6fc81b3678b6/텐서플로 최신 버전 지원 가이드.pdf --------------------------------------------------------------------------------