{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# CS 20 : TensorFlow for Deep Learning Research\n", "## Lecture 07 : ConvNet in TensorFlow\n", "### ConvNet mnist by low-level\n", "- Creating the **data pipeline** with `tf.data`\n", "- Creating the model as **Class** with `tf.nn`\n", "- Training the model with **Drop out** technique by `tf.nn.dropout`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Setup" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.12.0\n" ] } ], "source": [ "from __future__ import absolute_import, division, print_function\n", "import os, sys\n", "import numpy as np\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import tensorflow as tf\n", "%matplotlib inline\n", "\n", "print(tf.__version__)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Load and Pre-process data" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "(x_train, y_train), (x_tst, y_tst) = tf.keras.datasets.mnist.load_data()\n", "x_train = x_train / 255\n", "x_train = x_train.reshape(-1, 28, 28, 1).astype(np.float32)\n", "x_tst = x_tst / 255\n", "x_tst = x_tst.reshape(-1, 28, 28, 1).astype(np.float32)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(55000, 28, 28, 1) (55000,)\n", "(5000, 28, 28, 1) (5000,)\n" ] } ], "source": [ "tr_indices = np.random.choice(range(x_train.shape[0]), size = 55000, replace = False)\n", "\n", "x_tr = x_train[tr_indices]\n", "y_tr = y_train[tr_indices].astype(np.int32)\n", "\n", "x_val = np.delete(arr = x_train, obj = tr_indices, axis = 0)\n", "y_val = np.delete(arr = y_train, obj = tr_indices, axis = 0).astype(np.int32)\n", "\n", "print(x_tr.shape, y_tr.shape)\n", "print(x_val.shape, y_val.shape)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Define SimpleCNN class by low-level api" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "class SimpleCNN:\n", " def __init__(self, X, y, n_of_classes):\n", " \n", " self._X = X\n", " self._y = y\n", " self._keep_prob = tf.placeholder(dtype = tf.float32)\n", " \n", " conv1 = self._conv_relu(inputs = self._X, filters = 32, k_size = 5, stride = 1, padding = 'SAME',\n", " scope_name = 'conv1')\n", " pool1 = self._max_pool(inputs = conv1, k_size = 2, stride = 2, padding = 'SAME',\n", " scope_name = 'pool1')\n", " conv2 = self._conv_relu(inputs = pool1, filters = 64, k_size = 5, stride = 1, padding = 'SAME',\n", " scope_name = 'conv2')\n", " pool2 = self._max_pool(inputs = conv2, k_size = 2, stride = 2, padding = 'SAME',\n", " scope_name = 'pool2')\n", " flat_dim = pool2.get_shape().as_list()[1:]\n", " flattened = tf.reshape(tensor = pool2, shape = [-1,flat_dim[0] * flat_dim[1] * flat_dim[2]])\n", "\n", " pre_fc = self._fully_connected(inputs = flattened, out_dim = 1024, scope_name = 'fc1')\n", " fc = tf.nn.relu(pre_fc)\n", " dropped = tf.nn.dropout(x = fc, keep_prob = self._keep_prob)\n", " \n", " self._score = self._fully_connected(inputs = dropped, out_dim = n_of_classes, scope_name = 'score')\n", " self.ce_loss = self._loss(labels = self._y, logits = self._score, scope_name = 'ce_loss')\n", " \n", " with tf.variable_scope('prediction'):\n", " self._prediction = tf.argmax(input = self._score, axis = -1)\n", " \n", " def _conv_relu(self, inputs, filters, k_size, stride = 1, padding = 'SAME', scope_name = 'conv'):\n", " with tf.variable_scope(scope_name, reuse = tf.AUTO_REUSE):\n", " in_channels = inputs.get_shape().as_list()[-1]\n", " filter_weights = tf.get_variable(name = 'weights', shape = [k_size, k_size, in_channels, filters],\n", " dtype = tf.float32, initializer = tf.truncated_normal_initializer())\n", " biases = tf.get_variable(name = 'biases', shape = [filters], dtype = tf.float32,\n", " initializer = tf.truncated_normal_initializer())\n", " conv = tf.nn.conv2d(input = inputs, filter = filter_weights,\n", " strides = [1, stride, stride, 1], padding = padding)\n", " pre_activation = conv + biases\n", " activation = tf.nn.relu(pre_activation)\n", " return activation\n", " \n", " def _max_pool(self, inputs, k_size = 2, stride = 2, padding = 'SAME', scope_name = 'max_pool'):\n", " with tf.variable_scope(scope_name, reuse = tf.AUTO_REUSE):\n", " pool = tf.nn.max_pool(value = inputs, ksize = [1, k_size, k_size, 1],\n", " strides = [1, stride, stride, 1], padding = padding)\n", " return pool\n", " \n", " def _fully_connected(self, inputs, out_dim, scope_name = 'fc'):\n", " with tf.variable_scope(scope_name) :\n", " in_dim = inputs.get_shape().as_list()[-1]\n", " weights = tf.get_variable(name = 'weights', shape = [in_dim, out_dim],\n", " dtype = tf.float32, initializer = tf.truncated_normal_initializer())\n", " biases = tf.get_variable(name = 'biases', shape = [out_dim], dtype = tf.float32,\n", " initializer = tf.truncated_normal_initializer())\n", " pre_activation = tf.matmul(inputs, weights) + biases\n", " return pre_activation\n", " \n", " def _loss(self, labels, logits, scope_name):\n", " with tf.variable_scope(scope_name):\n", " ce_loss = tf.losses.sparse_softmax_cross_entropy(labels = labels, logits = logits)\n", " return ce_loss\n", " \n", " def predict(self, sess, x_data, keep_prob = 1.):\n", " feed_prediction = {self._X : x_data, self._keep_prob : keep_prob}\n", " return sess.run(self._prediction, feed_dict = feed_prediction)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Create a model of SimpleCNN" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "550\n" ] } ], "source": [ "# hyper-parameter\n", "lr = .01\n", "epochs = 30\n", "batch_size = 100\n", "total_step = int(x_tr.shape[0] / batch_size)\n", "print(total_step)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "<BatchDataset shapes: ((?, 28, 28, 1), (?,)), types: (tf.float32, tf.int32)>\n", "<BatchDataset shapes: ((?, 28, 28, 1), (?,)), types: (tf.float32, tf.int32)>\n" ] } ], "source": [ "## create input pipeline with tf.data\n", "# for train\n", "tr_dataset = tf.data.Dataset.from_tensor_slices((x_tr, y_tr))\n", "tr_dataset = tr_dataset.shuffle(buffer_size = 10000)\n", "tr_dataset = tr_dataset.batch(batch_size = batch_size)\n", "tr_iterator = tr_dataset.make_initializable_iterator()\n", "print(tr_dataset)\n", "\n", "# for validation\n", "val_dataset = tf.data.Dataset.from_tensor_slices((x_val,y_val))\n", "val_dataset = val_dataset.batch(batch_size = batch_size)\n", "val_iterator = val_dataset.make_initializable_iterator()\n", "print(val_dataset)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "## define Iterator\n", "# tf.data.Iterator.from_string_handle의 output_shapes는 default = None이지만 꼭 값을 넣는 게 좋음\n", "handle = tf.placeholder(dtype = tf.string)\n", "iterator = tf.data.Iterator.from_string_handle(string_handle = handle,\n", " output_types = tr_iterator.output_types,\n", " output_shapes = tr_iterator.output_shapes)\n", "\n", "x_data, y_data = iterator.get_next()" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "## connecting data pipeline with model\n", "cnn = SimpleCNN(X = x_data, y = y_data, n_of_classes = 10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Create training op and train model" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "## create training op\n", "opt = tf.train.AdamOptimizer(learning_rate = lr)\n", "\n", "# equal to 'var_list = None'\n", "training_op = opt.minimize(loss = cnn.ce_loss)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "epoch : 5, tr_loss : 7.832, val_loss : 6.412\n", "epoch : 10, tr_loss : 3.983, val_loss : 4.290\n", "epoch : 15, tr_loss : 1.084, val_loss : 1.116\n", "epoch : 20, tr_loss : 0.568, val_loss : 0.408\n", "epoch : 25, tr_loss : 0.586, val_loss : 0.364\n", "epoch : 30, tr_loss : 0.549, val_loss : 0.408\n" ] } ], "source": [ "sess_config = tf.ConfigProto(gpu_options=tf.GPUOptions(allow_growth=True))\n", "sess = tf.Session(config = sess_config)\n", "sess.run(tf.global_variables_initializer())\n", "tr_handle, val_handle = sess.run(fetches = [tr_iterator.string_handle(), val_iterator.string_handle()])\n", "\n", "tr_loss_hist = []\n", "val_loss_hist = []\n", "\n", "for epoch in range(epochs):\n", "\n", " avg_tr_loss = 0\n", " avg_val_loss = 0\n", " tr_step = 0\n", " val_step = 0\n", "\n", " # for mini-batch training\n", " sess.run(tr_iterator.initializer) \n", " try:\n", " while True:\n", " _, tr_loss = sess.run(fetches = [training_op, cnn.ce_loss],\n", " feed_dict = {handle : tr_handle, cnn._keep_prob : .5})\n", " avg_tr_loss += tr_loss\n", " tr_step += 1\n", " \n", " except tf.errors.OutOfRangeError:\n", " pass\n", "\n", " # for validation\n", " sess.run(val_iterator.initializer)\n", " try:\n", " while True:\n", " val_loss = sess.run(fetches = cnn.ce_loss, feed_dict = {handle : val_handle, cnn._keep_prob : 1.})\n", " avg_val_loss += val_loss\n", " val_step += 1\n", " \n", " except tf.errors.OutOfRangeError:\n", " pass\n", "\n", " avg_tr_loss /= tr_step\n", " avg_val_loss /= val_step\n", " tr_loss_hist.append(avg_tr_loss)\n", " val_loss_hist.append(avg_val_loss)\n", " \n", " if (epoch + 1) % 5 == 0:\n", " print('epoch : {:3}, tr_loss : {:.3f}, val_loss : {:.3f}'.format(epoch + 1, avg_tr_loss, avg_val_loss))" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "<matplotlib.legend.Legend at 0x7fd94c4950f0>" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "<Figure size 432x288 with 1 Axes>" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plt.plot(tr_loss_hist, label = 'train')\n", "plt.plot(val_loss_hist, label = 'validation')\n", "plt.legend()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "test acc: 93.45%\n" ] } ], "source": [ "yhat = cnn.predict(sess = sess, x_data = x_tst)\n", "print('test acc: {:.2%}'.format(np.mean(yhat == y_tst)))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.8" }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }