2364 lines
337 KiB
Plaintext
2364 lines
337 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"CPython 3.5.5\n",
|
||
"IPython 6.3.0\n",
|
||
"\n",
|
||
"numpy 1.14.3\n",
|
||
"sklearn 0.19.1\n",
|
||
"scipy 1.0.1\n",
|
||
"matplotlib 2.2.2\n",
|
||
"tensorflow 1.8.0\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"%load_ext watermark\n",
|
||
"%watermark -v -p numpy,sklearn,scipy,matplotlib,tensorflow"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"**15장 – 오토인코더**"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"_이 노트북은 15장에 있는 모든 샘플 코드와 연습문제 해답을 가지고 있습니다._"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# 설정"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"파이썬 2와 3을 모두 지원합니다. 공통 모듈을 임포트하고 맷플롯립 그림이 노트북 안에 포함되도록 설정하고 생성한 그림을 저장하기 위한 함수를 준비합니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# 파이썬 2와 파이썬 3 지원\n",
|
||
"from __future__ import division, print_function, unicode_literals\n",
|
||
"\n",
|
||
"# 공통\n",
|
||
"import numpy as np\n",
|
||
"import os\n",
|
||
"import sys\n",
|
||
"\n",
|
||
"# 일관된 출력을 위해 유사난수 초기화\n",
|
||
"def reset_graph(seed=42):\n",
|
||
" tf.reset_default_graph()\n",
|
||
" tf.set_random_seed(seed)\n",
|
||
" np.random.seed(seed)\n",
|
||
"\n",
|
||
"# 맷플롯립 설정\n",
|
||
"%matplotlib inline\n",
|
||
"import matplotlib\n",
|
||
"import matplotlib.pyplot as plt\n",
|
||
"plt.rcParams['axes.labelsize'] = 14\n",
|
||
"plt.rcParams['xtick.labelsize'] = 12\n",
|
||
"plt.rcParams['ytick.labelsize'] = 12\n",
|
||
"\n",
|
||
"# 한글출력\n",
|
||
"plt.rcParams['font.family'] = 'NanumBarunGothic'\n",
|
||
"plt.rcParams['axes.unicode_minus'] = False\n",
|
||
"\n",
|
||
"# 그림을 저장할 폴더\n",
|
||
"PROJECT_ROOT_DIR = \".\"\n",
|
||
"CHAPTER_ID = \"autoencoders\"\n",
|
||
"\n",
|
||
"def save_fig(fig_id, tight_layout=True):\n",
|
||
" path = os.path.join(PROJECT_ROOT_DIR, \"images\", CHAPTER_ID, fig_id + \".png\")\n",
|
||
" if tight_layout:\n",
|
||
" plt.tight_layout()\n",
|
||
" plt.savefig(path, format='png', dpi=300)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"28x28 흑백 이미지를 그리기 위한 유틸리티 함수:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def plot_image(image, shape=[28, 28]):\n",
|
||
" plt.imshow(image.reshape(shape), cmap=\"Greys\", interpolation=\"nearest\")\n",
|
||
" plt.axis(\"off\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def plot_multiple_images(images, n_rows, n_cols, pad=2):\n",
|
||
" images = images - images.min() # 최소값을 0으로 만들어 패딩이 하얗게 보이도록 합니다.\n",
|
||
" w,h = images.shape[1:]\n",
|
||
" image = np.zeros(((w+pad)*n_rows+pad, (h+pad)*n_cols+pad))\n",
|
||
" for y in range(n_rows):\n",
|
||
" for x in range(n_cols):\n",
|
||
" image[(y*(h+pad)+pad):(y*(h+pad)+pad+h),(x*(w+pad)+pad):(x*(w+pad)+pad+w)] = images[y*n_cols+x]\n",
|
||
" plt.imshow(image, cmap=\"Greys\", interpolation=\"nearest\")\n",
|
||
" plt.axis(\"off\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# 선형 오토인코더를 사용한 PCA"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"3D 데이터셋을 만듭니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import numpy.random as rnd\n",
|
||
"\n",
|
||
"rnd.seed(4)\n",
|
||
"m = 200\n",
|
||
"w1, w2 = 0.1, 0.3\n",
|
||
"noise = 0.1\n",
|
||
"\n",
|
||
"angles = rnd.rand(m) * 3 * np.pi / 2 - 0.5\n",
|
||
"data = np.empty((m, 3))\n",
|
||
"data[:, 0] = np.cos(angles) + np.sin(angles)/2 + noise * rnd.randn(m) / 2\n",
|
||
"data[:, 1] = np.sin(angles) * 0.7 + noise * rnd.randn(m) / 2\n",
|
||
"data[:, 2] = data[:, 0] * w1 + data[:, 1] * w2 + noise * rnd.randn(m)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"데이터를 정규화합니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from sklearn.preprocessing import StandardScaler\n",
|
||
"scaler = StandardScaler()\n",
|
||
"X_train = scaler.fit_transform(data[:100])\n",
|
||
"X_test = scaler.transform(data[100:])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"오토인코더를 만듭니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import tensorflow as tf\n",
|
||
"\n",
|
||
"reset_graph()\n",
|
||
"\n",
|
||
"n_inputs = 3\n",
|
||
"n_hidden = 2 # 코딩 유닛\n",
|
||
"n_outputs = n_inputs\n",
|
||
"\n",
|
||
"learning_rate = 0.01\n",
|
||
"\n",
|
||
"X = tf.placeholder(tf.float32, shape=[None, n_inputs])\n",
|
||
"hidden = tf.layers.dense(X, n_hidden)\n",
|
||
"outputs = tf.layers.dense(hidden, n_outputs)\n",
|
||
"\n",
|
||
"reconstruction_loss = tf.reduce_mean(tf.square(outputs - X))\n",
|
||
"\n",
|
||
"optimizer = tf.train.AdamOptimizer(learning_rate)\n",
|
||
"training_op = optimizer.minimize(reconstruction_loss)\n",
|
||
"\n",
|
||
"init = tf.global_variables_initializer()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 8,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"n_iterations = 1000\n",
|
||
"codings = hidden\n",
|
||
"\n",
|
||
"with tf.Session() as sess:\n",
|
||
" init.run()\n",
|
||
" for iteration in range(n_iterations):\n",
|
||
" training_op.run(feed_dict={X: X_train})\n",
|
||
" codings_val = codings.eval(feed_dict={X: X_test})"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"image/png": "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\n",
|
||
"text/plain": [
|
||
"<Figure size 288x216 with 1 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"fig = plt.figure(figsize=(4,3))\n",
|
||
"plt.plot(codings_val[:,0], codings_val[:, 1], \"b.\")\n",
|
||
"plt.xlabel(\"$z_1$\", fontsize=18)\n",
|
||
"plt.ylabel(\"$z_2$\", fontsize=18, rotation=0)\n",
|
||
"save_fig(\"linear_autoencoder_pca_plot\")\n",
|
||
"plt.show()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# 적층 오토인코더"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"MNIST 데이터셋을 사용합니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"주의: `tf.examples.tutorials.mnist`은 삭제될 예정이므로 대신 `tf.keras.datasets.mnist`를 사용하겠습니다."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"(X_train, y_train), (X_test, y_test) = tf.keras.datasets.mnist.load_data()\n",
|
||
"X_train = X_train.astype(np.float32).reshape(-1, 28*28) / 255.0\n",
|
||
"X_test = X_test.astype(np.float32).reshape(-1, 28*28) / 255.0\n",
|
||
"y_train = y_train.astype(np.int32)\n",
|
||
"y_test = y_test.astype(np.int32)\n",
|
||
"X_valid, X_train = X_train[:5000], X_train[5000:]\n",
|
||
"y_valid, y_train = y_train[:5000], y_train[5000:]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def shuffle_batch(X, y, batch_size):\n",
|
||
" rnd_idx = np.random.permutation(len(X))\n",
|
||
" n_batches = len(X) // batch_size\n",
|
||
" for batch_idx in np.array_split(rnd_idx, n_batches):\n",
|
||
" X_batch, y_batch = X[batch_idx], y[batch_idx]\n",
|
||
" yield X_batch, y_batch"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 10,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Extracting /tmp/data/train-images-idx3-ubyte.gz\n",
|
||
"Extracting /tmp/data/train-labels-idx1-ubyte.gz\n",
|
||
"Extracting /tmp/data/t10k-images-idx3-ubyte.gz\n",
|
||
"Extracting /tmp/data/t10k-labels-idx1-ubyte.gz\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"# from tensorflow.examples.tutorials.mnist import input_data\n",
|
||
"# mnist = input_data.read_data_sets(\"/tmp/data/\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 한 번에 모든 층을 훈련하기"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"3개의 은닉층과 1개의 출력층(즉, 두 개를 적층)을 가진 적층 오토인코더를 만들어 보겠습니다. ELU 활성화 함수와 He 초기화, L2 정규화를 사용하겠습니다."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 11,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"reset_graph()\n",
|
||
"\n",
|
||
"from functools import partial\n",
|
||
"\n",
|
||
"n_inputs = 28 * 28\n",
|
||
"n_hidden1 = 300\n",
|
||
"n_hidden2 = 150 # 코딩 유닛\n",
|
||
"n_hidden3 = n_hidden1\n",
|
||
"n_outputs = n_inputs\n",
|
||
"\n",
|
||
"learning_rate = 0.01\n",
|
||
"l2_reg = 0.0001\n",
|
||
"\n",
|
||
"X = tf.placeholder(tf.float32, shape=[None, n_inputs])\n",
|
||
"\n",
|
||
"he_init = tf.contrib.layers.variance_scaling_initializer() # He 초기화\n",
|
||
"#아래와 동일합니다:\n",
|
||
"#he_init = lambda shape, dtype=tf.float32: tf.truncated_normal(shape, 0., stddev=np.sqrt(2/shape[0]))\n",
|
||
"l2_regularizer = tf.contrib.layers.l2_regularizer(l2_reg)\n",
|
||
"my_dense_layer = partial(tf.layers.dense,\n",
|
||
" activation=tf.nn.elu,\n",
|
||
" kernel_initializer=he_init,\n",
|
||
" kernel_regularizer=l2_regularizer)\n",
|
||
"\n",
|
||
"hidden1 = my_dense_layer(X, n_hidden1)\n",
|
||
"hidden2 = my_dense_layer(hidden1, n_hidden2)\n",
|
||
"hidden3 = my_dense_layer(hidden2, n_hidden3)\n",
|
||
"outputs = my_dense_layer(hidden3, n_outputs, activation=None)\n",
|
||
"\n",
|
||
"reconstruction_loss = tf.reduce_mean(tf.square(outputs - X))\n",
|
||
"\n",
|
||
"reg_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)\n",
|
||
"loss = tf.add_n([reconstruction_loss] + reg_losses)\n",
|
||
"\n",
|
||
"optimizer = tf.train.AdamOptimizer(learning_rate)\n",
|
||
"training_op = optimizer.minimize(loss)\n",
|
||
"\n",
|
||
"init = tf.global_variables_initializer()\n",
|
||
"saver = tf.train.Saver() # 책에는 없음"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"이제 훈련시켜 보죠! 여기에서는 타깃 값을 주입하지 않습니다(`y_batch`가 사용되지 않습니다). 이는 비지도 학습입니다."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 12,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"0 훈련 MSE: 0.020550018\n",
|
||
"1 훈련 MSE: 0.01137075\n",
|
||
"2 훈련 MSE: 0.0102255605\n",
|
||
"3 훈련 MSE: 0.009902374\n",
|
||
"4 훈련 MSE: 0.010377134\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"n_epochs = 5\n",
|
||
"batch_size = 150\n",
|
||
"\n",
|
||
"with tf.Session() as sess:\n",
|
||
" init.run()\n",
|
||
" for epoch in range(n_epochs):\n",
|
||
" n_batches = len(X_train) // batch_size\n",
|
||
" for iteration in range(n_batches):\n",
|
||
" print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\") # 책에는 없음\n",
|
||
" sys.stdout.flush() # 책에는 없음\n",
|
||
" X_batch, y_batch = shuffle_batch(X_train, y_train, batch_size):\n",
|
||
" sess.run(training_op, feed_dict={X: X_batch})\n",
|
||
" loss_train = reconstruction_loss.eval(feed_dict={X: X_batch}) # 책에는 없음\n",
|
||
" print(\"\\r{}\".format(epoch), \"훈련 MSE:\", loss_train) # 책에는 없음\n",
|
||
" saver.save(sess, \"./my_model_all_layers.ckpt\") # 책에는 없음"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"이 함수는 모델을 로드하고 테스트 세트에서 이를 평가합니다(재구성 오차를 측정합니다). 그런 다음 원본 이미지와 재구성 이미지를 그립니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 13,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def show_reconstructed_digits(X, outputs, model_path = None, n_test_digits = 2):\n",
|
||
" with tf.Session() as sess:\n",
|
||
" if model_path:\n",
|
||
" saver.restore(sess, model_path)\n",
|
||
"# X_test = mnist.test.images[:n_test_digits]\n",
|
||
" outputs_val = outputs.eval(feed_dict={X: X_test[:n_test_digits]})\n",
|
||
"\n",
|
||
" fig = plt.figure(figsize=(8, 3 * n_test_digits))\n",
|
||
" for digit_index in range(n_test_digits):\n",
|
||
" plt.subplot(n_test_digits, 2, digit_index * 2 + 1)\n",
|
||
" plot_image(X_test[digit_index])\n",
|
||
" plt.subplot(n_test_digits, 2, digit_index * 2 + 2)\n",
|
||
" plot_image(outputs_val[digit_index])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 14,
|
||
"metadata": {
|
||
"scrolled": false
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"INFO:tensorflow:Restoring parameters from ./my_model_all_layers.ckpt\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"image/png": "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\n",
|
||
"text/plain": [
|
||
"<Figure size 576x432 with 4 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"show_reconstructed_digits(X, outputs, \"./my_model_all_layers.ckpt\")\n",
|
||
"save_fig(\"reconstruction_plot\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 가중치 묶기"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"인코더와 디코더의 가중치를 묶는 일은 자주 있습니다(`weights_decoder = tf.transpose(weights_encoder)`). 안타깝지만 `tf.layers.dense()` 함수를 사용해서 이렇게 하기는 불가능합니다(또는 매우 어렵습니다). 수동으로 직접 오토인코더를 만들어야 합니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 15,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"reset_graph()\n",
|
||
"\n",
|
||
"n_inputs = 28 * 28\n",
|
||
"n_hidden1 = 300\n",
|
||
"n_hidden2 = 150 # 코딩 유닛\n",
|
||
"n_hidden3 = n_hidden1\n",
|
||
"n_outputs = n_inputs\n",
|
||
"\n",
|
||
"learning_rate = 0.01\n",
|
||
"l2_reg = 0.0005"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 16,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"activation = tf.nn.elu\n",
|
||
"regularizer = tf.contrib.layers.l2_regularizer(l2_reg)\n",
|
||
"initializer = tf.contrib.layers.variance_scaling_initializer()\n",
|
||
"\n",
|
||
"X = tf.placeholder(tf.float32, shape=[None, n_inputs])\n",
|
||
"\n",
|
||
"weights1_init = initializer([n_inputs, n_hidden1])\n",
|
||
"weights2_init = initializer([n_hidden1, n_hidden2])\n",
|
||
"\n",
|
||
"weights1 = tf.Variable(weights1_init, dtype=tf.float32, name=\"weights1\")\n",
|
||
"weights2 = tf.Variable(weights2_init, dtype=tf.float32, name=\"weights2\")\n",
|
||
"weights3 = tf.transpose(weights2, name=\"weights3\") # 가중치 묶기\n",
|
||
"weights4 = tf.transpose(weights1, name=\"weights4\") # 가중치 묶기\n",
|
||
"\n",
|
||
"biases1 = tf.Variable(tf.zeros(n_hidden1), name=\"biases1\")\n",
|
||
"biases2 = tf.Variable(tf.zeros(n_hidden2), name=\"biases2\")\n",
|
||
"biases3 = tf.Variable(tf.zeros(n_hidden3), name=\"biases3\")\n",
|
||
"biases4 = tf.Variable(tf.zeros(n_outputs), name=\"biases4\")\n",
|
||
"\n",
|
||
"hidden1 = activation(tf.matmul(X, weights1) + biases1)\n",
|
||
"hidden2 = activation(tf.matmul(hidden1, weights2) + biases2)\n",
|
||
"hidden3 = activation(tf.matmul(hidden2, weights3) + biases3)\n",
|
||
"outputs = tf.matmul(hidden3, weights4) + biases4\n",
|
||
"\n",
|
||
"reconstruction_loss = tf.reduce_mean(tf.square(outputs - X))\n",
|
||
"reg_loss = regularizer(weights1) + regularizer(weights2)\n",
|
||
"loss = reconstruction_loss + reg_loss\n",
|
||
"\n",
|
||
"optimizer = tf.train.AdamOptimizer(learning_rate)\n",
|
||
"training_op = optimizer.minimize(loss)\n",
|
||
"\n",
|
||
"init = tf.global_variables_initializer()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 17,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"saver = tf.train.Saver()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 18,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"0 훈련 MSE: 0.01506695\n",
|
||
"1 훈련 MSE: 0.016488748\n",
|
||
"2 훈련 MSE: 0.017375939\n",
|
||
"3 훈련 MSE: 0.016878333\n",
|
||
"4 훈련 MSE: 0.015587721\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"n_epochs = 5\n",
|
||
"batch_size = 150\n",
|
||
"\n",
|
||
"with tf.Session() as sess:\n",
|
||
" init.run()\n",
|
||
" for epoch in range(n_epochs):\n",
|
||
" n_batches = len(X_train) // batch_size\n",
|
||
" for iteration in range(n_batches):\n",
|
||
" print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\")\n",
|
||
" sys.stdout.flush()\n",
|
||
" X_batch, y_batch = shuffle_batch(X_train, y_train, batch_size):s\n",
|
||
" sess.run(training_op, feed_dict={X: X_batch})\n",
|
||
" loss_train = reconstruction_loss.eval(feed_dict={X: X_batch})\n",
|
||
" print(\"\\r{}\".format(epoch), \"훈련 MSE:\", loss_train)\n",
|
||
" saver.save(sess, \"./my_model_tying_weights.ckpt\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 19,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"INFO:tensorflow:Restoring parameters from ./my_model_tying_weights.ckpt\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"image/png": "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\n",
|
||
"text/plain": [
|
||
"<Figure size 576x432 with 4 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"show_reconstructed_digits(X, outputs, \"./my_model_tying_weights.ckpt\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 여러 개의 그래프에서 오토인토더를 따로따로 훈련하기"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"하나의 오토인코더를 따로따로 훈련하는 방법이 많이 있습니다. 첫 번째 방법은 각 오토인코더를 다른 그래프를 사용하여 훈련하는 것입니다. 그런 다음 이런 오토인코더의 가중치와 편향을 복사해 초깃값으로 지정해서 적층 오토인코더를 만듭니다."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"하나의 오토인코더를 훈련하고 변환된 훈련 세트(즉, 은닉층의 출력)와 모델 파라미터를 반환하는 함수를 만들겠습니다."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 20,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"reset_graph()\n",
|
||
"\n",
|
||
"from functools import partial\n",
|
||
"\n",
|
||
"def train_autoencoder(X_train, n_neurons, n_epochs, batch_size,\n",
|
||
" learning_rate = 0.01, l2_reg = 0.0005, seed=42,\n",
|
||
" hidden_activation=tf.nn.elu,\n",
|
||
" output_activation=tf.nn.elu):\n",
|
||
" graph = tf.Graph()\n",
|
||
" with graph.as_default():\n",
|
||
" tf.set_random_seed(seed)\n",
|
||
"\n",
|
||
" n_inputs = X_train.shape[1]\n",
|
||
"\n",
|
||
" X = tf.placeholder(tf.float32, shape=[None, n_inputs])\n",
|
||
" \n",
|
||
" my_dense_layer = partial(\n",
|
||
" tf.layers.dense,\n",
|
||
" kernel_initializer=tf.contrib.layers.variance_scaling_initializer(),\n",
|
||
" kernel_regularizer=tf.contrib.layers.l2_regularizer(l2_reg))\n",
|
||
"\n",
|
||
" hidden = my_dense_layer(X, n_neurons, activation=hidden_activation, name=\"hidden\")\n",
|
||
" outputs = my_dense_layer(hidden, n_inputs, activation=output_activation, name=\"outputs\")\n",
|
||
"\n",
|
||
" reconstruction_loss = tf.reduce_mean(tf.square(outputs - X))\n",
|
||
"\n",
|
||
" reg_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)\n",
|
||
" loss = tf.add_n([reconstruction_loss] + reg_losses)\n",
|
||
"\n",
|
||
" optimizer = tf.train.AdamOptimizer(learning_rate)\n",
|
||
" training_op = optimizer.minimize(loss)\n",
|
||
"\n",
|
||
" init = tf.global_variables_initializer()\n",
|
||
"\n",
|
||
" with tf.Session(graph=graph) as sess:\n",
|
||
" init.run()\n",
|
||
" for epoch in range(n_epochs):\n",
|
||
" n_batches = len(X_train) // batch_size\n",
|
||
" for iteration in range(n_batches):\n",
|
||
" print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\")\n",
|
||
" sys.stdout.flush()\n",
|
||
" indices = rnd.permutation(len(X_train))[:batch_size]\n",
|
||
" X_batch = X_train[indices]\n",
|
||
" sess.run(training_op, feed_dict={X: X_batch})\n",
|
||
" loss_train = reconstruction_loss.eval(feed_dict={X: X_batch})\n",
|
||
" print(\"\\r{}\".format(epoch), \"훈련 MSE:\", loss_train)\n",
|
||
" params = dict([(var.name, var.eval()) for var in tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES)])\n",
|
||
" hidden_val = hidden.eval(feed_dict={X: X_train})\n",
|
||
" return hidden_val, params[\"hidden/kernel:0\"], params[\"hidden/bias:0\"], params[\"outputs/kernel:0\"], params[\"outputs/bias:0\"]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"이제 두 개의 오토인코더를 훈련시켜 보죠. 첫 번째는 훈련 데이터를 사용하고 두 번째는 첫 번째 오토인코더의 은닉층 출력을 사용해 훈련시킵니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 21,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"0 훈련 MSE: 0.01851794\n",
|
||
"1 훈련 MSE: 0.01868272\n",
|
||
"2 훈련 MSE: 0.018467719\n",
|
||
"3 훈련 MSE: 0.019231746\n",
|
||
"0 훈련 MSE: 0.004236093\n",
|
||
"1 훈련 MSE: 0.0048326333\n",
|
||
"2 훈련 MSE: 0.004668708\n",
|
||
"3 훈련 MSE: 0.0044038747\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"hidden_output, W1, b1, W4, b4 = train_autoencoder(X_train, n_neurons=300, n_epochs=4, batch_size=150,\n",
|
||
" output_activation=None)\n",
|
||
"_, W2, b2, W3, b3 = train_autoencoder(hidden_output, n_neurons=150, n_epochs=4, batch_size=150)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"마지막으로 방금전 훈련한 오토인코더의 가중치와 편향을 재사용하여 적층 오토인코더를 만듭니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 22,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"reset_graph()\n",
|
||
"\n",
|
||
"n_inputs = 28*28\n",
|
||
"\n",
|
||
"X = tf.placeholder(tf.float32, shape=[None, n_inputs])\n",
|
||
"hidden1 = tf.nn.elu(tf.matmul(X, W1) + b1)\n",
|
||
"hidden2 = tf.nn.elu(tf.matmul(hidden1, W2) + b2)\n",
|
||
"hidden3 = tf.nn.elu(tf.matmul(hidden2, W3) + b3)\n",
|
||
"outputs = tf.matmul(hidden3, W4) + b4"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 23,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"image/png": "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\n",
|
||
"text/plain": [
|
||
"<Figure size 576x432 with 4 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"show_reconstructed_digits(X, outputs)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 하나의 그래프에서 오토인코더를 따로따로 훈련하기"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"하나의 그래프를 사용하는 방법도 있습니다. 이 방법은 전체 적층 오토인코더를 위한 그래프를 만들지만 각 오토인코더를 독립적으로 훈련하기 위한 연산도 추가합니다. 단계 1은 맨 아래층과 맨 윗층을 훈련하고(즉, 첫 번째 오토인코더), 단계 2는 두 개의 가운데 층을 훈련합니다(즉, 두 번째 오토인코더)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 24,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"reset_graph()\n",
|
||
"\n",
|
||
"n_inputs = 28 * 28\n",
|
||
"n_hidden1 = 300\n",
|
||
"n_hidden2 = 150 # 코딩 유닛\n",
|
||
"n_hidden3 = n_hidden1\n",
|
||
"n_outputs = n_inputs\n",
|
||
"\n",
|
||
"learning_rate = 0.01\n",
|
||
"l2_reg = 0.0001\n",
|
||
"\n",
|
||
"activation = tf.nn.elu\n",
|
||
"regularizer = tf.contrib.layers.l2_regularizer(l2_reg)\n",
|
||
"initializer = tf.contrib.layers.variance_scaling_initializer()\n",
|
||
"\n",
|
||
"X = tf.placeholder(tf.float32, shape=[None, n_inputs])\n",
|
||
"\n",
|
||
"weights1_init = initializer([n_inputs, n_hidden1])\n",
|
||
"weights2_init = initializer([n_hidden1, n_hidden2])\n",
|
||
"weights3_init = initializer([n_hidden2, n_hidden3])\n",
|
||
"weights4_init = initializer([n_hidden3, n_outputs])\n",
|
||
"\n",
|
||
"weights1 = tf.Variable(weights1_init, dtype=tf.float32, name=\"weights1\")\n",
|
||
"weights2 = tf.Variable(weights2_init, dtype=tf.float32, name=\"weights2\")\n",
|
||
"weights3 = tf.Variable(weights3_init, dtype=tf.float32, name=\"weights3\")\n",
|
||
"weights4 = tf.Variable(weights4_init, dtype=tf.float32, name=\"weights4\")\n",
|
||
"\n",
|
||
"biases1 = tf.Variable(tf.zeros(n_hidden1), name=\"biases1\")\n",
|
||
"biases2 = tf.Variable(tf.zeros(n_hidden2), name=\"biases2\")\n",
|
||
"biases3 = tf.Variable(tf.zeros(n_hidden3), name=\"biases3\")\n",
|
||
"biases4 = tf.Variable(tf.zeros(n_outputs), name=\"biases4\")\n",
|
||
"\n",
|
||
"hidden1 = activation(tf.matmul(X, weights1) + biases1)\n",
|
||
"hidden2 = activation(tf.matmul(hidden1, weights2) + biases2)\n",
|
||
"hidden3 = activation(tf.matmul(hidden2, weights3) + biases3)\n",
|
||
"outputs = tf.matmul(hidden3, weights4) + biases4\n",
|
||
"\n",
|
||
"reconstruction_loss = tf.reduce_mean(tf.square(outputs - X))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 25,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"optimizer = tf.train.AdamOptimizer(learning_rate)\n",
|
||
"\n",
|
||
"with tf.name_scope(\"phase1\"):\n",
|
||
" phase1_outputs = tf.matmul(hidden1, weights4) + biases4 # hidden2와 hidden3 통과합니다\n",
|
||
" phase1_reconstruction_loss = tf.reduce_mean(tf.square(phase1_outputs - X))\n",
|
||
" phase1_reg_loss = regularizer(weights1) + regularizer(weights4)\n",
|
||
" phase1_loss = phase1_reconstruction_loss + phase1_reg_loss\n",
|
||
" phase1_training_op = optimizer.minimize(phase1_loss)\n",
|
||
"\n",
|
||
"with tf.name_scope(\"phase2\"):\n",
|
||
" phase2_reconstruction_loss = tf.reduce_mean(tf.square(hidden3 - hidden1))\n",
|
||
" phase2_reg_loss = regularizer(weights2) + regularizer(weights3)\n",
|
||
" phase2_loss = phase2_reconstruction_loss + phase2_reg_loss\n",
|
||
" train_vars = [weights2, biases2, weights3, biases3]\n",
|
||
" phase2_training_op = optimizer.minimize(phase2_loss, var_list=train_vars) # hidden1 동결"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 26,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"init = tf.global_variables_initializer()\n",
|
||
"saver = tf.train.Saver()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 27,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"훈련 단계 #1\n",
|
||
"0 훈련 MSE: 0.007406866\n",
|
||
"1 훈련 MSE: 0.0078288205\n",
|
||
"2 훈련 MSE: 0.007728097\n",
|
||
"3 훈련 MSE: 0.0074090064\n",
|
||
"훈련 단계 #2\n",
|
||
"09% 훈련 MSE: 0.35758996\n",
|
||
"1 훈련 MSE: 0.00593613\n",
|
||
"2 훈련 MSE: 0.0030089526\n",
|
||
"3 훈련 MSE: 0.0024365915\n",
|
||
"테스트 MSE: 0.009815396\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"training_ops = [phase1_training_op, phase2_training_op]\n",
|
||
"reconstruction_losses = [phase1_reconstruction_loss, phase2_reconstruction_loss]\n",
|
||
"n_epochs = [4, 4]\n",
|
||
"batch_sizes = [150, 150]\n",
|
||
"\n",
|
||
"with tf.Session() as sess:\n",
|
||
" init.run()\n",
|
||
" for phase in range(2):\n",
|
||
" print(\"훈련 단계 #{}\".format(phase + 1))\n",
|
||
" for epoch in range(n_epochs[phase]):\n",
|
||
" n_batches = len(X_train) // batch_sizes[phase]\n",
|
||
" for iteration in range(n_batches):\n",
|
||
" print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\")\n",
|
||
" sys.stdout.flush()\n",
|
||
" X_batch, y_batch = shuffle_batch(X_train, y_train, batch_sizes[phase]):\n",
|
||
" sess.run(training_ops[phase], feed_dict={X: X_batch})\n",
|
||
" loss_train = reconstruction_losses[phase].eval(feed_dict={X: X_batch})\n",
|
||
" print(\"\\r{}\".format(epoch), \"훈련 MSE:\", loss_train)\n",
|
||
" saver.save(sess, \"./my_model_one_at_a_time.ckpt\")\n",
|
||
" loss_test = reconstruction_loss.eval(feed_dict={X: X_test})\n",
|
||
" print(\"테스트 MSE:\", loss_test)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 동결 층의 출력을 캐싱하기"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 28,
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"훈련 단계 #1\n",
|
||
"0 훈련 MSE: 0.0075382586\n",
|
||
"1 훈련 MSE: 0.007754701\n",
|
||
"2 훈련 MSE: 0.007343679\n",
|
||
"3 훈련 MSE: 0.007837775\n",
|
||
"훈련 단계 #2\n",
|
||
"0 훈련 MSE: 0.18597357\n",
|
||
"1 훈련 MSE: 0.0044647465\n",
|
||
"2 훈련 MSE: 0.002462252\n",
|
||
"3 훈련 MSE: 0.0020415403\n",
|
||
"테스트 MSE: 0.009790834\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"training_ops = [phase1_training_op, phase2_training_op]\n",
|
||
"reconstruction_losses = [phase1_reconstruction_loss, phase2_reconstruction_loss]\n",
|
||
"n_epochs = [4, 4]\n",
|
||
"batch_sizes = [150, 150]\n",
|
||
"\n",
|
||
"with tf.Session() as sess:\n",
|
||
" init.run()\n",
|
||
" for phase in range(2):\n",
|
||
" print(\"훈련 단계 #{}\".format(phase + 1))\n",
|
||
" if phase == 1:\n",
|
||
" hidden1_cache = hidden1.eval(feed_dict={X: X_train})\n",
|
||
" for epoch in range(n_epochs[phase]):\n",
|
||
" n_batches = len(X_train) // batch_sizes[phase]\n",
|
||
" for iteration in range(n_batches):\n",
|
||
" print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\")\n",
|
||
" sys.stdout.flush()\n",
|
||
" if phase == 1:\n",
|
||
" indices = rnd.permutation(len(X_train))\n",
|
||
" hidden1_batch = hidden1_cache[indices[:batch_sizes[phase]]]\n",
|
||
" feed_dict = {hidden1: hidden1_batch}\n",
|
||
" sess.run(training_ops[phase], feed_dict=feed_dict)\n",
|
||
" else:\n",
|
||
" X_batch, y_batch = shuffle_batch(X_train, y_train, batch_sizes[phase]):\n",
|
||
" feed_dict = {X: X_batch}\n",
|
||
" sess.run(training_ops[phase], feed_dict=feed_dict)\n",
|
||
" loss_train = reconstruction_losses[phase].eval(feed_dict=feed_dict)\n",
|
||
" print(\"\\r{}\".format(epoch), \"훈련 MSE:\", loss_train)\n",
|
||
" saver.save(sess, \"./my_model_cache_frozen.ckpt\")\n",
|
||
" loss_test = reconstruction_loss.eval(feed_dict={X: X_test})\n",
|
||
" print(\"테스트 MSE:\", loss_test)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 재구성 시각화"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 29,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"INFO:tensorflow:Restoring parameters from ./my_model_one_at_a_time.ckpt\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAUAAAAD+CAYAAABLJ9wbAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAFoRJREFUeJzt3Vmo1VUbx/FlDuU86/E4ZeYc5oA4XqS9WBQkDRIlUVSQBAUJDQZBddNleRMVhZZ5EZRlJY2mkWWikkZOWGpax+M8j6m9V+/it57XvdznuLfnuJ/v5+r5s/bZ/731uPg/j89aq8m///4bAMCjqxr6AwBAQ2ECBOAWEyAAt5gAAbjFBAjALSZAAG4xAQJwiwkQgFtMgADcatYA92TpSePRpKE/QCWpqanhd7uRqK6uLup3mydAAG4xAQJwiwkQgFsNUQMEUAJNmqRlrvru7KTvU5f3uOqq9Pkp97ONddcpngABuMUECMAtUmCgEbNpripVytm8efMYnzlzJnv/8+fPx9imwDrWtGnTgmMa2/fJfd9y4AkQgFtMgADcYgIE4BY1QKCB5dpZcrW8c+fOFRzL1ee05hdCCP/880+MbQ3QvlavmzUrPH3oe4aQ1gRtfVCVqrWnWDwBAnCLCRCAW6TAQAOrS5qXS2U1tbSppKbLduzkyZMxzqXOdvzs2bPJmKa9p0+fTsb0ta1atUrGcqm0jtnPYq/rgydAAG4xAQJwiwkQgFvUAIFGRutsuRpcbtna1VdfnYzl6mydOnWK8alTp5Ixe4/Dhw/HuEWLFslYmzZtYmzrk/o9bA1SX2u/r9Y1S1Hzs3gCBOAWEyAAt0iBgUZGW0iOHDlScMy2oWg7TdeuXZMxTTPbt2+fjGm6bMdyabZt39H0XFtr7M9Z+j3sChK9v02BS7FzDE+AANxiAgTgFhMgALcqogb4888/J9dz5syJcc+ePZOxli1bxvjBBx9MxrQdQGOgnOyuLocOHYrxli1bkrG//vorxrY+qPUzbUkJIYTq6uoYd+nSJRlr3bp1jNu1a5f9rHpP+7m1ZcW23ehYVVVVMtahQ4cY27qiXpdjt2ieAAG4xQQIwK0mDXBeZ8lvOGjQoOTapg3F0haAcePGXdJnqo9rr702xrNnz07G+vTpU45bXt4TaCpcTU1NvX63bctITU1NjFetWpWM6e/2vn37kjFdxXH8+PGi76etNTZ1tinxjh07Co717ds3xrpiJIQQ+vfvH+NJkyYlYyNGjIixpuMXk0uPq6uri/rd5gkQgFtMgADcYgIE4FZFtMF88sknyfXatWtjPGzYsGRs/fr1MV65cmUytmjRohh/9dVXyVi/fv1ivG3btqI/m20H6NGjR4x37txZ8Oe0HhhCCM8++2zR90TjY1tG9Nou8dLall0ads0118T4uuuuS8Z0dxZbA9TftQ0bNiRjuhTO3m/v3r3JtbaztG3bNhnbtWtXjNetW5eM1dbWxnjIkCHJmN7T7jCj7NI/doQGgEvABAjArYpogykVbSPYvn17MqYp8NatW4t+T/tIrymwvmcIabrx8ccfJ2PTpk0r+p51QBtMCdk2GP23ZdM3bduwY/p7kDtcyLaMaHuLbUM5ePBgjO3BR/qex44dK/ieIaTpq209Wbp0aYwXLlyYjOnqk+eeey4ZGz9+fIx1pZb9bLndb2iDAYA6YgIE4BYTIAC3KqINplS0xWDw4MEFX2f/G78utPXGLmUaO3ZsjKdOnVrve6Bx0LqUto9Y+nsXQro7iq0h28OO1IkTJ2KsteYQ0h2h7XI3bcnJLaELIa3l6a41IYSwbNmyGNudpHv16hXj3r17J2P6nWy7UO7/KNgRGgAuARMgALdIgcvMphR33nlnjG0n+2uvvRZj2w6AK5ttPcmd/aspqk2BNZXNna+bO5TIptyaZtrUtXPnzsm1pvJ//PFHMrZ58+YYt2rVKhnT8o49sElXS9lzie2fWyH1TYd5AgTgFhMgALeYAAG4RQ2wzObNm5dc664Ytr6iO+qistgalV5r7S6E/9+RRekSN7sUTutztn1E72GX1+m1/SzW7t27Y7x48eJkbM2aNTG2uz5PmTKl4OfWPwtbD9VrWw9kNxgAuARMgADcIgUuA20PmDVrVsHXrVixIrm256WicuTOu821euRWkOR2irGprLa32BRb38ducmrbaTZu3Bhj3f0lhLRlR9teQkhXf9gWGU1lbalAx2zKq6+t765WPAECcIsJEIBbTIAA3KIGWAafffZZjG29Zfr06TG2h9rAj9zBR8rujqJLJO0OyVr3sz+Xa2/RthS79M7uLK07PdulcLfddluMJ0yYkIxp3S+3O3auBmgPGCvFbvY8AQJwiwkQgFtMgADcogZYAraGoye62R18X3nllRjnerxQ2XI1QO0LtL1+WgezdT79fbJbXulrbQ1O39OOLV++PLlevXp1jAcOHJiM6cmFtr6t38l+bv2OuUPic32A9cUTIAC3mAABuEUKXALvvPNOcv3DDz/E+P7770/GaH2BlUv77DI5TR9tW4i+j02r9cAk+565A9WXLFmSXGu6Om7cuGRs1KhRMW7fvn0ypjuj2zRb2c9m23IUu8EAwCVgAgTgFhMgALeoAdbD2rVrk+snnngiudaDrV9++eXL8plw5bJLunK7IGvrh22x0lqePV1NT5qz7Vf62s8//zwZ012eQ0hre5MnT07GdIdzW4PUup9tX9E6n60P5tp3ij0xLocnQABuMQECcIsUuEiaXtx3333JmO1snzFjRoxpe8GFaNprU1JNbXOrNuqyEkSvbcqtbVvz589Pxnbt2pVcP/DAAzEeP358MqYpqba92M9qU3f9jvY75VqCcofLF4snQABuMQECcIsJEIBb1AALsDWF22+/PcabN29OxoYMGZJcv/TSS+X7YKgIudPOcvVBrZfl2kBsDVBrhzt27EjGFi1aFOP169cnY//5z3+S65tvvjnGdrlbbucWrfvlapdW7uQ3lsIBwCVgAgTgFilwAQcOHEiuly1bVvC1tnWgU6dO5fhIuMJo+mbTtVz6pqmeXTWhu7HYg4702qaLujLjq6++SsZWrVoVY7vJ6T333JNcjxw5MsZ2NxpdUWK/n6a59rNpSlyKtLYueAIE4BYTIAC3mAABuEUNUOhuuHa3W/X+++8n11oXAf4nV8vLtbBoq4ut82ndzdbg9NB0+/47d+6M8cqVK5Ox2traGN97773J2OjRo5Nr/U72wCb9rHrYuv08dqeaQu8RQlq7tN+JNhgAuARMgADcIgUWc+fOjfHWrVsLvm7SpEnJdSnOJ0Vls78judUPmurZ12kKag8MOnr0aIz37t2bjC1YsCDGn376aTLWsWPHGA8aNCgZ69atW3Ktqa1d0aHpau7sX5vm6mvtz+VaiUqBJ0AAbjEBAnCLCRCAW65rgFu2bEmuX3zxxYb5IKh4dvmXytWQc4ci2Z/Tw883bNiQjC1evDjGurt5CCGMGTMmxoMHD07GbL3u4MGDMT5z5kwypjVJW8vT96nLssBy4wkQgFtMgADccp0C62EwIYRw5MiRgq/VTU+14x4oJ3u+rrbF2JUYmnba1Ra6y4u2vYQQwoQJE2LctWvXZMzeQ9mVKLn03B7u1FjwBAjALSZAAG4xAQJwy3UNMEfrIiGE8M0338SYGiBKybbI5FpmtCZo62xakxswYEAyduutt8bYtrb07ds3xnYXF1uD1MONcp/Ttrbk6oMNiSdAAG4xAQJwq0nuMbZMLvsNUVDjyUUqQE1NzWX93barRHKtJvpam57mNme16Woufc2t6Mj9XDnmoOrq6qJ+t3kCBOAWEyAAt5gAAbjVEDVAAGgUeAIE4BYTIAC3mAABuMUECMAtJkAAbjEBAnCLCRCAW0yAANxiAgTgFhMgALeYAAG4xQQIwC0mQABuMQECcIsJEIBbTIAA3GICBOAWEyAAt5gAAbjVrAHuySEkjQfnApdQbW3tFfm7rWf2VsoZQVVVVZwLDAA5TIAA3GICBOBWQ9QAAZSA1u4uRmt7uZ+zNUD72mLfJ/dzjQlPgADcYgIE4BYpMHCFsmnl+fPnC47p9VVXpc89V1999QXf40Jyae/Jkydj3KxZOrU0bdq04P3Pnj2bvWc58QQIwC0mQABuMQECcMt1DXDBggXJ9fHjx2O8Zs2aZOytt94q+D4vvPBCcj1lypQY33TTTZfwCeGR1uty9bFTp04l12fOnCn4c4cPH47xsWPHkjGtz/3zzz/JmH2f9u3bx7h169bJmF5rXTGEEFq1ahVjWwNsSI3nkwDAZcYECMCtJg3Qod2gLeGPP/54jN98882y3GPo0KExXr58eTKmKUQjwG4wJVTf3WBs64m2mpw+fToZO3HiRIz37NmTjG3fvj3Gv/zySzL2448/xvjgwYPJmKbENq3t1atXcj148OAY33LLLcnYwIEDY9yuXbtkTFNimwLn2meUpuoh5FelsBsMAFwEEyAAt5gAAbhV8W0wWvMLofi638iRI5Pru+++O8ZbtmxJxt59993kesOGDTH+8MMPk7FHHnmkqPvDL60J2raUffv2xXjFihXJ2KZNm2K8cOHCgu8/ceLE5HrEiBEx1naZEEKoqalJrvfv3x/jv//+OxkbO3ZsjNu2bZuMab3Otu80b948xufOnUvGtF5o/yxatGhxwfevC54AAbjFBAjArYpMgXfs2BHjt99+u+DrxowZk1x/+eWXMdbO9RDSx237mP77778n19pyoCkLcCG2LURbX7RFJIQ0RT106FAytnPnzhiPHz8+GZs8eXKMb7311mSsQ4cOMV69enUy9tFHHyXX2jKze/fuZExT4p49eyZjukrFprK51pfc63SVim2RKRZPgADcYgIE4BYTIAC3KrIGqHU3+9/jWvf79ttvk7E2bdoU9f7z5s1LrletWlXwtdOmTSvqPeFXXXZo1lp0VVVVMqY7Dw0bNiwZGz58eIwHDBiQjGnt0LbB7N27N7nWGqD999KpU6eCY1rLzB2YZP+95naSrm/dT/EECMAtJkAAblVkCjxq1KgY2zYUTSFatmxZr/e3rTX6X/zA/2iqZ9M+TW1tq4uujLC7B+nvrE0z9R62DaVz584xPnDgQDK2devWGH/99dfJ2Pr165PrHj16FLyHpsBHjhwp+NnsjjO51R6aEpci5bV4AgTgFhMgALeYAAG4VZE1QFWqHZjnz58f43Xr1mVfO3Xq1Bj379+/JPfHlSdXA1R25xStD2o9MIS0RmZ/TpeKaa3bvqfu6BJCegCYXdZp63UTJkyIsW2n0SWi9nNrnTzXBpOr89klqCr355vDEyAAt5gAAbhV8SlwfdlDZR577LEY24NqtDUghBDmzJkTY5sKwA9NO22KpqmeTfs0lbUtMpoG2vKO/l7mdk6xqzt0g1+72kJbykJINz21v/d6Dz1jO4Q0Jbfpuab1Ns0t96FtPAECcIsJEIBbTIAA3KIGWIA9cMbW/dTMmTOTaz0gGgjh/2tZdpcXpTUy3X0lhLTOZutleq2vCyGE3377LcYffPBBMrZ8+fIYd+3aNRnTXWRCSGuC3bp1S8b0ACVb19QlfLYeauuOSl9r/wz15zgUCQDqiAkQgFukwOLhhx+OsU0T1FNPPZVcP/PMM2X7TKhMufQtV27RsRMnTiRjmmYePHgwGdPDjr777ruC79+rV6/k2qbAmiLbFSXa8qWbuoYQwjXXXBNjm/7rKhGbDudS21K0yPAECMAtJkAAbjEBAnDLdQ3Qthh88cUXMT516lQy1r179xg///zzyZhd2gNYuR1QbMuKvVZ6iLmts2nryaZNm5Ix3cHI1s5uvPHGGNtDvGxLl/67yC1bs0v4dMwevNSuXbsY239LudYefc9cK00OT4AA3GICBOCW6xR4+vTpyfWePXsKvvbJJ5+MsR7+Alwqu2pC0zk7pqm0bSfZsWNHjO2Z1z/99FOMNY0OIYRBgwbFeMSIEcmYPXhJ23DsoWKaktrdaPSQJG2JCSH9vjYF1jKVTYFLsdMST4AA3GICBOAWEyAAt9zVAPUAmGXLlhV83V133ZVcz5o1q1wfCQ7Y1hO9zu0WbX9Ol7/ZQ8Q3b94c419//bXg/bTmF0III0eOvOC9Q0iXqYWQ1gRtO4t+Hluv08OV7HfS72/fU+uc9W11yeEJEIBbTIAA3GICBOBWxdcA7ZKc2bNnx9jWN9To0aOTa5a7oVxyB35b2of3559/JmOLFy+O8caNG5OxG264Ica21693794xtr11ttdP+/Ls6XJaP7S9hq1atYqx7RHU73T06NFkTF+r71EqPAECcIsJEIBbFZ8Cv/HGG8n1kiVLCr5Wd4Sm7QXlpOmibYPR1g/bMqI7PduDuzQl1h1WQkgPNJ8wYUIy1rlz5wve+0L0s9o0V++Za+2xY9r6YlPgjh07xtimztp2Y9t3isUTIAC3mAABuMUECMCtiq8B2t2bc1599dUY0/aCctJlXbZVS2tdtgaobSj79u1LxrQtxbaMaKtLdXV1wc9ll6LZ++sSN1uT0zqcXQqn31EPUA8hhF27dhW8n7bl2G20SoEnQABuMQECcKviU+C60PTiUnae0MNq7H/Pa9d/7gBsmxbNmTOnqHvb+2kJoBQ76KJ+6pJKavqaOzBp69atyZimkt26dUvGdEdmfV0IIRw4cCDG9vfOptLa+mLbWTZs2BBj286i6blNgbWdZejQoclYVVVVjO2/yVLsDsMTIAC3mAABuMUECMAtaoCiZ8+eJXmfmTNnxti2HNTW1sb49ddfL8n9cvQ7Pfroo2W/H4qjS85sDVDrhXbHIq0b2/qg1pftTjFLly6N8W+//ZaMHT9+PMa643QIIbRt2za51laU9u3bJ2Na27MtOlp/trW7AQMGxNj+WWg93dZRS4EnQABuMQECcKviU+AZM2Yk13Pnzi37Pe0ONMXSx//c7hYPPfRQcj1+/PiCr504cWK9PgsunW0TUZoC29dpqmdXP3Tp0iXG9u99//79Md62bVsy9v333xf8LNqyou9/IXooUr9+/ZIxTcFtuqrfV1PeENKWnT59+iRjmmbXd8eXHJ4AAbjFBAjALSZAAG41Kcd/LV/EZb+heu+992KcOxTJWrduXYzr0r7y9NNPJ9fXX399wdfecccdMbZLmcqkcJEKdVZbW1v077bWxOwSRR2zS9F0SZttWdE2FP19DSGt8+mu0vbnVq5cmYzpUrQQ0l2Shg8fnoxpvdLuFt29e/cY29aaHj16xFh3gA4h3WW6Lks5q6qqivrd5gkQgFtMgADccpcCI0EKXEK5FNi2cOi/u1y7jF01oSmofU8t6dizhvV97P0OHToUY7tTjH1t69atLxiHkKbuuoIjhBBOnToVCtHvZFeC5D53DikwAFwEEyAAt5gAAbhV8UvhgMbA1uS0nlWXOnyulqb3sK/TOpttrenUqVOM9ZB0+zkte4i61utyO2DbP4vcErpy4wkQgFtMgADcIgUGGkCxqZ7d9FTpYUIhpClpLj21BxZpmmtTXns+tn4euzIjd0iRprn2c+fKAaU4+CiHJ0AAbjEBAnCLCRCAW9QAgUam2CVftj6ndTZbA9Rlc7bOlrufrUFq/c6O5XZr0Xva5W653bHLjSdAAG4xAQJwixQYaGTquxpC01ybZmp6bNNMTUEv1naS243GrvBQek+bnjckngABuMUECMAtJkAAbjXEjtAA0CjwBAjALSZAAG4xAQJwiwkQgFtMgADcYgIE4BYTIAC3mAABuMUECMAtJkAAbjEBAnCLCRCAW0yAANxiAgTgFhMgALeYAAG4xQQIwC0mQABuMQECcIsJEIBbTIAA3GICBOAWEyAAt5gAAbjFBAjArf8CDQYr7vEDsvQAAAAASUVORK5CYII=\n",
|
||
"text/plain": [
|
||
"<Figure size 432x288 with 4 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"n_test_digits = 2\n",
|
||
"# X_test = mnist.test.images[:n_test_digits]\n",
|
||
"\n",
|
||
"with tf.Session() as sess:\n",
|
||
" saver.restore(sess, \"./my_model_one_at_a_time.ckpt\") # not shown in the book\n",
|
||
" outputs_val = outputs.eval(feed_dict={X: X_test[:n_test_digits]})\n",
|
||
"\n",
|
||
"def plot_image(image, shape=[28, 28]):\n",
|
||
" plt.imshow(image.reshape(shape), cmap=\"Greys\", interpolation=\"nearest\")\n",
|
||
" plt.axis(\"off\")\n",
|
||
"\n",
|
||
"for digit_index in range(n_test_digits):\n",
|
||
" plt.subplot(n_test_digits, 2, digit_index * 2 + 1)\n",
|
||
" plot_image(X_test[digit_index])\n",
|
||
" plt.subplot(n_test_digits, 2, digit_index * 2 + 2)\n",
|
||
" plot_image(outputs_val[digit_index])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 특성 시각화"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 30,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"INFO:tensorflow:Restoring parameters from ./my_model_one_at_a_time.ckpt\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"image/png": "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\n",
|
||
"text/plain": [
|
||
"<Figure size 432x288 with 5 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"with tf.Session() as sess:\n",
|
||
" saver.restore(sess, \"./my_model_one_at_a_time.ckpt\") # 책에는 없음\n",
|
||
" weights1_val = weights1.eval()\n",
|
||
"\n",
|
||
"for i in range(5):\n",
|
||
" plt.subplot(1, 5, i + 1)\n",
|
||
" plot_image(weights1_val.T[i])\n",
|
||
"\n",
|
||
"save_fig(\"extracted_features_plot\") # 책에는 없음\n",
|
||
"plt.show() # 책에는 없음"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# 비지도 사전훈련"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"MNIST 분류 문제를 위한 작은 신경망을 만들겠습니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 31,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"reset_graph()\n",
|
||
"\n",
|
||
"n_inputs = 28 * 28\n",
|
||
"n_hidden1 = 300\n",
|
||
"n_hidden2 = 150\n",
|
||
"n_outputs = 10\n",
|
||
"\n",
|
||
"learning_rate = 0.01\n",
|
||
"l2_reg = 0.0005\n",
|
||
"\n",
|
||
"activation = tf.nn.elu\n",
|
||
"regularizer = tf.contrib.layers.l2_regularizer(l2_reg)\n",
|
||
"initializer = tf.contrib.layers.variance_scaling_initializer()\n",
|
||
"\n",
|
||
"X = tf.placeholder(tf.float32, shape=[None, n_inputs])\n",
|
||
"y = tf.placeholder(tf.int32, shape=[None])\n",
|
||
"\n",
|
||
"weights1_init = initializer([n_inputs, n_hidden1])\n",
|
||
"weights2_init = initializer([n_hidden1, n_hidden2])\n",
|
||
"weights3_init = initializer([n_hidden2, n_outputs])\n",
|
||
"\n",
|
||
"weights1 = tf.Variable(weights1_init, dtype=tf.float32, name=\"weights1\")\n",
|
||
"weights2 = tf.Variable(weights2_init, dtype=tf.float32, name=\"weights2\")\n",
|
||
"weights3 = tf.Variable(weights3_init, dtype=tf.float32, name=\"weights3\")\n",
|
||
"\n",
|
||
"biases1 = tf.Variable(tf.zeros(n_hidden1), name=\"biases1\")\n",
|
||
"biases2 = tf.Variable(tf.zeros(n_hidden2), name=\"biases2\")\n",
|
||
"biases3 = tf.Variable(tf.zeros(n_outputs), name=\"biases3\")\n",
|
||
"\n",
|
||
"hidden1 = activation(tf.matmul(X, weights1) + biases1)\n",
|
||
"hidden2 = activation(tf.matmul(hidden1, weights2) + biases2)\n",
|
||
"logits = tf.matmul(hidden2, weights3) + biases3\n",
|
||
"\n",
|
||
"cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, logits=logits)\n",
|
||
"reg_loss = regularizer(weights1) + regularizer(weights2) + regularizer(weights3)\n",
|
||
"loss = cross_entropy + reg_loss\n",
|
||
"optimizer = tf.train.AdamOptimizer(learning_rate)\n",
|
||
"training_op = optimizer.minimize(loss)\n",
|
||
"\n",
|
||
"correct = tf.nn.in_top_k(logits, y, 1)\n",
|
||
"accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))\n",
|
||
"\n",
|
||
"init = tf.global_variables_initializer()\n",
|
||
"pretrain_saver = tf.train.Saver([weights1, weights2, biases1, biases2])\n",
|
||
"saver = tf.train.Saver()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"(사전훈련 없이)평범하게 훈련시킵니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 32,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"0 훈련 정확도: 0.97333336 테스트 정확도: 0.9334\n",
|
||
"1 훈련 정확도: 0.98 테스트 정확도: 0.936\n",
|
||
"2 훈련 정확도: 0.97333336 테스트 정확도: 0.9382\n",
|
||
"3 훈련 정확도: 0.9866667 테스트 정확도: 0.9489\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"n_epochs = 4\n",
|
||
"batch_size = 150\n",
|
||
"n_labeled_instances = 20000\n",
|
||
"\n",
|
||
"with tf.Session() as sess:\n",
|
||
" init.run()\n",
|
||
" for epoch in range(n_epochs):\n",
|
||
" n_batches = n_labeled_instances // batch_size\n",
|
||
" for iteration in range(n_batches):\n",
|
||
" print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\")\n",
|
||
" sys.stdout.flush()\n",
|
||
" indices = rnd.permutation(n_labeled_instances)[:batch_size]\n",
|
||
" X_batch, y_batch = X_train[indices], y_train[indices]\n",
|
||
" sess.run(training_op, feed_dict={X: X_batch, y: y_batch})\n",
|
||
" accuracy_val = accuracy.eval(feed_dict={X: X_batch, y: y_batch})\n",
|
||
" print(\"\\r{}\".format(epoch), \"검증 세트 정확도:\", accuracy_val, end=\" \")\n",
|
||
" saver.save(sess, \"./my_model_supervised.ckpt\")\n",
|
||
" test_val = accuracy.eval(feed_dict={X: X_test, y: y_test})\n",
|
||
" print(\"테스트 정확도:\", test_val)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"사전 훈련된 오토인코더의 첫 두개의 층을 재사용해 보겠습니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 33,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"INFO:tensorflow:Restoring parameters from ./my_model_cache_frozen.ckpt\n",
|
||
"0 훈련 정확도: 0.9533333\t테스트 정확도: 0.9294\n",
|
||
"1 훈련 정확도: 0.96666664\t테스트 정확도: 0.9342\n",
|
||
"2 훈련 정확도: 0.98\t테스트 정확도: 0.9449\n",
|
||
"3 훈련 정확도: 0.9866667\t테스트 정확도: 0.9462\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"n_epochs = 4\n",
|
||
"batch_size = 150\n",
|
||
"n_labeled_instances = 20000\n",
|
||
"\n",
|
||
"#training_op = optimizer.minimize(loss, var_list=[weights3, biases3]) # layers 1와 2를 동결 (선택사항)\n",
|
||
"\n",
|
||
"with tf.Session() as sess:\n",
|
||
" init.run()\n",
|
||
" pretrain_saver.restore(sess, \"./my_model_cache_frozen.ckpt\")\n",
|
||
" for epoch in range(n_epochs):\n",
|
||
" n_batches = n_labeled_instances // batch_size\n",
|
||
" for iteration in range(n_batches):\n",
|
||
" print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\")\n",
|
||
" sys.stdout.flush()\n",
|
||
" indices = rnd.permutation(n_labeled_instances)[:batch_size]\n",
|
||
" X_batch, y_batch = X_train[indices], y_train[indices]\n",
|
||
" sess.run(training_op, feed_dict={X: X_batch, y: y_batch})\n",
|
||
" accuracy_val = accuracy.eval(feed_dict={X: X_batch, y: y_batch})\n",
|
||
" print(\"\\r{}\".format(epoch), \"훈련 정확도:\", accuracy_val, end=\"\\t\")\n",
|
||
" saver.save(sess, \"./my_model_supervised_pretrained.ckpt\")\n",
|
||
" test_val = accuracy.eval(feed_dict={X: X_test, y: y_test})\n",
|
||
" print(\"테스트 정확도:\", test_val)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# 적층 잡음제거 오토인코더"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"가우시안 잡음을 사용합니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 34,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"reset_graph()\n",
|
||
"\n",
|
||
"n_inputs = 28 * 28\n",
|
||
"n_hidden1 = 300\n",
|
||
"n_hidden2 = 150 # 코딩 유닛\n",
|
||
"n_hidden3 = n_hidden1\n",
|
||
"n_outputs = n_inputs\n",
|
||
"\n",
|
||
"learning_rate = 0.01"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 35,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"noise_level = 1.0\n",
|
||
"\n",
|
||
"X = tf.placeholder(tf.float32, shape=[None, n_inputs])\n",
|
||
"X_noisy = X + noise_level * tf.random_normal(tf.shape(X))\n",
|
||
"\n",
|
||
"hidden1 = tf.layers.dense(X_noisy, n_hidden1, activation=tf.nn.relu,\n",
|
||
" name=\"hidden1\")\n",
|
||
"hidden2 = tf.layers.dense(hidden1, n_hidden2, activation=tf.nn.relu, # 책에는 없음\n",
|
||
" name=\"hidden2\") # 책에는 없음\n",
|
||
"hidden3 = tf.layers.dense(hidden2, n_hidden3, activation=tf.nn.relu, # 책에는 없음\n",
|
||
" name=\"hidden3\") # 책에는 없음\n",
|
||
"outputs = tf.layers.dense(hidden3, n_outputs, name=\"outputs\") # 책에는 없음\n",
|
||
"\n",
|
||
"reconstruction_loss = tf.reduce_mean(tf.square(outputs - X)) # MSE"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 36,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"optimizer = tf.train.AdamOptimizer(learning_rate)\n",
|
||
"training_op = optimizer.minimize(reconstruction_loss)\n",
|
||
" \n",
|
||
"init = tf.global_variables_initializer()\n",
|
||
"saver = tf.train.Saver()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 37,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"0 훈련 MSE: 0.044004317\n",
|
||
"1 훈련 MSE: 0.04299514\n",
|
||
"2 훈련 MSE: 0.042179663\n",
|
||
"3 훈련 MSE: 0.040822495\n",
|
||
"4 훈련 MSE: 0.040334057\n",
|
||
"5 훈련 MSE: 0.038522195\n",
|
||
"6 훈련 MSE: 0.039496247\n",
|
||
"7 훈련 MSE: 0.04211809\n",
|
||
"8 훈련 MSE: 0.03993781\n",
|
||
"9 훈련 MSE: 0.04112029\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"n_epochs = 10\n",
|
||
"batch_size = 150\n",
|
||
"\n",
|
||
"with tf.Session() as sess:\n",
|
||
" init.run()\n",
|
||
" for epoch in range(n_epochs):\n",
|
||
" n_batches = len(X_train) // batch_size\n",
|
||
" for iteration in range(n_batches):\n",
|
||
" print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\")\n",
|
||
" sys.stdout.flush()\n",
|
||
" X_batch, y_batch = shuffle_batch(X_train, y_train, batch_size):\n",
|
||
" sess.run(training_op, feed_dict={X: X_batch})\n",
|
||
" loss_train = reconstruction_loss.eval(feed_dict={X: X_batch})\n",
|
||
" print(\"\\r{}\".format(epoch), \"훈련 MSE:\", loss_train)\n",
|
||
" saver.save(sess, \"./my_model_stacked_denoising_gaussian.ckpt\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"드롭아웃을 사용합니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 38,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"reset_graph()\n",
|
||
"\n",
|
||
"n_inputs = 28 * 28\n",
|
||
"n_hidden1 = 300\n",
|
||
"n_hidden2 = 150 # 코딩 유닛\n",
|
||
"n_hidden3 = n_hidden1\n",
|
||
"n_outputs = n_inputs\n",
|
||
"\n",
|
||
"learning_rate = 0.01"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 39,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"dropout_rate = 0.3\n",
|
||
"\n",
|
||
"training = tf.placeholder_with_default(False, shape=(), name='training')\n",
|
||
"\n",
|
||
"X = tf.placeholder(tf.float32, shape=[None, n_inputs])\n",
|
||
"X_drop = tf.layers.dropout(X, dropout_rate, training=training)\n",
|
||
"\n",
|
||
"hidden1 = tf.layers.dense(X_drop, n_hidden1, activation=tf.nn.relu,\n",
|
||
" name=\"hidden1\")\n",
|
||
"hidden2 = tf.layers.dense(hidden1, n_hidden2, activation=tf.nn.relu, # 책에는 없음\n",
|
||
" name=\"hidden2\") # 책에는 없음\n",
|
||
"hidden3 = tf.layers.dense(hidden2, n_hidden3, activation=tf.nn.relu, # 책에는 없음\n",
|
||
" name=\"hidden3\") # 책에는 없음\n",
|
||
"outputs = tf.layers.dense(hidden3, n_outputs, name=\"outputs\") # 책에는 없음\n",
|
||
"\n",
|
||
"reconstruction_loss = tf.reduce_mean(tf.square(outputs - X)) # MSE"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 40,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"optimizer = tf.train.AdamOptimizer(learning_rate)\n",
|
||
"training_op = optimizer.minimize(reconstruction_loss)\n",
|
||
" \n",
|
||
"init = tf.global_variables_initializer()\n",
|
||
"saver = tf.train.Saver()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 41,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"0 훈련 MSE: 0.02953044\n",
|
||
"1 훈련 MSE: 0.027892366\n",
|
||
"2 훈련 MSE: 0.024280708\n",
|
||
"3 훈련 MSE: 0.024674317\n",
|
||
"4 훈련 MSE: 0.024266083\n",
|
||
"5 훈련 MSE: 0.024863964\n",
|
||
"6 훈련 MSE: 0.024136161\n",
|
||
"7 훈련 MSE: 0.025188059\n",
|
||
"8 훈련 MSE: 0.024125345\n",
|
||
"9 훈련 MSE: 0.024291817\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"n_epochs = 10\n",
|
||
"batch_size = 150\n",
|
||
"\n",
|
||
"with tf.Session() as sess:\n",
|
||
" init.run()\n",
|
||
" for epoch in range(n_epochs):\n",
|
||
" n_batches = len(X_train) // batch_size\n",
|
||
" for iteration in range(n_batches):\n",
|
||
" print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\")\n",
|
||
" sys.stdout.flush()\n",
|
||
" X_batch, y_batch = shuffle_batch(X_train, y_train, batch_size):\n",
|
||
" sess.run(training_op, feed_dict={X: X_batch, training: True})\n",
|
||
" loss_train = reconstruction_loss.eval(feed_dict={X: X_batch})\n",
|
||
" print(\"\\r{}\".format(epoch), \"훈련 MSE:\", loss_train)\n",
|
||
" saver.save(sess, \"./my_model_stacked_denoising_dropout.ckpt\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 42,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"INFO:tensorflow:Restoring parameters from ./my_model_stacked_denoising_dropout.ckpt\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAa4AAAFrCAYAAACJ0G2dAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAG3ZJREFUeJzt3VlsVeX3xvEXiqVAS7EtLVBEUKwMTjiBU6LGeGPUqPFCvdCoicZEE03UaGKiJkYv5cao0ThfmBiHaBzimKhBYxRQcQABBRRaUCjQGfB/+ffHeha8+5z2HBb9fi5Xzrv3Pqc9Xezsh/WO+ffffxMAAFGMrfYFAABQBI0LABAKjQsAEAqNCwAQCo0LABAKjQsAEAqNCwAQCo0LABAKjQsAEAqNCwAQyrgqnJMZUxhuY6p9AaNVV1dX9vdZjZcbM2b4f3TeGLuROFfu+St17kobiffa2tp60ANwxwUACIXGBQAIhcYFAAilGs+4ABwmijzjqNRznrFj9b/H9+7da2rqmops9VRTU2Nq48bZP6veMdU1FTm/eq/79u3LXq/O5X1+SrWe3XHHBQAIhcYFAAiFxgUACIXGBQAIhcYFAAiFVCGAkhVJlam0W5H16rWq5qXqVILviCOOMDWVFEwppT179hzsEl3q3Aeq78/7nNR67/qVoaGhrGOqzykl/VkXSSWWijsuAEAoNC4AQCg0LgBAKDQuAEAohDMAVERuEKNIYEMFCbzAQ21trampkUfeyCW1XgURVODBC4yo8VC5Y6S816oQSV9fn1yfGw7xgilFgiBKkfFW/8UdFwAgFBoXACAUGhcAIBQaFwAgFMIZAEpWZD+u3Afx3noVcCgyuSE3iOAFIXJDF4ODg9nXpOrqc1LHTCk/MKJel5KeiKE+pyLTSFRgY7j3aOOOCwAQCo0LABAKjQsAEAqNCwAQCo0LABAKqUIAJSt3P60iI5dyE3hFxhONHz/e1LwEnkrW9ff3Zx2zSKpQfU7eaKXcpKa6Tu/8RcY45f5MS00PerjjAgCEQuMCAIRC4wIAhELjAgCEQjgDQNWocIA3mknVVRDDCwKo0EVdXZ2pqTFI3rnUMYvsEab2ycoNbBRRJByiqMBJSnoMlgp35I7bysUdFwAgFBoXACAUGhcAIBQaFwAglFEXzvjqq69MbenSpfK17e3tpjZhwgRTu/766+X6pqamrBowWg0MDJiat/fU9u3bs2o9PT1y/ZQpU0ytvr7e1FTgICUdzlA1NaVi9+7d8pi9vb2mpoIY3vrccMqCBQvk+o6ODlNTf6O8/bhywzXl7tFmzlvSKgAAqoTGBQAIhcYFAAiFxgUACIXGBQAIZdSlClUCcM2aNWUd85FHHpH1xsZGU1uyZElZ56qU2bNny/p9991narNmzRrhq8HhQCXTVIJQjUFKKaW1a9ea2rp160ztzz//lOtV2k+lGlXSL6WUdu3alfVaNTJq3Lj8P7Uq6eh9Jjt27DA1lXzeuHGjXD9x4sSs83vXn5sK9EZLlToKijsuAEAoNC4AQCg0LgBAKDQuAEAooy6c8eabb5raihUr5GsXLlxoaqtWrTK1r7/+Wq5/6623TO2DDz4wtTlz5pja+vXr5TFzeQ9Tp0+fbmreg1tFhTbuvffe7PUYvdQoJRU6UGOcUkpp69atpqaCVatXr5br1Z5SW7ZsMbVt27bJ9Wq8kgpCTJo0KauWUkpHH3101mtViCSllDZv3izr+2tra5P15cuXm9rkyZNNrbW1Nes8KenxTt7IqFJxxwUACIXGBQAIhcYFAAiFxgUACGXUhTPmz5+fVfOcdNJJpnbNNdfI1z722GOm9vvvv5uaCmeoiQBF1NbWyroKZ6jzqwfhKaU0b968sq4Lo1dNTY2pqd9TL1ik1qvJDer3OSW9H9fxxx9vat5+YCrgUFdXZ2oqXKFe571W1dQ+giml1NXVZWr//POPqanPLiX9XtU0EC8coqaEqGkYRSaH5OCOCwAQCo0LABAKjQsAEAqNCwAQCo0LABDKqEsVVpJKEuWm8ookHYtQ46nUiJvFixfL9RdffPGwXxNGBzVySSXQ1H5QKaU0Y8YMU1MJwqlTp8r1alyZSvA1NDTI9er6c5OSXspXrVf7fnkj4NS1qvFKLS0t2etVAlC995T0GKwirys1bcgdFwAgFBoXACAUGhcAIBQaFwAgFMIZh6menh5Zv+KKK0xNPcx9/PHH5Xq1/xBGLzVySe3H5FEP570ggwoSdHR0mJo38mnmzJmmpn6fvfFM6nui3r8ag+TtR+WNYtrf2LH6HqO7u9vUGhsbTW3atGlyvfqsmpqaTE29p5R0uKbIz79U3HEBAEKhcQEAQqFxAQBCoXEBAEIhnHGYev7552V9y5Ytptbc3GxqRx999HBfEg5DRR7EqyCDCh144YzJkyebmpp8ocIFXl2dPzcwkZJ+T7k171w7duwwtZUrV8r16vs8a9YsU/Omiag9xlRgxQuHqNDG0NBQ9vpScccFAAiFxgUACIXGBQAIhcYFAAiFcMZhYO3ataZ21113Za9ftmyZqXn/0x4YTuqhvfcgX4UG1ESKIuEKdS4vSKHq6vyq5oVY+vr6TE1tPfTll19mr29vbzc1L2ylPlMVjvF+JpWYkqFwxwUACIXGBQAIhcYFAAiFxgUACIXGBQAIhVThYeDtt982NTV2JaWUrr76alM75phjhv2aMDoU2Y8r97Xe3k8q7aZ+z9UeUV5dnb9IAnBgYMDU1PWrfcdSSumvv/4ytU8++cTUNm/eLNfPnTvX1BYuXGhqarRTSimNHz/e1IokLQcHB2U9d32pqUTuuAAAodC4AACh0LgAAKHQuAAAoRDOCEY9jH7jjTdMTT10TSmlRx991NSKjMgB/qvc/bhUYML7fVTjiVQQwgsC5O79tWfPHrk+Nwiirr+3t1ce89133zW1Dz/80NQaGxvl+osuusjUTj31VFOrr6+X69W15o6xSik/3FJkfQ7uuAAAodC4AACh0LgAAKHQuAAAoRDOCObZZ581tc8//9zUrr32WrmeKRmoFhWOUOEGb3KGooIUXjBJBQG8faYUNf1CXasKfPzwww/ymCqIsXXrVlO76qqr5PrLLrvM1JqamkzNC0Go0ER/f3/W6zzqM/UCN16Q5qDnKGkVAABVQuMCAIRC4wIAhELjAgCEQuMCAIRCqvAQtWLFClm//fbbTW3KlCmm9vDDDw/7NQHl8PbJ2p+X9CuSVlPU3lkqbeeNfFLnV7Wuri5Te/311+Uxly9fbmrHHXecqV1yySVy/axZs2R9f156T30muenPlPJHbnmpRkY+AQBGBRoXACAUGhcAIBQaFwAgFMIZh4C+vj5Tu+aaa+Rr1UPS6667ztQY7YRKUA/ivXBF7n5cHjVySY138sYTqT2xioycUu9LfXeXLVtmau+88448ptrj64ILLjC1M844Q65Xn0mRn4kKt6hr8sIdqq6uqdQQhoc7LgBAKDQuAEAoNC4AQCg0LgBAKIQzKkw9OFb/K/7XX3+V6+fPn29qDz30UPkXBpRAPXQv8iBfhQO8aRjqu6OCAEUCH4p3fjVRY/369ab21ltvmdrq1avlMU855RRTu/TSS01t8uTJcr36TCZMmGBqXjhCfVZFJl8oar33O1FkP7T/WVfSKgAAqoTGBQAIhcYFAAiFxgUACIXGBQAIhVRhhf3zzz+m9tlnn2Wvf+mll0ytqampnEsCqqbIeCBVV6k0b2STWu+9VlHf3S+++MLU1Mgn7z2dd955pqb22FJJQe+46jP1xmApar2XtBwcHMy6Ji9VWCruuAAAodC4AACh0LgAAKHQuAAAoRDOGEHd3d2mtmTJkqy1L7/8sqwvWrSorGsCqkUFIdTIIfXAP6WUamtrTU3tHeVRQQ51Lu+YP/30k6mpcMaGDRtMraOjQx7z9NNPN7XW1lZTq6urk+vVGKoiI69UaEN9Tl64Q/1MiuwHViruuAAAodC4AACh0LgAAKHQuAAAoRDOGEHPPfecqa1bty5r7bnnnivrRfbFAQ4ludMbvHBBb29v1vqBgYHsa1JBDBWuSCmlTz/91NRWrVplai0tLaam9txLKaUzzzzT1BobG01NhTBS0uGSInuUqb8n6rXqmJ7cPb688+fgjgsAEAqNCwAQCo0LABAKjQsAEAqNCwAQCqnCYbBmzRpZf/DBByt7IcAhTCXIclNtRXgJuJ6eHlNTY9m85O9ff/2Vdf758+eb2ty5c7PWpqRTkV6qUI1SUknJIvthFdlPK/e4w52G5o4LABAKjQsAEAqNCwAQCo0LABAK4Yxh8Pnnn8v6zp07s9arh7kTJkwo65qAQ416kF/koX1NTU1Zr1MBB/Ud/eOPP+R6NXJKXb/aT8sLjPT395va7t27TS33vaekwxne56zCHUXCGdXCHRcAIBQaFwAgFBoXACAUGhcAIBTCGRV29tlnm9qHH35oaoQzcLjJDWJ4r1MBARW48PbjUgGHhoYGU1u4cKFcr157wgknmFpzc7OpHXvssfKYKhyhrt8LZ6jPqra2Nnu92s9LGe79tMrFHRcAIBQaFwAgFBoXACAUGhcAIBQaFwAglDFVGOVxaM0OweGgOtEmpK6urjDf59xUohrt5FEJPpUU9KjXqgRgkVRfkZFNRa51JKhrnTp16kG/z9xxAQBCoXEBAEKhcQEAQqFxAQBCqUY4AwCAknHHBQAIhcYFAAiFxgUACIXGBQAIhcYFAAiFxgUACIXGBQAIhcYFAAiFxgUACIXGBQAIhcYFAAiFxgUACIXGBQAIhcYFAAiFxgUACIXGBQAIhcYFAAiFxgUACIXGBQAIhcYFAAiFxgUACIXGBQAIhcYFAAiFxgUACIXGBQAIhcYFAAiFxgUACIXGBQAIhcYFAAhlXBXO+W8VzonD25hqX8Bo1dnZyfd5FPv3X/vjHzOmvK9jW1vbQQ/AHRcAIBQaFwAgFBoXACCUajzjAoDCcp+njB2r/z2+d+/erPXqPEXOX1NTI9fnXpPivSdl37592a9V76nIucp9nlUq7rgAAKHQuAAAodC4AACh0LgAAKHQuAAAoZAqBBBCboKwSKquSCpOvTb3mrykokogqpqXPhwcHMw617hx+k+9utZyE4wjMU1jf9xxAQBCoXEBAEKhcQEAQqFxAQBCIZwxDF555RVZ7+npMbVvv/3W1J5++unscz3wwAOmduGFF5ra+eefn31MoFqKPMhXr1WhBS/IoL6P27dvN7Xe3l65fufOnaamggzq+uvr6+UxJ0yYYGpHHnlk9vojjjjC1IqEU3LDLd4xi4y3Gk7ccQEAQqFxAQBCoXEBAEKhcQEAQhnj/Y/uEVTxEw6n2267zdSeeuqpKlzJ/1uwYIGpffHFF/K1jY2NI3051VCdTYGQOjs7s7/PRfa+UlRAoL+/39S2bdsm1//888+m9sMPP5jaihUr5PrVq1ebmgonqMDF3Llz5TFPPvlkUzvttNNMTX3HU0qptbU165r27Nkj16vJG0X2OBsYGMh6bZHJGW1tbQd9MXdcAIBQaFwAgFBoXACAUGhcAIBQaFwAgFAY+XQAI5EgXLRokaldddVVprZmzRq5/oUXXjC1n376ydRee+01uf6mm2462CUCIyJ3vJOXNFSvVanCjRs3yvVq3NqXX35paio9mJIer1RbW2tqdXV1puYlHdW51Ptsb2+X66dPn25qKtXX19cn16tUobp+L5Wo9vkq8jMtNdXOHRcAIBQaFwAgFBoXACAUGhcAIBTCGSmlDRs2yPozzzyTtf6MM86Q9ffff9/UJk6caGrqAa+3p9Bvv/1mauoBs/cwGKiW3If23nggFcRQI4fU9yklvc+VGrm0ePFiuV6FFtS5du3aZWpdXV3ymN99952pbd261dSam5vl+mnTppmaGjmlQhgp+aGN/XmfqQptqMCGt5+Xem0O7rgAAKHQuAAAodC4AACh0LgAAKEQzkh+kEE9OFZBjI8++kiur6+vL/mann/+eVn/5ptvstZffvnlJZ8bKEeRaQhDQ0PZ69UDfhWYmDlzplyvggTz5s0ztZaWFrleBQlUiGrt2rWm5u2Pp/72qHDGkiVL5Hr1mahwixeCUNNAiuynpX5WRQI3XgjtYLjjAgCEQuMCAIRC4wIAhELjAgCEQuMCAIRCqjCldOqpp8q6Svyo0SdqxEq5vHFT3ugW4FDhJciU3FRcSjoZN378eFPzxhOpBKFKGqqkoqe7u9vU1B5ZXlJRXasaY+VR61Wa2fu7oT7rmpoaU1NJw5T0z0+lCtUxUyJVCAAYJWhcAIBQaFwAgFBoXACAUAhnHEBjY2NFzvPSSy+Z2sqVK7PXX3zxxaZ27LHHlnVNQKmKhDOKvFYFBFQ4wws3qPVqf7wie0SpIIc6vxrjlFJKnZ2dpqb+7jQ0NMj16v17QQpFhSPUeu8zyR355IUwivz8/4s7LgBAKDQuAEAoNC4AQCg0LgBAKIQzKmz58uWmdsstt5ia94BZ/a/8pUuXmpraZwcYbupBvBcOyA0CFNnPa/fu3abW19cnX6uOq8IV3uQN9Z3s7e01tc2bN5uaCmGkpMMJzc3NpnbUUUfJ9epaVZDCm1yh1qtr8sIVueEML9yhJm/k4I4LABAKjQsAEAqNCwAQCo0LABAKjQsAEAqpwgpbtmyZqRXZf+fWW281tY6OjrKuCSiVSqB5qUBVL5IqU+tVgtBLwKkEobp+tUeXdy6VINy4caOp9ff3y2OqBOGiRYtMbc6cOXJ9bnrYSxWqvQSHhoZMzRvNlDseipFPAIBRjcYFAAiFxgUACIXGBQAIhXDGCLrxxhtN7dVXX81ae+edd8r6PffcU9Y1AdVSZDyUkhtiUntUeXUvNKD09PSY2q5du0xNjYH6+++/5TGnTp1qajNmzDA1FSxJSX+mXhBEUZ+JCmd4gRUVrlBBkFJDGB7uuAAAodC4AACh0LgAAKHQuAAAoRDOGAZqT6CUUnrvvfdMTT04bWtrM7X7779fHtPbKwg41KkpDyoc4QUBco/pfUfUlAg1DaO7u1uu37Rpk6l1dXWZmgpiNDQ0yGNOmjTJ1NR72rJli1w/e/ZsUxscHDQ1b3KGmnKhPj91zJT0z69I4IXJGQCAUYHGBQAIhcYFAAiFxgUACIVwxjC4+uqrZV09uFXuuOMOU2tqairrmoBq8bY1UVuYlDtNQwUuvPW5W7CoCRkp6S1M/vjjD1NT4YoTTjhBHlO9dubMmabmhSN+/PFHU1OBj6OOOkquV+9f1bzAjLou9Z6YnAEAGNVoXACAUGhcAIBQaFwAgFBoXACAUEgVFvTtt9+a2meffZa9/sorrzS1u+66q5xLAqpGJdCKJMiKpArVcVVSUaXavNeqvbM2btwo1//yyy+mpsa9zZo1y9RaWlrkMVXaT+3R5VHJZTVeyjumGvmkEoTqc0pJpwpVqpFUIQBgVKNxAQBCoXEBAEKhcQEAQiGccQBqr5777rvP1LxxLMppp51mauyxhaiG+6H7gajQhap530cVMFDhht9++02u37p1q6m1traamtpfr6OjQx6zvb3d1Orr603NG0Ol3tOUKVNMTQVTvOPu3LnT1NR7T0mHOxobG01NjeZKif24AACjBI0LABAKjQsAEAqNCwAQCuGMA3jyySdN7eOPP85ef+ONN5oaUzIwWqkH8armTc7InfKgwgUppbRlyxZTW7Vqlan9/fffcr0KHagpGfPmzTM1tcdWSikdeeSRpqbev7cfltq3T4W9vM9EBVnU56T2IktJvy81TcQLoNXU1Mj6wXDHBQAIhcYFAAiFxgUACIXGBQAIhcYFAAhljNoPZ4RV/ISlUmNKiox36u7uNjU1zgVlq9zcIfyPzs7O7O9z7t8abwyQStuptNzq1avlepUg3LBhg6mpUW8ppTR9+nRTmz9/vqmpPba87/348eNNrb+/39R27dol12/fvt3U9u7da2oDAwNy/aZNm0xNJQgnTpwo1y9evNjUZs+ebWoq/ZiSToq2tbUd9PvMHRcAIBQaFwAgFBoXACAUGhcAIBRGPo0gNfrEG2dTDvWA1xulUuTBraIeXC9dujR7vaKu9f7775evVfsvIS71u6d+n1PSoY2hoSFT8/aO+vnnn03t+++/zz6/utYdO3aYmgqHeN9H9Z5U4MQLheWGM9TrUtLXr8ZQLVy4UK5X1HtV15SSDmfk4I4LABAKjQsAEAqNCwAQCo0LABAK4YwR1N7eXpHz3HrrraY2Y8YM+Vq1184TTzwx7NdULu+zu/nmmyt8JRgu+/btMzUVTvACOGryhnqtN+Wht7fX1FQQwptSsX79elNT+0ypiTttbW3ymNu2bTM1NXGnp6dHrldTNtT5vRCE2k9L/e047rjj5Ppp06aZ2qRJk0zNC6WVOrmJOy4AQCg0LgBAKDQuAEAoNC4AQCg0LgBAKKQKD+C6664zteeee64KV3JgTz755LAf00sheaNr9nfDDTfI+llnnZW1/pxzzsl6HWJTv2dFEmh1dXWmNnfuXLl+wYIFpqbGsq1bt06uV2k/tV6NZ1L7fqWk379KNXr7Wam9r9TIpubmZrm+o6PD1E488URT81KFLS0tpuaNzFK8vdcOhjsuAEAoNC4AQCg0LgBAKDQuAEAoY0oduVGGip9wOL344oum5u2Vk2vlypWmVu4YprvvvlvWvQfX+7vssstkvbW1teRrGkGlPeFF2To7O8v6Pqt9mrwAkBrvpEYheX/TNm3aZGorVqwwtT///FOuV+EM9d1XY5iKvCc1RmrOnDlyvRqvpEY+ed9bNR5L1RoaGrLPXyRwo7S1tR30+8wdFwAgFBoXACAUGhcAIBQaFwAgFMIZOBwQzqiSIuGM3L81at+ulPQD/j179mS9LiV/Gsz+VGAkpfz9wIrsp6UmR6jJF2pCSEopDQwMZF3n0NCQXJ/LO78KnajzF5mQQTgDAHDYoXEBAEKhcQEAQqFxAQBCoXEBAEJhPy4AFaGSZSqB5o1HUmlDlRT0UoGqnjtyKSWdrFPnb2xslOsVtb5IKlCNZ1JJQ5W+TEl/pqrmJTVV3UuFDifuuAAAodC4AACh0LgAAKHQuAAAoRDOABCCCjKoIIcXRFChBRUk8EZTqXCHWl9kvJLaO0vxrknV+/r6TM0LV6jPT722yMimSuCOCwAQCo0LABAKjQsAEAqNCwAQCuEMAFWTO00jJR2EUIEJb/KFqufuJ5WSvlZVUxM2VGDCq6tjeoETRb0nby8y9ZkWCWJUYkqGwh0XACAUGhcAIBQaFwAgFBoXACAUGhcAIBRShQAOKeWOFyqyH5caA+WNR8pN+6lUoveeVAKwyH5Y3t5lOcc80HVVSqnn544LABAKjQsAEAqNCwAQCo0LABDKGG+8CQAAhyLuuAAAodC4AACh0LgAAKHQuAAAodC4AACh0LgAAKHQuAAAodC4AACh0LgAAKHQuAAAodC4AACh0LgAAKHQuAAAodC4AACh0LgAAKHQuAAAodC4AACh0LgAAKHQuAAAodC4AACh0LgAAKHQuAAAodC4AACh0LgAAKHQuAAAofwf8ORPTEfR3xEAAAAASUVORK5CYII=\n",
|
||
"text/plain": [
|
||
"<Figure size 576x432 with 4 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"show_reconstructed_digits(X, outputs, \"./my_model_stacked_denoising_dropout.ckpt\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# 희소 오토인코더"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 43,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"image/png": "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\n",
|
||
"text/plain": [
|
||
"<Figure size 432x288 with 1 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"p = 0.1\n",
|
||
"q = np.linspace(0.001, 0.999, 500)\n",
|
||
"kl_div = p * np.log(p / q) + (1 - p) * np.log((1 - p) / (1 - q))\n",
|
||
"mse = (p - q)**2\n",
|
||
"plt.plot([p, p], [0, 0.3], \"k:\")\n",
|
||
"plt.text(0.05, 0.32, \"목표 희소\", fontsize=14)\n",
|
||
"plt.plot(q, kl_div, \"b-\", label=\"쿨백 라이블러 발산\")\n",
|
||
"plt.plot(q, mse, \"r--\", label=\"MSE\")\n",
|
||
"plt.legend(loc=\"upper left\")\n",
|
||
"plt.xlabel(\"실제 희소\")\n",
|
||
"plt.ylabel(\"비용\", rotation=0)\n",
|
||
"plt.axis([0, 1, 0, 0.95])\n",
|
||
"save_fig(\"sparsity_loss_plot\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 44,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"reset_graph()\n",
|
||
"\n",
|
||
"n_inputs = 28 * 28\n",
|
||
"n_hidden1 = 1000 # 희소 코딩 유닛\n",
|
||
"n_outputs = n_inputs"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 45,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def kl_divergence(p, q):\n",
|
||
" # 쿨백 라이블러 발산\n",
|
||
" return p * tf.log(p / q) + (1 - p) * tf.log((1 - p) / (1 - q))\n",
|
||
"\n",
|
||
"learning_rate = 0.01\n",
|
||
"sparsity_target = 0.1\n",
|
||
"sparsity_weight = 0.2\n",
|
||
"\n",
|
||
"X = tf.placeholder(tf.float32, shape=[None, n_inputs]) # 책에는 없음\n",
|
||
"\n",
|
||
"hidden1 = tf.layers.dense(X, n_hidden1, activation=tf.nn.sigmoid) # 책에는 없음\n",
|
||
"outputs = tf.layers.dense(hidden1, n_outputs) # 책에는 없음\n",
|
||
"\n",
|
||
"hidden1_mean = tf.reduce_mean(hidden1, axis=0) # 배치 평균\n",
|
||
"sparsity_loss = tf.reduce_sum(kl_divergence(sparsity_target, hidden1_mean))\n",
|
||
"reconstruction_loss = tf.reduce_mean(tf.square(outputs - X)) # MSE\n",
|
||
"loss = reconstruction_loss + sparsity_weight * sparsity_loss\n",
|
||
"\n",
|
||
"optimizer = tf.train.AdamOptimizer(learning_rate)\n",
|
||
"training_op = optimizer.minimize(loss)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 46,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"init = tf.global_variables_initializer()\n",
|
||
"saver = tf.train.Saver()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 47,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"0 훈련 MSE: 0.13819474 \t희소 손실: 0.4184438 \t전체 손실: 0.2218835\n",
|
||
"1 훈련 MSE: 0.059185907 \t희소 손실: 0.010747713 \t전체 손실: 0.06133545\n",
|
||
"2 훈련 MSE: 0.053931113 \t희소 손실: 0.01995793 \t전체 손실: 0.0579227\n",
|
||
"3 훈련 MSE: 0.04771372 \t희소 손실: 0.039470345 \t전체 손실: 0.05560779\n",
|
||
"4 훈련 MSE: 0.044841796 \t희소 손실: 0.011593144 \t전체 손실: 0.047160424\n",
|
||
"5 훈련 MSE: 0.04044193 \t희소 손실: 0.092471 \t전체 손실: 0.058936134\n",
|
||
"6 훈련 MSE: 0.03886659 \t희소 손실: 0.04581263 \t전체 손실: 0.048029117\n",
|
||
"7 훈련 MSE: 0.037868652 \t희소 손실: 0.07498071 \t전체 손실: 0.052864797\n",
|
||
"8 훈련 MSE: 0.033122517 \t희소 손실: 0.020321768 \t전체 손실: 0.037186872\n",
|
||
"9 훈련 MSE: 0.031449173 \t희소 손실: 0.095670156 \t전체 손실: 0.050583206\n",
|
||
"10 훈련 MSE: 0.027398113 \t희소 손실: 0.06570565 \t전체 손실: 0.040539242\n",
|
||
"11 훈련 MSE: 0.024734963 \t희소 손실: 0.08889264 \t전체 손실: 0.04251349\n",
|
||
"12 훈련 MSE: 0.023367295 \t희소 손실: 0.05766213 \t전체 손실: 0.03489972\n",
|
||
"13 훈련 MSE: 0.023007901 \t희소 손실: 0.06193536 \t전체 손실: 0.035394974\n",
|
||
"14 훈련 MSE: 0.02123353 \t희소 손실: 0.025881292 \t전체 손실: 0.02640979\n",
|
||
"15 훈련 MSE: 0.022064691 \t희소 손실: 0.48820361 \t전체 손실: 0.119705416\n",
|
||
"16 훈련 MSE: 0.01910253 \t희소 손실: 0.03220318 \t전체 손실: 0.025543166\n",
|
||
"17 훈련 MSE: 0.018982193 \t희소 손실: 0.1299511 \t전체 손실: 0.044972412\n",
|
||
"18 훈련 MSE: 0.017487913 \t희소 손실: 0.035001524 \t전체 손실: 0.024488218\n",
|
||
"19 훈련 MSE: 0.017776337 \t희소 손실: 0.11024489 \t전체 손실: 0.039825313\n",
|
||
"20 훈련 MSE: 0.01691014 \t희소 손실: 0.030320974 \t전체 손실: 0.022974335\n",
|
||
"21 훈련 MSE: 0.018679725 \t희소 손실: 0.36376736 \t전체 손실: 0.0914332\n",
|
||
"22 훈련 MSE: 0.016285753 \t희소 손실: 0.055482175 \t전체 손실: 0.027382188\n",
|
||
"23 훈련 MSE: 0.015950203 \t희소 손실: 0.07936562 \t전체 손실: 0.03182333\n",
|
||
"24 훈련 MSE: 0.015672015 \t희소 손실: 0.14289382 \t전체 손실: 0.04425078\n",
|
||
"25 훈련 MSE: 0.014612303 \t희소 손실: 0.13330582 \t전체 손실: 0.041273467\n",
|
||
"26 훈련 MSE: 0.014524783 \t희소 손실: 0.10948151 \t전체 손실: 0.036421087\n",
|
||
"27 훈련 MSE: 0.013598451 \t희소 손실: 0.07208073 \t전체 손실: 0.028014597\n",
|
||
"28 훈련 MSE: 0.014069849 \t희소 손실: 0.1578956 \t전체 손실: 0.045648966\n",
|
||
"29 훈련 MSE: 0.01344161 \t희소 손실: 0.14449331 \t전체 손실: 0.04234027\n",
|
||
"30 훈련 MSE: 0.013608929 \t희소 손실: 0.18506998 \t전체 손실: 0.050622925\n",
|
||
"31 훈련 MSE: 0.014197284 \t희소 손실: 0.06788698 \t전체 손실: 0.02777468\n",
|
||
"32 훈련 MSE: 0.013759439 \t희소 손실: 0.057576388 \t전체 손실: 0.025274716\n",
|
||
"33 훈련 MSE: 0.013667366 \t희소 손실: 0.11363433 \t전체 손실: 0.03639423\n",
|
||
"34 훈련 MSE: 0.01264697 \t희소 손실: 0.13469386 \t전체 손실: 0.039585743\n",
|
||
"35 훈련 MSE: 0.012872911 \t희소 손실: 0.1685048 \t전체 손실: 0.046573874\n",
|
||
"36 훈련 MSE: 0.012669464 \t희소 손실: 0.09312945 \t전체 손실: 0.031295355\n",
|
||
"37 훈련 MSE: 0.012427666 \t희소 손실: 0.10538912 \t전체 손실: 0.033505492\n",
|
||
"38 훈련 MSE: 0.012336045 \t희소 손실: 0.19236036 \t전체 손실: 0.050808117\n",
|
||
"39 훈련 MSE: 0.0123378765 \t희소 손실: 0.1423154 \t전체 손실: 0.04080096\n",
|
||
"40 훈련 MSE: 0.012627057 \t희소 손실: 0.23267198 \t전체 손실: 0.059161454\n",
|
||
"41 훈련 MSE: 0.0123833865 \t희소 손실: 0.10489211 \t전체 손실: 0.033361807\n",
|
||
"42 훈련 MSE: 0.011781143 \t희소 손실: 0.10161278 \t전체 손실: 0.0321037\n",
|
||
"43 훈련 MSE: 0.012043943 \t희소 손실: 0.13593857 \t전체 손실: 0.039231658\n",
|
||
"44 훈련 MSE: 0.011620727 \t희소 손실: 0.114727125 \t전체 손실: 0.034566153\n",
|
||
"45 훈련 MSE: 0.011668878 \t희소 손실: 0.15798113 \t전체 손실: 0.043265104\n",
|
||
"46 훈련 MSE: 0.011761186 \t희소 손실: 0.13549805 \t전체 손실: 0.038860794\n",
|
||
"47 훈련 MSE: 0.011549666 \t희소 손실: 0.15659894 \t전체 손실: 0.042869456\n",
|
||
"48 훈련 MSE: 0.011674238 \t희소 손실: 0.44305113 \t전체 손실: 0.100284465\n",
|
||
"49 훈련 MSE: 0.011562435 \t희소 손실: 0.1758345 \t전체 손실: 0.046729334\n",
|
||
"50 훈련 MSE: 0.01136023 \t희소 손실: 0.18884605 \t전체 손실: 0.04912944\n",
|
||
"51 훈련 MSE: 0.01153872 \t희소 손실: 0.2633665 \t전체 손실: 0.06421202\n",
|
||
"52 훈련 MSE: 0.012044075 \t희소 손실: 0.36758316 \t전체 손실: 0.0855607\n",
|
||
"53 훈련 MSE: 0.011250994 \t희소 손실: 0.12487886 \t전체 손실: 0.036226768\n",
|
||
"54 훈련 MSE: 0.013878834 \t희소 손실: 0.43317184 \t전체 손실: 0.100513205\n",
|
||
"55 훈련 MSE: 0.012782411 \t희소 손실: 0.07718266 \t전체 손실: 0.028218944\n",
|
||
"56 훈련 MSE: 0.012197349 \t희소 손실: 0.301488 \t전체 손실: 0.072494954\n",
|
||
"57 훈련 MSE: 0.012758316 \t희소 손실: 0.24829106 \t전체 손실: 0.062416527\n",
|
||
"58 훈련 MSE: 0.023019526 \t희소 손실: 0.23253448 \t전체 손실: 0.06952642\n",
|
||
"59 훈련 MSE: 0.0134694 \t희소 손실: 0.1981337 \t전체 손실: 0.053096145\n",
|
||
"60 훈련 MSE: 0.019005049 \t희소 손실: 0.19429345 \t전체 손실: 0.057863742\n",
|
||
"61 훈련 MSE: 0.012830879 \t희소 손실: 0.22918573 \t전체 손실: 0.058668025\n",
|
||
"62 훈련 MSE: 0.013951195 \t희소 손실: 0.47963494 \t전체 손실: 0.10987819\n",
|
||
"63 훈련 MSE: 0.014569022 \t희소 손실: 0.33389828 \t전체 손실: 0.08134868\n",
|
||
"64 훈련 MSE: 0.011955362 \t희소 손실: 0.17778753 \t전체 손실: 0.047512867\n",
|
||
"65 훈련 MSE: 0.016137443 \t희소 손실: 0.18549094 \t전체 손실: 0.05323563\n",
|
||
"66 훈련 MSE: 0.014922719 \t희소 손실: 0.9833389 \t전체 손실: 0.2115905\n",
|
||
"67 훈련 MSE: 0.037293304 \t희소 손실: 0.31203473 \t전체 손실: 0.09970025\n",
|
||
"68 훈련 MSE: 0.015952839 \t희소 손실: 0.21828063 \t전체 손실: 0.059608966\n",
|
||
"69 훈련 MSE: 0.012261292 \t희소 손실: 0.43984902 \t전체 손실: 0.100231096\n",
|
||
"70 훈련 MSE: 0.037013255 \t희소 손실: 0.7457465 \t전체 손실: 0.18616256\n",
|
||
"71 훈련 MSE: 0.014764387 \t희소 손실: 0.24276587 \t전체 손실: 0.06331757\n",
|
||
"72 훈련 MSE: 0.016606566 \t희소 손실: 0.7994744 \t전체 손실: 0.17650145\n",
|
||
"73 훈련 MSE: 0.0144267725 \t희소 손실: 0.31668615 \t전체 손실: 0.077764004\n",
|
||
"74 훈련 MSE: 0.036295358 \t희소 손실: 0.32408017 \t전체 손실: 0.1011114\n",
|
||
"75 훈련 MSE: 0.038099732 \t희소 손실: 0.5090959 \t전체 손실: 0.13991891\n",
|
||
"76 훈련 MSE: 0.019446107 \t희소 손실: 0.20034213 \t전체 손실: 0.059514537\n",
|
||
"77 훈련 MSE: 0.022708207 \t희소 손실: 0.3122869 \t전체 손실: 0.08516559\n",
|
||
"78 훈련 MSE: 0.016776377 \t희소 손실: 0.5347481 \t전체 손실: 0.123725995\n",
|
||
"79 훈련 MSE: 0.02007503 \t희소 손실: 0.42173243 \t전체 손실: 0.10442152\n",
|
||
"80 훈련 MSE: 0.015990663 \t희소 손실: 0.11620571 \t전체 손실: 0.039231807\n",
|
||
"81 훈련 MSE: 0.012873366 \t희소 손실: 0.8802524 \t전체 손실: 0.18892385\n",
|
||
"82 훈련 MSE: 0.015848754 \t희소 손실: 2.1350327 \t전체 손실: 0.4428553\n",
|
||
"83 훈련 MSE: 0.014213436 \t희소 손실: 0.6619952 \t전체 손실: 0.14661248\n",
|
||
"84 훈련 MSE: 0.0148504 \t희소 손실: 0.27111006 \t전체 손실: 0.06907241\n",
|
||
"85 훈련 MSE: 0.028653098 \t희소 손실: 0.9375648 \t전체 손실: 0.21616606\n",
|
||
"86 훈련 MSE: 0.014789838 \t희소 손실: 0.68491566 \t전체 손실: 0.15177298\n",
|
||
"87 훈련 MSE: 0.012122109 \t희소 손실: 1.4151382 \t전체 손실: 0.29514974\n",
|
||
"88 훈련 MSE: 0.019227153 \t희소 손실: 0.85921484 \t전체 손실: 0.19107012\n",
|
||
"89 훈련 MSE: 0.028509108 \t희소 손실: 0.29490086 \t전체 손실: 0.087489285\n",
|
||
"90 훈련 MSE: 0.028761363 \t희소 손실: 0.45986366 \t전체 손실: 0.120734096\n",
|
||
"91 훈련 MSE: 0.014937726 \t희소 손실: 0.098271474 \t전체 손실: 0.03459202\n",
|
||
"92 훈련 MSE: 0.014802266 \t희소 손실: 0.3885908 \t전체 손실: 0.09252043\n",
|
||
"93 훈련 MSE: 0.015891917 \t희소 손실: 0.1618818 \t전체 손실: 0.048268277\n",
|
||
"94 훈련 MSE: 0.012146741 \t희소 손실: 0.115840726 \t전체 손실: 0.035314888\n",
|
||
"95 훈련 MSE: 0.013941603 \t희소 손실: 0.10216563 \t전체 손실: 0.03437473\n",
|
||
"96 훈련 MSE: 0.019508341 \t희소 손실: 0.23841716 \t전체 손실: 0.06719177\n",
|
||
"97 훈련 MSE: 0.013997071 \t희소 손실: 0.108866125 \t전체 손실: 0.035770297\n",
|
||
"98 훈련 MSE: 0.013801815 \t희소 손실: 0.09045001 \t전체 손실: 0.031891815\n",
|
||
"99 훈련 MSE: 0.02559923 \t희소 손실: 0.33294424 \t전체 손실: 0.092188075\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"n_epochs = 100\n",
|
||
"batch_size = 1000\n",
|
||
"\n",
|
||
"with tf.Session() as sess:\n",
|
||
" init.run()\n",
|
||
" for epoch in range(n_epochs):\n",
|
||
" n_batches = len(X_train) // batch_size\n",
|
||
" for iteration in range(n_batches):\n",
|
||
" print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\")\n",
|
||
" sys.stdout.flush()\n",
|
||
" X_batch, y_batch = shuffle_batch(X_train, y_train, batch_size):\n",
|
||
" sess.run(training_op, feed_dict={X: X_batch})\n",
|
||
" reconstruction_loss_val, sparsity_loss_val, loss_val = sess.run([reconstruction_loss, sparsity_loss, loss], feed_dict={X: X_batch})\n",
|
||
" print(\"\\r{}\".format(epoch), \"훈련 MSE:\", reconstruction_loss_val, \"\\t희소 손실:\", sparsity_loss_val, \"\\t전체 손실:\", loss_val)\n",
|
||
" saver.save(sess, \"./my_model_sparse.ckpt\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 48,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"INFO:tensorflow:Restoring parameters from ./my_model_sparse.ckpt\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"image/png": "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\n",
|
||
"text/plain": [
|
||
"<Figure size 576x432 with 4 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"show_reconstructed_digits(X, outputs, \"./my_model_sparse.ckpt\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"코딩층은 0에서 1사이의 값을 출력해야 하므로 시그모이드 활성화 함수를 사용합니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 49,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"hidden1 = tf.layers.dense(X, n_hidden1, activation=tf.nn.sigmoid)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"훈련 속도를 높이기 위해 입력을 0과 1사이로 정규화하고 비용 함수로 MSE 대신 크로스엔트로피를 사용합니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 50,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"logits = tf.layers.dense(hidden1, n_outputs)\n",
|
||
"outputs = tf.nn.sigmoid(logits)\n",
|
||
"\n",
|
||
"xentropy = tf.nn.sigmoid_cross_entropy_with_logits(labels=X, logits=logits)\n",
|
||
"reconstruction_loss = tf.reduce_mean(xentropy)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# 변이형 오토인코더"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 51,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"reset_graph()\n",
|
||
"\n",
|
||
"from functools import partial\n",
|
||
"\n",
|
||
"n_inputs = 28 * 28\n",
|
||
"n_hidden1 = 500\n",
|
||
"n_hidden2 = 500\n",
|
||
"n_hidden3 = 20 # 코딩 유닛\n",
|
||
"n_hidden4 = n_hidden2\n",
|
||
"n_hidden5 = n_hidden1\n",
|
||
"n_outputs = n_inputs\n",
|
||
"learning_rate = 0.001\n",
|
||
"\n",
|
||
"initializer = tf.contrib.layers.variance_scaling_initializer()\n",
|
||
"\n",
|
||
"my_dense_layer = partial(\n",
|
||
" tf.layers.dense,\n",
|
||
" activation=tf.nn.elu,\n",
|
||
" kernel_initializer=initializer)\n",
|
||
"\n",
|
||
"X = tf.placeholder(tf.float32, [None, n_inputs])\n",
|
||
"hidden1 = my_dense_layer(X, n_hidden1)\n",
|
||
"hidden2 = my_dense_layer(hidden1, n_hidden2)\n",
|
||
"hidden3_mean = my_dense_layer(hidden2, n_hidden3, activation=None)\n",
|
||
"hidden3_sigma = my_dense_layer(hidden2, n_hidden3, activation=None)\n",
|
||
"noise = tf.random_normal(tf.shape(hidden3_sigma), dtype=tf.float32)\n",
|
||
"hidden3 = hidden3_mean + hidden3_sigma * noise\n",
|
||
"hidden4 = my_dense_layer(hidden3, n_hidden4)\n",
|
||
"hidden5 = my_dense_layer(hidden4, n_hidden5)\n",
|
||
"logits = my_dense_layer(hidden5, n_outputs, activation=None)\n",
|
||
"outputs = tf.sigmoid(logits)\n",
|
||
"\n",
|
||
"xentropy = tf.nn.sigmoid_cross_entropy_with_logits(labels=X, logits=logits)\n",
|
||
"reconstruction_loss = tf.reduce_sum(xentropy)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 52,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"eps = 1e-10 # NaN을 반환하는 log(0)을 피하기 위한 안전항\n",
|
||
"latent_loss = 0.5 * tf.reduce_sum(\n",
|
||
" tf.square(hidden3_sigma) + tf.square(hidden3_mean)\n",
|
||
" - 1 - tf.log(eps + tf.square(hidden3_sigma)))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 53,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"loss = reconstruction_loss + latent_loss\n",
|
||
"\n",
|
||
"optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)\n",
|
||
"training_op = optimizer.minimize(loss)\n",
|
||
"\n",
|
||
"init = tf.global_variables_initializer()\n",
|
||
"saver = tf.train.Saver()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 54,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"0 훈련 전체 손실: 38016.934 \t재구성 손실: 26717.334 \t잠재 손실: 11299.599\n",
|
||
"1 훈련 전체 손실: 30065.5 \t재구성 손실: 24319.137 \t잠재 손실: 5746.3633\n",
|
||
"2 훈련 전체 손실: 32188.535 \t재구성 손실: 24696.451 \t잠재 손실: 7492.085\n",
|
||
"3 훈련 전체 손실: 29995.074 \t재구성 손실: 24591.836 \t잠재 손실: 5403.2393\n",
|
||
"4 훈련 전체 손실: 22977.074 \t재구성 손실: 19545.846 \t잠재 손실: 3431.228\n",
|
||
"5 훈련 전체 손실: 21461.336 \t재구성 손실: 18221.758 \t잠재 손실: 3239.5786\n",
|
||
"6 훈련 전체 손실: 17799.531 \t재구성 손실: 14987.603 \t잠재 손실: 2811.9297\n",
|
||
"7 훈련 전체 손실: 17872.271 \t재구성 손실: 14900.03 \t잠재 손실: 2972.2415\n",
|
||
"8 훈련 전체 손실: 16473.062 \t재구성 손실: 13437.503 \t잠재 손실: 3035.5598\n",
|
||
"9 훈련 전체 손실: 18285.943 \t재구성 손실: 15230.208 \t잠재 손실: 3055.7349\n",
|
||
"10 훈련 전체 손실: 17281.297 \t재구성 손실: 14238.846 \t잠재 손실: 3042.4512\n",
|
||
"11 훈련 전체 손실: 16178.416 \t재구성 손실: 13091.535 \t잠재 손실: 3086.881\n",
|
||
"12 훈련 전체 손실: 16544.488 \t재구성 손실: 13217.236 \t잠재 손실: 3327.253\n",
|
||
"13 훈련 전체 손실: 16427.021 \t재구성 손실: 13077.631 \t잠재 손실: 3349.391\n",
|
||
"14 훈련 전체 손실: 16616.738 \t재구성 손실: 13293.669 \t잠재 손실: 3323.07\n",
|
||
"15 훈련 전체 손실: 16271.476 \t재구성 손실: 13142.443 \t잠재 손실: 3129.0325\n",
|
||
"16 훈련 전체 손실: 16567.523 \t재구성 손실: 13333.615 \t잠재 손실: 3233.9075\n",
|
||
"17 훈련 전체 손실: 29101.3 \t재구성 손실: 24271.592 \t잠재 손실: 4829.709\n",
|
||
"18 훈련 전체 손실: 24227.15 \t재구성 손실: 20683.895 \t잠재 손실: 3543.2554\n",
|
||
"19 훈련 전체 손실: 20956.738 \t재구성 손실: 17900.092 \t잠재 손실: 3056.6475\n",
|
||
"20 훈련 전체 손실: 20429.688 \t재구성 손실: 16620.959 \t잠재 손실: 3808.7285\n",
|
||
"21 훈련 전체 손실: 17099.916 \t재구성 손실: 13952.262 \t잠재 손실: 3147.6538\n",
|
||
"22 훈련 전체 손실: 16274.533 \t재구성 손실: 12991.28 \t잠재 손실: 3283.2524\n",
|
||
"23 훈련 전체 손실: 16308.104 \t재구성 손실: 12951.634 \t잠재 손실: 3356.4697\n",
|
||
"24 훈련 전체 손실: 15702.99 \t재구성 손실: 12309.805 \t잠재 손실: 3393.1858\n",
|
||
"25 훈련 전체 손실: 15554.395 \t재구성 손실: 12204.829 \t잠재 손실: 3349.565\n",
|
||
"26 훈련 전체 손실: 16080.304 \t재구성 손실: 12602.002 \t잠재 손실: 3478.3018\n",
|
||
"27 훈련 전체 손실: 16153.012 \t재구성 손실: 12719.799 \t잠재 손실: 3433.213\n",
|
||
"28 훈련 전체 손실: 16836.662 \t재구성 손실: 13554.496 \t잠재 손실: 3282.1663\n",
|
||
"29 훈련 전체 손실: 16081.364 \t재구성 손실: 12673.35 \t잠재 손실: 3408.0144\n",
|
||
"30 훈련 전체 손실: 18377.371 \t재구성 손실: 14856.055 \t잠재 손실: 3521.316\n",
|
||
"31 훈련 전체 손실: 15566.567 \t재구성 손실: 12113.064 \t잠재 손실: 3453.503\n",
|
||
"32 훈련 전체 손실: 15363.791 \t재구성 손실: 11939.522 \t잠재 손실: 3424.268\n",
|
||
"33 훈련 전체 손실: 15380.105 \t재구성 손실: 11933.108 \t잠재 손실: 3446.9973\n",
|
||
"34 훈련 전체 손실: 15197.85 \t재구성 손실: 11855.855 \t잠재 손실: 3341.9941\n",
|
||
"35 훈련 전체 손실: 15376.002 \t재구성 손실: 11782.05 \t잠재 손실: 3593.952\n",
|
||
"36 훈련 전체 손실: 15606.907 \t재구성 손실: 12056.068 \t잠재 손실: 3550.839\n",
|
||
"37 훈련 전체 손실: 18351.05 \t재구성 손실: 14509.541 \t잠재 손실: 3841.5088\n",
|
||
"38 훈련 전체 손실: 16268.131 \t재구성 손실: 12896.816 \t잠재 손실: 3371.3145\n",
|
||
"39 훈련 전체 손실: 17762.117 \t재구성 손실: 14202.475 \t잠재 손실: 3559.6433\n",
|
||
"40 훈련 전체 손실: 23485.436 \t재구성 손실: 19128.334 \t잠재 손실: 4357.101\n",
|
||
"41 훈련 전체 손실: 36509.016 \t재구성 손실: 26140.258 \t잠재 손실: 10368.758\n",
|
||
"42 훈련 전체 손실: 25619.293 \t재구성 손실: 20840.367 \t잠재 손실: 4778.926\n",
|
||
"43 훈련 전체 손실: 28378.17 \t재구성 손실: 22257.338 \t잠재 손실: 6120.8325\n",
|
||
"44 훈련 전체 손실: 20361.963 \t재구성 손실: 16991.43 \t잠재 손실: 3370.5337\n",
|
||
"45 훈련 전체 손실: 18422.102 \t재구성 손실: 14912.807 \t잠재 손실: 3509.295\n",
|
||
"46 훈련 전체 손실: 16764.645 \t재구성 손실: 13529.869 \t잠재 손실: 3234.7764\n",
|
||
"47 훈련 전체 손실: 15870.282 \t재구성 손실: 12479.645 \t잠재 손실: 3390.6377\n",
|
||
"48 훈련 전체 손실: 15523.098 \t재구성 손실: 12218.592 \t잠재 손실: 3304.506\n",
|
||
"49 훈련 전체 손실: 15175.317 \t재구성 손실: 11773.2705 \t잠재 손실: 3402.0469\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"n_epochs = 50\n",
|
||
"batch_size = 150\n",
|
||
"\n",
|
||
"with tf.Session() as sess:\n",
|
||
" init.run()\n",
|
||
" for epoch in range(n_epochs):\n",
|
||
" n_batches = len(X_train) // batch_size\n",
|
||
" for iteration in range(n_batches):\n",
|
||
" print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\")\n",
|
||
" sys.stdout.flush()\n",
|
||
" X_batch, y_batch = shuffle_batch(X_train, y_train, batch_size):\n",
|
||
" sess.run(training_op, feed_dict={X: X_batch})\n",
|
||
" loss_val, reconstruction_loss_val, latent_loss_val = sess.run([loss, reconstruction_loss, latent_loss], feed_dict={X: X_batch})\n",
|
||
" print(\"\\r{}\".format(epoch), \"훈련 전체 손실:\", loss_val, \"\\t재구성 손실:\", reconstruction_loss_val, \"\\t잠재 손실:\", latent_loss_val)\n",
|
||
" saver.save(sess, \"./my_model_variational.ckpt\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 55,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"reset_graph()\n",
|
||
"\n",
|
||
"from functools import partial\n",
|
||
"\n",
|
||
"n_inputs = 28 * 28\n",
|
||
"n_hidden1 = 500\n",
|
||
"n_hidden2 = 500\n",
|
||
"n_hidden3 = 20 # 코딩 유닛\n",
|
||
"n_hidden4 = n_hidden2\n",
|
||
"n_hidden5 = n_hidden1\n",
|
||
"n_outputs = n_inputs\n",
|
||
"learning_rate = 0.001\n",
|
||
"\n",
|
||
"initializer = tf.contrib.layers.variance_scaling_initializer()\n",
|
||
"my_dense_layer = partial(\n",
|
||
" tf.layers.dense,\n",
|
||
" activation=tf.nn.elu,\n",
|
||
" kernel_initializer=initializer)\n",
|
||
"\n",
|
||
"X = tf.placeholder(tf.float32, [None, n_inputs])\n",
|
||
"hidden1 = my_dense_layer(X, n_hidden1)\n",
|
||
"hidden2 = my_dense_layer(hidden1, n_hidden2)\n",
|
||
"hidden3_mean = my_dense_layer(hidden2, n_hidden3, activation=None)\n",
|
||
"hidden3_gamma = my_dense_layer(hidden2, n_hidden3, activation=None)\n",
|
||
"noise = tf.random_normal(tf.shape(hidden3_gamma), dtype=tf.float32)\n",
|
||
"hidden3 = hidden3_mean + tf.exp(0.5 * hidden3_gamma) * noise\n",
|
||
"hidden4 = my_dense_layer(hidden3, n_hidden4)\n",
|
||
"hidden5 = my_dense_layer(hidden4, n_hidden5)\n",
|
||
"logits = my_dense_layer(hidden5, n_outputs, activation=None)\n",
|
||
"outputs = tf.sigmoid(logits)\n",
|
||
"\n",
|
||
"xentropy = tf.nn.sigmoid_cross_entropy_with_logits(labels=X, logits=logits)\n",
|
||
"reconstruction_loss = tf.reduce_sum(xentropy)\n",
|
||
"latent_loss = 0.5 * tf.reduce_sum(\n",
|
||
" tf.exp(hidden3_gamma) + tf.square(hidden3_mean) - 1 - hidden3_gamma)\n",
|
||
"loss = reconstruction_loss + latent_loss\n",
|
||
"\n",
|
||
"optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)\n",
|
||
"training_op = optimizer.minimize(loss)\n",
|
||
"\n",
|
||
"init = tf.global_variables_initializer()\n",
|
||
"saver = tf.train.Saver()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 숫자 이미지 생성"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"모델을 훈련시켜 랜덤한 이미지를 생성해 보겠습니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 56,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"0 훈련 전체 손실: 17792.723 \t재구성 손실: 14123.082 \t잠재 손실: 3669.6401\n",
|
||
"1 훈련 전체 손실: 17332.346 \t재구성 손실: 13560.099 \t잠재 손실: 3772.2463\n",
|
||
"2 훈련 전체 손실: 16350.873 \t재구성 손실: 12579.393 \t잠재 손실: 3771.4807\n",
|
||
"3 훈련 전체 손실: 16581.45 \t재구성 손실: 12810.662 \t잠재 손실: 3770.7861\n",
|
||
"4 훈련 전체 손실: 16224.016 \t재구성 손실: 12450.172 \t잠재 손실: 3773.8433\n",
|
||
"5 훈련 전체 손실: 15628.262 \t재구성 손실: 11819.755 \t잠재 손실: 3808.5068\n",
|
||
"6 훈련 전체 손실: 16081.008 \t재구성 손실: 12179.777 \t잠재 손실: 3901.231\n",
|
||
"7 훈련 전체 손실: 15772.933 \t재구성 손실: 12021.411 \t잠재 손실: 3751.5212\n",
|
||
"8 훈련 전체 손실: 16276.584 \t재구성 손실: 12404.785 \t잠재 손실: 3871.7988\n",
|
||
"9 훈련 전체 손실: 15589.723 \t재구성 손실: 11740.717 \t잠재 손실: 3849.0063\n",
|
||
"10 훈련 전체 손실: 15931.363 \t재구성 손실: 12031.385 \t잠재 손실: 3899.9783\n",
|
||
"11 훈련 전체 손실: 16112.865 \t재구성 손실: 12238.496 \t잠재 손실: 3874.369\n",
|
||
"12 훈련 전체 손실: 16002.043 \t재구성 손실: 12185.183 \t잠재 손실: 3816.8608\n",
|
||
"13 훈련 전체 손실: 15357.919 \t재구성 손실: 11667.58 \t잠재 손실: 3690.3389\n",
|
||
"14 훈련 전체 손실: 16208.517 \t재구성 손실: 12264.615 \t잠재 손실: 3943.9011\n",
|
||
"15 훈련 전체 손실: 15970.236 \t재구성 손실: 12158.714 \t잠재 손실: 3811.522\n",
|
||
"16 훈련 전체 손실: 15551.721 \t재구성 손실: 11783.23 \t잠재 손실: 3768.4897\n",
|
||
"17 훈련 전체 손실: 15330.088 \t재구성 손실: 11555.771 \t잠재 손실: 3774.3167\n",
|
||
"18 훈련 전체 손실: 15251.499 \t재구성 손실: 11584.66 \t잠재 손실: 3666.8386\n",
|
||
"19 훈련 전체 손실: 15196.1455 \t재구성 손실: 11516.703 \t잠재 손실: 3679.4424\n",
|
||
"20 훈련 전체 손실: 15324.054 \t재구성 손실: 11526.015 \t잠재 손실: 3798.0388\n",
|
||
"21 훈련 전체 손실: 15358.613 \t재구성 손실: 11515.41 \t잠재 손실: 3843.2036\n",
|
||
"22 훈련 전체 손실: 15298.06 \t재구성 손실: 11582.691 \t잠재 손실: 3715.3684\n",
|
||
"23 훈련 전체 손실: 14673.169 \t재구성 손실: 10940.84 \t잠재 손실: 3732.329\n",
|
||
"24 훈련 전체 손실: 15293.574 \t재구성 손실: 11561.805 \t잠재 손실: 3731.7695\n",
|
||
"25 훈련 전체 손실: 15256.209 \t재구성 손실: 11540.664 \t잠재 손실: 3715.545\n",
|
||
"26 훈련 전체 손실: 15305.479 \t재구성 손실: 11475.454 \t잠재 손실: 3830.025\n",
|
||
"27 훈련 전체 손실: 15276.918 \t재구성 손실: 11449.658 \t잠재 손실: 3827.2593\n",
|
||
"28 훈련 전체 손실: 14980.705 \t재구성 손실: 11318.064 \t잠재 손실: 3662.6406\n",
|
||
"29 훈련 전체 손실: 15232.898 \t재구성 손실: 11520.201 \t잠재 손실: 3712.6968\n",
|
||
"30 훈련 전체 손실: 14872.446 \t재구성 손실: 11173.004 \t잠재 손실: 3699.4421\n",
|
||
"31 훈련 전체 손실: 14890.485 \t재구성 손실: 11144.245 \t잠재 손실: 3746.2402\n",
|
||
"32 훈련 전체 손실: 15246.843 \t재구성 손실: 11439.51 \t잠재 손실: 3807.333\n",
|
||
"33 훈련 전체 손실: 15063.674 \t재구성 손실: 11282.296 \t잠재 손실: 3781.3784\n",
|
||
"34 훈련 전체 손실: 15046.693 \t재구성 손실: 11310.135 \t잠재 손실: 3736.5586\n",
|
||
"35 훈련 전체 손실: 15293.908 \t재구성 손실: 11599.437 \t잠재 손실: 3694.4717\n",
|
||
"36 훈련 전체 손실: 15134.561 \t재구성 손실: 11362.827 \t잠재 손실: 3771.734\n",
|
||
"37 훈련 전체 손실: 14705.802 \t재구성 손실: 11054.809 \t잠재 손실: 3650.993\n",
|
||
"38 훈련 전체 손실: 14914.01 \t재구성 손실: 11077.051 \t잠재 손실: 3836.9585\n",
|
||
"39 훈련 전체 손실: 14848.272 \t재구성 손실: 11198.791 \t잠재 손실: 3649.4814\n",
|
||
"40 훈련 전체 손실: 14694.52 \t재구성 손실: 10991.713 \t잠재 손실: 3702.807\n",
|
||
"41 훈련 전체 손실: 15223.752 \t재구성 손실: 11464.886 \t잠재 손실: 3758.8667\n",
|
||
"42 훈련 전체 손실: 14585.404 \t재구성 손실: 11019.355 \t잠재 손실: 3566.0483\n",
|
||
"43 훈련 전체 손실: 14579.119 \t재구성 손실: 10931.234 \t잠재 손실: 3647.8848\n",
|
||
"44 훈련 전체 손실: 15049.283 \t재구성 손실: 11381.96 \t잠재 손실: 3667.3232\n",
|
||
"45 훈련 전체 손실: 14855.669 \t재구성 손실: 11125.52 \t잠재 손실: 3730.1494\n",
|
||
"46 훈련 전체 손실: 14777.61 \t재구성 손실: 11093.045 \t잠재 손실: 3684.5652\n",
|
||
"47 훈련 전체 손실: 14408.994 \t재구성 손실: 10788.754 \t잠재 손실: 3620.24\n",
|
||
"48 훈련 전체 손실: 14479.196 \t재구성 손실: 10864.229 \t잠재 손실: 3614.9678\n",
|
||
"49 훈련 전체 손실: 14638.092 \t재구성 손실: 10926.594 \t잠재 손실: 3711.4983\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"import numpy as np\n",
|
||
"\n",
|
||
"n_digits = 60\n",
|
||
"n_epochs = 50\n",
|
||
"batch_size = 150\n",
|
||
"\n",
|
||
"with tf.Session() as sess:\n",
|
||
" init.run()\n",
|
||
" for epoch in range(n_epochs):\n",
|
||
" n_batches = len(X_train) // batch_size\n",
|
||
" for iteration in range(n_batches):\n",
|
||
" print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\") # not shown in the book\n",
|
||
" sys.stdout.flush() # not shown\n",
|
||
" X_batch, y_batch = shuffle_batch(X_train, y_train, batch_size):\n",
|
||
" sess.run(training_op, feed_dict={X: X_batch})\n",
|
||
" loss_val, reconstruction_loss_val, latent_loss_val = sess.run([loss, reconstruction_loss, latent_loss], feed_dict={X: X_batch}) # not shown\n",
|
||
" print(\"\\r{}\".format(epoch), \"훈련 전체 손실:\", loss_val, \"\\t재구성 손실:\", reconstruction_loss_val, \"\\t잠재 손실:\", latent_loss_val) # not shown\n",
|
||
" saver.save(sess, \"./my_model_variational.ckpt\") # not shown\n",
|
||
" \n",
|
||
" codings_rnd = np.random.normal(size=[n_digits, n_hidden3])\n",
|
||
" outputs_val = outputs.eval(feed_dict={hidden3: codings_rnd})"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 57,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"image/png": "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\n",
|
||
"text/plain": [
|
||
"<Figure size 576x3600 with 60 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"plt.figure(figsize=(8,50)) # 책에는 없음\n",
|
||
"for iteration in range(n_digits):\n",
|
||
" plt.subplot(n_digits, 10, iteration + 1)\n",
|
||
" plot_image(outputs_val[iteration])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 58,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"image/png": "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\n",
|
||
"text/plain": [
|
||
"<Figure size 432x288 with 1 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"n_rows = 6\n",
|
||
"n_cols = 10\n",
|
||
"plot_multiple_images(outputs_val.reshape(-1, 28, 28), n_rows, n_cols)\n",
|
||
"save_fig(\"generated_digits_plot\")\n",
|
||
"plt.show()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"여기에서 잠재 변수 손실은 조금 다르게 계산된 점을 주목하세요:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 59,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"latent_loss = 0.5 * tf.reduce_sum(\n",
|
||
" tf.exp(hidden3_gamma) + tf.square(hidden3_mean) - 1 - hidden3_gamma)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 인코드 & 디코드"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"인코드:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 60,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"INFO:tensorflow:Restoring parameters from ./my_model_variational.ckpt\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"n_digits = 3\n",
|
||
"# X_test, y_test = mnist.test.next_batch(batch_size)\n",
|
||
"X_test_batch, y_test_batch = shuffle_batch(X_test, y_test, batch_size):\n",
|
||
"codings = hidden3\n",
|
||
"\n",
|
||
"with tf.Session() as sess:\n",
|
||
" saver.restore(sess, \"./my_model_variational.ckpt\")\n",
|
||
" codings_val = codings.eval(feed_dict={X: X_test_batch})"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"디코드:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 61,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"INFO:tensorflow:Restoring parameters from ./my_model_variational.ckpt\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"with tf.Session() as sess:\n",
|
||
" saver.restore(sess, \"./my_model_variational.ckpt\")\n",
|
||
" outputs_val = outputs.eval(feed_dict={codings: codings_val})"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"재구성 이미지를 그려봅니다:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 62,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAZIAAAG8CAYAAAD0JCO8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAGWBJREFUeJzt3XvsV3X9B/ADXxAB6SteklJz5gzUJKfOu66J2iwyRTejQltmKWrTvDRpTstFTp2bK1grbdPmXVhl6rKRtdTwMleZgVZmouEFQUFA+HL5/fVrvN7n0/f2+n6+t8/j8d/zs885n4Nyvk/O5/V9nzNi69atFQD01siBPgAAhjZFAkCKIgEgRZEAkKJIAEhRJACkKBIAUhQJACmKBICUUQPwmZbSD28jBvoA6FfO5+GtW+ezKxIAUhQJACmKBIAURQJAiiIBIEWRAJCiSABIUSQApCgSAFIUCQApigSAFEUCQIoiASBFkQCQokgASFEkAKQMxIOtAIaFrVvrz/XasGFDyMuWLQv5+eefD3mnnXaq7WOvvfYKecKECSG3t7fXtmlra+v8YJvIFQkAKYoEgBRFAkCKGUk/W79+fe21lStXhlx+p3rccceFfOaZZ9b2cfbZZ4d8wgkn9PYQgf+hnH+88sortffce++9IS9ZsiTk1157LeR33323to+JEyeG/JnPfCbkr3/967Vtxo0bF/KIESNq72kWVyQApCgSAFIUCQApigSAlBGNFtQ0Wb9/4EBat25dyN/5zndq77nhhhvSnzNqVPy9iauuuqrT3ET9N+FjMBg253Ojn4XvvfdeyBdeeGHICxcurG2zefPmkD/0oQ+FvPvuu3f6/qqqquXLl4c8derUkK+55praNuV7Ro7sk+uEbp3PrkgASFEkAKQoEgBSLEjsgS1btoT8j3/8o/aek046KeQ333wz5O233762zc9+9rOQy+82TzvttJAbLWD67ne/G/Jtt90W8gUXXFDbptHN4qBVlDORFStW1N7z+c9/PuTHHnss5EZziH333TfkSy+9NOQjjzwy5HKOWlVVdfPNN4fc0dERcqO5ygDMu//LFQkAKYoEgBRFAkCKdSQ98Mc//jHko48+usf7OOOMM2qv3XPPPSH35mZr5XemM2bMCPmoo46qbfOtb32rx5/TDdaRtJYhez6/8847IZfnTFVV1TPPPBPyLrvsEnK5rqSqqurLX/5yyOVDqMq5Sjl7raqqevzxx0P+wQ9+EPJFF11U26acvZRry3p5E0frSABoPkUCQIoiASBFkQCQYkFiJ8oFSuVTyrqjHIrNnDkzdUz/S1tbW8i77bZbyOUvCkCr2bhxY8jlU0UXL15c22bXXXcN+a677gr54IMPrm3T0yF3o0WNkyZNCrl8smp5M8mqajy07y+uSABIUSQApCgSAFLMSLaxadOmkO+///6QV61aFXKj7z7LxUjlzdea5f333w/517/+dcgrV67sl+OAwaJcbH3nnXeG/OCDD4Y8bty42j5uuummkMuZSDkPqaqeL/xrtCh89erVIb/00kshL126tLbNtGnTUseR4YoEgBRFAkCKIgEgxYxkG3fccUfI559/fsjd+c7x6quv7tNj6q6f//znIS9fvjzkRjekg+GsnGledtllIZc3Om20Tqx8rY9uhBg0mpGUD82bMGFCyDvssENtm0brUfqLKxIAUhQJACmKBIAUM5JtrFmzJuSuvv9sdJ+d8h5X/aV8SM9pp50W8t13392fhwP9qtF9pq699tqQy7VUEydODPn666+v7WPMmDEhN2Mm0tHRUXvPo48+GnJ5n7BDDjmktk15v73+5IoEgBRFAkCKIgEgRZEAkGLY3olyKFYuTioXMFZVVW2//fZNPaaqaryA6ZZbbgl5n332afpxwGDx7rvv1l574IEHQh4/fnzI11xzTcgf/vCHa/toxnC9zG+99VZtm7/85S8h77HHHiHvueeetW0sSARgyFIkAKQoEgBSzEi28frrr4dcLli68cYbQ25vb2/6MTVy3XXX1V579tlnQz7qqKP663BgwD322GO11957772Qjz766JC/8pWvhNydGUM53+jNDKW8WeQ999xTe09509UDDjgg5J133rnHn9tMrkgASFEkAKQoEgBSzEi2Ua7FKNeNTJkypT8P57/Kh1bdcMMNXW7zxS9+sVmHAwNu06ZNId90002195QPobrwwgtDHjduXMjdmXf0ZiZSzlXeeOONkG+//fbaNuUNZM8555yQB/IGjY24IgEgRZEAkKJIAEhRJACktOywfenSpbXXygHXQHn++edDnjlzZsjlU9uqqqr++te/hrzffvv1/YHBILFq1aqQG53P5dNKy0W6zbrJYTlcL4/1rLPOCvm1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\n",
|
||
"text/plain": [
|
||
"<Figure size 576x540 with 6 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"fig = plt.figure(figsize=(8, 2.5 * n_digits))\n",
|
||
"for iteration in range(n_digits):\n",
|
||
" plt.subplot(n_digits, 2, 1 + 2 * iteration)\n",
|
||
" plot_image(X_test_batch[iteration])\n",
|
||
" plt.subplot(n_digits, 2, 2 + 2 * iteration)\n",
|
||
" plot_image(outputs_val[iteration])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 숫자 이미지 보간"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 63,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"INFO:tensorflow:Restoring parameters from ./my_model_variational.ckpt\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"image/png": "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\n",
|
||
"text/plain": [
|
||
"<Figure size 792x324 with 6 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
},
|
||
{
|
||
"data": {
|
||
"image/png": "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McNyRUWFZd3UW0ujOivXOb/Epo+Wtbypj6y7dOliWRcevv32273j6iPr2rVrW863koEuMuucP7NMy9ALFy60rOdcz7MukK3t7Zy/kbvOktahAFWZIZhv57+mxUrH4aLop+nMaqXvA2SWXnt6v8q3ITS5IGlmtA7hKCkpsaz3PZw7Pa8PPfSQ5e3bt1suKyvzXvPxxx9b1k0e6tWrZ1k/G/Xz74033rAcrgby0ksvWU4aLpVpPGEEAABAFB1GAAAARGVlSTqcbaSPenX20J133mlZF5/VBbZ1f0adMe2cc23btrWsZWQto+kjf/07dKHncBZT0mypfBOWpPW8rV27ttKvK30kP3DgQMsPP/yw93M6u1nLZHreC+WcZ5KWK8NhA3rN6R64OnNeh43osZiVXvP0POuqBHpN79y507Jew1xr6aPnOZxFe1qTJk0sJy30HeK6qpyeF93k49VXX7Wsm00459y0adMsJw230s8p7XfotTZ8+HDvuDr0Kls39uDKBwAAQBQdRgAAAETlREla6cxazVoi1hnMscf0KumRvb6ex/q+cGbs/v37LXfr1s2ylvW1nDJo0CDL48aNs6yLeDvHrOdsoWWSsWPHet/TxW21BKNtP3LkSMt6vdKOmaUbGui1p9d3Ve+jqB4dwqGbVOi+3h07drRMSTp1tN+hi2jryizOObdixQrLuhGFDovTxdV1g5CuXbta1o0nnPNXaslWPGEEAABAFB1GAAAARGVlSTqVqvsonkf5ycKFRwcPHmy5f//+lrVUojOb9dxynrOflmzCcsro0aMt6wx53ftbVzXI5wXtc01xcbHl0tJSy9p22bSfbT7Te2WdOnUs6/ArXZGge/fulpNWHsC503tSuID9LbfcYvnmm2+2HK4aUtmxYp95uXAf5F0FAACAKDqMAAAAiKLDCAAAgKhaGVgugfUZ0itVAyFop/RKRTvRRulFG2W/vGojXcroyy+/tLxs2TLLJSUlljt16mRZl7AKx8NleExjXrVRnqpSG/GEEQAAAFF0GAEAABBFSTr/UJLODZRpsh9tlP1oo+xHG2U/StIAAACoPjqMAAAAiKLDCAAAgCg6jAAAAIiiwwgAAICoTMySBgAAQA7hCSMAAACi6DACAAAgig4jAAAAougwAgAAIIoOIwAAAKLoMAIAACCKDiMAAACi6DACAAAgig4jAAAAougwAgAAIIoOIwAAAKLoMAIAACCKDiMAAACi6DACAAAgig4jAAAAougwAgAAIIoOIwAAAKLoMAIAACCKDiMAAACi6DACAAAgig4jAAAAougwAgAAIIoOIwAAAKLoMAIAACCKDiMAAACi/gfC/ZQoF8dwtAAAAABJRU5ErkJggg==\n",
|
||
"text/plain": [
|
||
"<Figure size 792x324 with 6 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
},
|
||
{
|
||
"data": {
|
||
"image/png": "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\n",
|
||
"text/plain": [
|
||
"<Figure size 792x324 with 6 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
},
|
||
{
|
||
"data": {
|
||
"image/png": "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\n",
|
||
"text/plain": [
|
||
"<Figure size 792x324 with 6 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"n_iterations = 3\n",
|
||
"n_digits = 6\n",
|
||
"codings_rnd = np.random.normal(size=[n_digits, n_hidden3])\n",
|
||
"\n",
|
||
"with tf.Session() as sess:\n",
|
||
" saver.restore(sess, \"./my_model_variational.ckpt\")\n",
|
||
" target_codings = np.roll(codings_rnd, -1, axis=0)\n",
|
||
" for iteration in range(n_iterations + 1):\n",
|
||
" codings_interpolate = codings_rnd + (target_codings - codings_rnd) * iteration / n_iterations\n",
|
||
" outputs_val = outputs.eval(feed_dict={codings: codings_interpolate})\n",
|
||
" plt.figure(figsize=(11, 1.5*n_iterations))\n",
|
||
" for digit_index in range(n_digits):\n",
|
||
" plt.subplot(1, n_digits, digit_index + 1)\n",
|
||
" plot_image(outputs_val[digit_index])\n",
|
||
" plt.show()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"source": [
|
||
"# 연습문제 해답"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Coming soon..."
|
||
]
|
||
}
|
||
],
|
||
"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.5"
|
||
},
|
||
"nav_menu": {
|
||
"height": "381px",
|
||
"width": "453px"
|
||
},
|
||
"toc": {
|
||
"navigate_menu": true,
|
||
"number_sections": true,
|
||
"sideBar": true,
|
||
"threshold": 6,
|
||
"toc_cell": false,
|
||
"toc_section_display": "block",
|
||
"toc_window_display": false
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 1
|
||
}
|