{ "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.2\n", "sklearn 0.19.1\n", "scipy 1.0.1\n", "matplotlib 2.2.2\n", "tensorflow 1.7.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": [ "
" ] }, "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": "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": [ "tf.logging.set_verbosity(tf.logging.ERROR) # deprecated 경고 메세지를 출력하지 않기 위해 \n", "from tensorflow.examples.tutorials.mnist import input_data\n", "mnist = input_data.read_data_sets(\"/tmp/data/\")\n", "tf.logging.set_verbosity(tf.logging.INFO)" ] }, { "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.022107124\n", "1 훈련 MSE: 0.012154639\n", "2 훈련 MSE: 0.010653543\n", "3 훈련 MSE: 0.010217447\n", "4 훈련 MSE: 0.010719749\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 = mnist.train.num_examples // 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 = mnist.train.next_batch(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", "\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": true }, "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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SP+Xv/ylWm89eB6OJ1EXbKs7NurCjTp9W5sYvPXWW9X6zJnxz/DatWur9SuuuKJaf//73x+utXDhwmo96vL+3e9+F64VfS579+6t1lsbaOzfv79anzatvrdCa63o8++lY3727Nmdrutorx2NO2MASCaMASCZMAaAZMIYAJIJYwBIppv6KFrdxFEXZtQxXUopDz74YLU+d+7cbhfWcOedd1brf/vb3zqv9bnPfW6cVwNTQ/QM5ugZxKXE3bFRB26ra/fUU0+t1lvPn//oRz9ara9atapanzdvXrjWnj17qvXoGdTPPPNMuNbY2Fi1Hv32tZ5NfejQoWo9+r727dsXrhV9/q2plKg7O/ruoymW1jHvhjtjAEgmjAEgmTAGgGTCGACSCWMASCaMASCZ0aaj+MAHPhC+Fo09tVrfBwYGxn1NRxNtYBGNEMCJpOsIU2ujiGizgGjThdb//Wit/v7+8JiVK1dW69HvSGvsJxpVuvfee6v1zZs3h2t98pOfrNbPOuusan3JkiXhWtHnEm0gEf37UnobX+tqPONLLe6MASCZMAaAZMIYAJIJYwBIJowBIJlu6nEYGhpKPf9dd91VrW/atKnzWmvXrq3WzznnnM5rwVQUdcG2unOjruVoo4Q5c+aEa7U2cegq6ppubWzzxBNPVOvPPvtstb58+fJwrUsvvbRaP++886r1mTPjqBkdHa3Wo00fWptxROdpdblH3fTRZiDHijtjAEgmjAEgmTAGgGTCGACSCWMASCaMASCZ0aYp7qmnngpf+/rXv16tR6MCp59+erjWunXrqvVZs2Y1rg5yTOTD+lubCETniY5prRWNULVGaKIxngMHDlTrO3bsCNd67rnnqvXomt/73veGa3UdeXzppZfC16LPOBora/0mRe+llzGl6LpaG4uM5+/SnTEAJBPGAJBMGANAMmEMAMmEMQAk0009xT322GPha1HXdOTGG28MX2t1TsJU0+po7XpMLxsP9NKdG52/tYlCZPv27dX6hg0bwmPuv//+an1wcLBajzaDKKWU1atXV+vR53Lw4MFwrQULFlTr0aYb0SYdpZQyfXr9/rL19xJtIhH9XfTyt/duuDMGgGTCGACSCWMASCaMASCZMAaAZLqpp4gbbrihWv/973/fea1vfetb1fp3vvOdzmvBiSLqwm11M0cTC9EziFud2dGzllvHDA8P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\n", "text/plain": [ "
" ] }, "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 = mnist.train.num_examples // 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 = mnist.train.next_batch(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_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": [ "
" ] }, "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.018564083\n", "1 훈련 MSE: 0.018759882\n", "2 훈련 MSE: 0.018457456\n", "3 훈련 MSE: 0.019239973\n", "0 훈련 MSE: 0.0042280294\n", "1 훈련 MSE: 0.004805386\n", "2 훈련 MSE: 0.004675172\n", "3 훈련 MSE: 0.004376106\n" ] } ], "source": [ "hidden_output, W1, b1, W4, b4 = train_autoencoder(mnist.train.images, 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": [ "
" ] }, "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", "0 훈련 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 = mnist.train.num_examples // 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 = mnist.train.next_batch(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: mnist.test.images})\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: mnist.train.images})\n", " for epoch in range(n_epochs[phase]):\n", " n_batches = mnist.train.num_examples // 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(mnist.train.num_examples)\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 = mnist.train.next_batch(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: mnist.test.images})\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": "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\n", "text/plain": [ "
" ] }, "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", "\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": [ "
" ] }, "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 = mnist.train.images[indices], mnist.train.labels[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", " accuracy_val = accuracy.eval(feed_dict={X: mnist.test.images, y: mnist.test.labels})\n", " print(\"테스트 정확도:\", accuracy_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 = mnist.train.images[indices], mnist.train.labels[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", " accuracy_val = accuracy.eval(feed_dict={X: mnist.test.images, y: mnist.test.labels})\n", " print(\"테스트 정확도:\", accuracy_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.046190277\n", "1 훈련 MSE: 0.044343986\n", "2 훈련 MSE: 0.04200526\n", "3 훈련 MSE: 0.040973965\n", "4 훈련 MSE: 0.040393338\n", "5 훈련 MSE: 0.038924493\n", "6 훈련 MSE: 0.0394448\n", "7 훈련 MSE: 0.042411502\n", "8 훈련 MSE: 0.039848443\n", "9 훈련 MSE: 0.04152445\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 = mnist.train.num_examples // 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 = mnist.train.next_batch(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.027500158\n", "1 훈련 MSE: 0.02639269\n", "2 훈련 MSE: 0.022876455\n", "3 훈련 MSE: 0.0229337\n", "4 훈련 MSE: 0.022025634\n", "5 훈련 MSE: 0.021996608\n", "6 훈련 MSE: 0.021385597\n", "7 훈련 MSE: 0.021463407\n", "8 훈련 MSE: 0.021037336\n", "9 훈련 MSE: 0.02082274\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 = mnist.train.num_examples // 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 = mnist.train.next_batch(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": "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\n", "text/plain": [ "
" ] }, "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": [ "
" ] }, "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.41844434 \t전체 손실: 0.22188361\n", "1 훈련 MSE: 0.059185907 \t희소 손실: 0.010747161 \t전체 손실: 0.06133534\n", "2 훈련 MSE: 0.053931113 \t희소 손실: 0.019957827 \t전체 손실: 0.05792268\n", "3 훈련 MSE: 0.04771372 \t희소 손실: 0.039470375 \t전체 손실: 0.055607796\n", "4 훈련 MSE: 0.044841796 \t희소 손실: 0.011593379 \t전체 손실: 0.047160473\n", "5 훈련 MSE: 0.04044193 \t희소 손실: 0.09246979 \t전체 손실: 0.058935888\n", "6 훈련 MSE: 0.03886659 \t희소 손실: 0.045811094 \t전체 손실: 0.04802881\n", "7 훈련 MSE: 0.037868652 \t희소 손실: 0.07498116 \t전체 손실: 0.052864887\n", "8 훈련 MSE: 0.033122517 \t희소 손실: 0.020321798 \t전체 손실: 0.037186876\n", "9 훈련 MSE: 0.031449173 \t희소 손실: 0.095670365 \t전체 손실: 0.050583243\n", "10 훈련 MSE: 0.027398113 \t희소 손실: 0.065706335 \t전체 손실: 0.04053938\n", "11 훈련 MSE: 0.024734963 \t희소 손실: 0.08889374 \t전체 손실: 0.042513713\n", "12 훈련 MSE: 0.023367295 \t희소 손실: 0.0576614 \t전체 손실: 0.034899574\n", "13 훈련 MSE: 0.023007901 \t희소 손실: 0.061935436 \t전체 손실: 0.03539499\n", "14 훈련 MSE: 0.02123353 \t희소 손실: 0.025881436 \t전체 손실: 0.026409818\n", "15 훈련 MSE: 0.02206469 \t희소 손실: 0.48820436 \t전체 손실: 0.11970556\n", "16 훈련 MSE: 0.01910253 \t희소 손실: 0.032202266 \t전체 손실: 0.025542984\n", "17 훈련 MSE: 0.01898219 \t희소 손실: 0.12995036 \t전체 손실: 0.044972263\n", "18 훈련 MSE: 0.017487913 \t희소 손실: 0.035002217 \t전체 손실: 0.024488356\n", "19 훈련 MSE: 0.017776337 \t희소 손실: 0.11024549 \t전체 손실: 0.039825432\n", "20 훈련 MSE: 0.016910141 \t희소 손실: 0.030320741 \t전체 손실: 0.02297429\n", "21 훈련 MSE: 0.018679725 \t희소 손실: 0.36376768 \t전체 손실: 0.091433264\n", "22 훈련 MSE: 0.016285753 \t희소 손실: 0.055482324 \t전체 손실: 0.027382217\n", "23 훈련 MSE: 0.015950203 \t희소 손실: 0.079365596 \t전체 손실: 0.031823322\n", "24 훈련 MSE: 0.015672017 \t희소 손실: 0.14289412 \t전체 손실: 0.04425084\n", "25 훈련 MSE: 0.014612305 \t희소 손실: 0.13330609 \t전체 손실: 0.041273523\n", "26 훈련 MSE: 0.014524785 \t희소 손실: 0.10948229 \t전체 손실: 0.036421243\n", "27 훈련 MSE: 0.013598451 \t희소 손실: 0.07208246 \t전체 손실: 0.028014943\n", "28 훈련 MSE: 0.014069845 \t희소 손실: 0.15789555 \t전체 손실: 0.045648955\n", "29 훈련 MSE: 0.013441612 \t희소 손실: 0.14449221 \t전체 손실: 0.042340055\n", "30 훈련 MSE: 0.013608929 \t희소 손실: 0.18507166 \t전체 손실: 0.05062326\n", "31 훈련 MSE: 0.014197283 \t희소 손실: 0.06788807 \t전체 손실: 0.027774898\n", "32 훈련 MSE: 0.013759435 \t희소 손실: 0.057576656 \t전체 손실: 0.025274767\n", "33 훈련 MSE: 0.013667367 \t희소 손실: 0.11363616 \t전체 손실: 0.0363946\n", "34 훈련 MSE: 0.0126469685 \t희소 손실: 0.13469556 \t전체 손실: 0.039586082\n", "35 훈련 MSE: 0.012872889 \t희소 손실: 0.16850437 \t전체 손실: 0.046573766\n", "36 훈련 MSE: 0.012669464 \t희소 손실: 0.09313129 \t전체 손실: 0.03129572\n", "37 훈련 MSE: 0.012427666 \t희소 손실: 0.105387196 \t전체 손실: 0.033505104\n", "38 훈련 MSE: 0.01233604 \t희소 손실: 0.19235855 \t전체 손실: 0.05080775\n", "39 훈련 MSE: 0.012337869 \t희소 손실: 0.14231703 \t전체 손실: 0.040801276\n", "40 훈련 MSE: 0.012626693 \t희소 손실: 0.23267308 \t전체 손실: 0.05916131\n", "41 훈련 MSE: 0.012383292 \t희소 손실: 0.104892224 \t전체 손실: 0.033361737\n", "42 훈련 MSE: 0.011781142 \t희소 손실: 0.10161172 \t전체 손실: 0.032103486\n", "43 훈련 MSE: 0.012044032 \t희소 손실: 0.1359405 \t전체 손실: 0.039232135\n", "44 훈련 MSE: 0.011620717 \t희소 손실: 0.11472766 \t전체 손실: 0.03456625\n", "45 훈련 MSE: 0.011669101 \t희소 손실: 0.15798101 \t전체 손실: 0.043265305\n", "46 훈련 MSE: 0.01167006 \t희소 손실: 0.13549636 \t전체 손실: 0.038769335\n", "47 훈련 MSE: 0.011549011 \t희소 손실: 0.15662336 \t전체 손실: 0.042873684\n", "48 훈련 MSE: 0.011729614 \t희소 손실: 0.4430182 \t전체 손실: 0.10033325\n", "49 훈련 MSE: 0.011562036 \t희소 손실: 0.17581894 \t전체 손실: 0.046725824\n", "50 훈련 MSE: 0.01135992 \t희소 손실: 0.18881696 \t전체 손실: 0.049123313\n", "51 훈련 MSE: 0.0115385335 \t희소 손실: 0.26335293 \t전체 손실: 0.06420912\n", "52 훈련 MSE: 0.0120425625 \t희소 손실: 0.3675837 \t전체 손실: 0.0855593\n", "53 훈련 MSE: 0.011238733 \t희소 손실: 0.12488687 \t전체 손실: 0.03621611\n", "54 훈련 MSE: 0.013967819 \t희소 손실: 0.43314826 \t전체 손실: 0.10059747\n", "55 훈련 MSE: 0.012766779 \t희소 손실: 0.07719517 \t전체 손실: 0.028205812\n", "56 훈련 MSE: 0.012239235 \t희소 손실: 0.30152494 \t전체 손실: 0.072544225\n", "57 훈련 MSE: 0.012724373 \t희소 손실: 0.24817757 \t전체 손실: 0.062359888\n", "58 훈련 MSE: 0.023815982 \t희소 손실: 0.2323372 \t전체 손실: 0.07028343\n", "59 훈련 MSE: 0.013152219 \t희소 손실: 0.19813177 \t전체 손실: 0.052778576\n", "60 훈련 MSE: 0.019204749 \t희소 손실: 0.19425029 \t전체 손실: 0.058054805\n", "61 훈련 MSE: 0.01287946 \t희소 손실: 0.22912267 \t전체 손실: 0.058703996\n", "62 훈련 MSE: 0.014201862 \t희소 손실: 0.47936517 \t전체 손실: 0.1100749\n", "63 훈련 MSE: 0.014247858 \t희소 손실: 0.3340563 \t전체 손실: 0.08105911\n", "64 훈련 MSE: 0.01188848 \t희소 손실: 0.17818896 \t전체 손실: 0.04752627\n", "65 훈련 MSE: 0.016912188 \t희소 손실: 0.18625271 \t전체 손실: 0.054162733\n", "66 훈련 MSE: 0.015350101 \t희소 손실: 0.984547 \t전체 손실: 0.21225952\n", "67 훈련 MSE: 0.037533756 \t희소 손실: 0.31189525 \t전체 손실: 0.09991281\n", "68 훈련 MSE: 0.015359703 \t희소 손실: 0.21824294 \t전체 손실: 0.059008293\n", "69 훈련 MSE: 0.0130188465 \t희소 손실: 0.43986538 \t전체 손실: 0.10099193\n", "70 훈련 MSE: 0.04249404 \t희소 손실: 0.7454435 \t전체 손실: 0.19158275\n", "71 훈련 MSE: 0.014368004 \t희소 손실: 0.24009731 \t전체 손실: 0.06238747\n", "72 훈련 MSE: 0.015802076 \t희소 손실: 0.7972901 \t전체 손실: 0.1752601\n", "73 훈련 MSE: 0.014027514 \t희소 손실: 0.31637588 \t전체 손실: 0.077302694\n", "74 훈련 MSE: 0.033579413 \t희소 손실: 0.32424852 \t전체 손실: 0.09842911\n", "75 훈련 MSE: 0.037583392 \t희소 손실: 0.51026374 \t전체 손실: 0.13963614\n", "76 훈련 MSE: 0.018015897 \t희소 손실: 0.19957174 \t전체 손실: 0.057930246\n", "77 훈련 MSE: 0.019651866 \t희소 손실: 0.30766442 \t전체 손실: 0.08118475\n", "78 훈련 MSE: 0.018113064 \t희소 손실: 0.5368116 \t전체 손실: 0.12547539\n", "79 훈련 MSE: 0.019586327 \t희소 손실: 0.4225994 \t전체 손실: 0.10410621\n", "80 훈련 MSE: 0.016286958 \t희소 손실: 0.116765514 \t전체 손실: 0.03964006\n", "81 훈련 MSE: 0.012678387 \t희소 손실: 0.8773603 \t전체 손실: 0.18815045\n", "82 훈련 MSE: 0.015514646 \t희소 손실: 2.136949 \t전체 손실: 0.44290447\n", "83 훈련 MSE: 0.014462668 \t희소 손실: 0.6624632 \t전체 손실: 0.14695531\n", "84 훈련 MSE: 0.0139609 \t희소 손실: 0.2704364 \t전체 손실: 0.06804818\n", "85 훈련 MSE: 0.02716384 \t희소 손실: 0.93438864 \t전체 손실: 0.21404156\n", "86 훈련 MSE: 0.014590265 \t희소 손실: 0.6826812 \t전체 손실: 0.1511265\n", "87 훈련 MSE: 0.012223512 \t희소 손실: 1.41284 \t전체 손실: 0.29479152\n", "88 훈련 MSE: 0.01925102 \t희소 손실: 0.8619595 \t전체 손실: 0.19164293\n", "89 훈련 MSE: 0.029023234 \t희소 손실: 0.2942158 \t전체 손실: 0.087866396\n", "90 훈련 MSE: 0.03109355 \t희소 손실: 0.45987695 \t전체 손실: 0.12306894\n", "91 훈련 MSE: 0.014538759 \t희소 손실: 0.09905543 \t전체 손실: 0.034349844\n", "92 훈련 MSE: 0.015151837 \t희소 손실: 0.38795644 \t전체 손실: 0.09274313\n", "93 훈련 MSE: 0.01682431 \t희소 손실: 0.1613949 \t전체 손실: 0.04910329\n", "94 훈련 MSE: 0.011993256 \t희소 손실: 0.11752173 \t전체 손실: 0.035497602\n", "95 훈련 MSE: 0.0139113525 \t희소 손실: 0.10376862 \t전체 손실: 0.034665078\n", "96 훈련 MSE: 0.018343525 \t희소 손실: 0.23694368 \t전체 손실: 0.06573226\n", "97 훈련 MSE: 0.013478864 \t희소 손실: 0.10932048 \t전체 손실: 0.03534296\n", "98 훈련 MSE: 0.013734443 \t희소 손실: 0.089936554 \t전체 손실: 0.031721756\n", "99 훈련 MSE: 0.0233883 \t희소 손실: 0.33332965 \t전체 손실: 0.09005423\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 = mnist.train.num_examples // 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 = mnist.train.next_batch(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": [ "
" ] }, "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 훈련 전체 손실: 33711.305 \t재구성 손실: 24141.234 \t잠재 손실: 9570.07\n", "1 훈련 전체 손실: 27055.078 \t재구성 손실: 22278.68 \t잠재 손실: 4776.3984\n", "2 훈련 전체 손실: 28769.135 \t재구성 손실: 23155.71 \t잠재 손실: 5613.4233\n", "3 훈련 전체 손실: 26304.252 \t재구성 손실: 21337.469 \t잠재 손실: 4966.783\n", "4 훈련 전체 손실: 31762.32 \t재구성 손실: 24771.611 \t잠재 손실: 6990.71\n", "5 훈련 전체 손실: 25975.902 \t재구성 손실: 21666.244 \t잠재 손실: 4309.659\n", "6 훈련 전체 손실: 21084.105 \t재구성 손실: 17912.25 \t잠재 손실: 3171.8557\n", "7 훈련 전체 손실: 20691.05 \t재구성 손실: 17767.701 \t잠재 손실: 2923.3506\n", "8 훈련 전체 손실: 18301.613 \t재구성 손실: 15335.816 \t잠재 손실: 2965.7979\n", "9 훈련 전체 손실: 18003.305 \t재구성 손실: 14857.625 \t잠재 손실: 3145.6807\n", "10 훈련 전체 손실: 16868.87 \t재구성 손실: 13742.127 \t잠재 손실: 3126.7417\n", "11 훈련 전체 손실: 16322.584 \t재구성 손실: 13176.514 \t잠재 손실: 3146.0708\n", "12 훈련 전체 손실: 16848.775 \t재구성 손실: 13641.574 \t잠재 손실: 3207.201\n", "13 훈련 전체 손실: 16411.53 \t재구성 손실: 13193.485 \t잠재 손실: 3218.0444\n", "14 훈련 전체 손실: 16841.875 \t재구성 손실: 13629.753 \t잠재 손실: 3212.122\n", "15 훈련 전체 손실: 18734.246 \t재구성 손실: 15469.811 \t잠재 손실: 3264.4355\n", "16 훈련 전체 손실: 15549.877 \t재구성 손실: 12475.354 \t잠재 손실: 3074.523\n", "17 훈련 전체 손실: 16549.727 \t재구성 손실: 13114.041 \t잠재 손실: 3435.6865\n", "18 훈련 전체 손실: 16204.832 \t재구성 손실: 12911.634 \t잠재 손실: 3293.198\n", "19 훈련 전체 손실: 19072.146 \t재구성 손실: 15676.701 \t잠재 손실: 3395.4456\n", "20 훈련 전체 손실: 18689.686 \t재구성 손실: 14211.309 \t잠재 손실: 4478.3774\n", "21 훈련 전체 손실: 16398.697 \t재구성 손실: 13045.562 \t잠재 손실: 3353.135\n", "22 훈련 전체 손실: 16106.504 \t재구성 손실: 12735.91 \t잠재 손실: 3370.5942\n", "23 훈련 전체 손실: 20430.426 \t재구성 손실: 15874.012 \t잠재 손실: 4556.413\n", "24 훈련 전체 손실: 15652.191 \t재구성 손실: 12415.114 \t잠재 손실: 3237.077\n", "25 훈련 전체 손실: 15460.601 \t재구성 손실: 12243.658 \t잠재 손실: 3216.9421\n", "26 훈련 전체 손실: 15832.671 \t재구성 손실: 12465.408 \t잠재 손실: 3367.2627\n", "27 훈련 전체 손실: 37082.61 \t재구성 손실: 25035.375 \t잠재 손실: 12047.233\n", "28 훈련 전체 손실: 26629.25 \t재구성 손실: 21904.469 \t잠재 손실: 4724.7803\n", "29 훈련 전체 손실: 23798.465 \t재구성 손실: 19210.568 \t잠재 손실: 4587.8955\n", "30 훈련 전체 손실: 20755.977 \t재구성 손실: 17576.453 \t잠재 손실: 3179.5234\n", "31 훈련 전체 손실: 17813.498 \t재구성 손실: 14805.74 \t잠재 손실: 3007.7578\n", "32 훈련 전체 손실: 17064.127 \t재구성 손실: 13854.3125 \t잠재 손실: 3209.8142\n", "33 훈련 전체 손실: 16516.027 \t재구성 손실: 13270.247 \t잠재 손실: 3245.781\n", "34 훈련 전체 손실: 16060.129 \t재구성 손실: 12752.525 \t잠재 손실: 3307.6035\n", "35 훈련 전체 손실: 16070.643 \t재구성 손실: 12676.658 \t잠재 손실: 3393.9841\n", "36 훈련 전체 손실: 16754.852 \t재구성 손실: 13328.36 \t잠재 손실: 3426.492\n", "37 훈련 전체 손실: 16162.049 \t재구성 손실: 12813.662 \t잠재 손실: 3348.3872\n", "38 훈련 전체 손실: 16215.911 \t재구성 손실: 12828.523 \t잠재 손실: 3387.388\n", "39 훈련 전체 손실: 15912.985 \t재구성 손실: 12628.198 \t잠재 손실: 3284.787\n", "40 훈련 전체 손실: 15275.752 \t재구성 손실: 11982.837 \t잠재 손실: 3292.9146\n", "41 훈련 전체 손실: 16066.625 \t재구성 손실: 12757.855 \t잠재 손실: 3308.7693\n", "42 훈련 전체 손실: 17823.701 \t재구성 손실: 14552.526 \t잠재 손실: 3271.1743\n", "43 훈련 전체 손실: 24408.918 \t재구성 손실: 19846.832 \t잠재 손실: 4562.0864\n", "44 훈련 전체 손실: 24694.812 \t재구성 손실: 19852.523 \t잠재 손실: 4842.288\n", "45 훈련 전체 손실: 30566.844 \t재구성 손실: 22793.793 \t잠재 손실: 7773.05\n", "46 훈련 전체 손실: 24413.105 \t재구성 손실: 19724.02 \t잠재 손실: 4689.086\n", "47 훈련 전체 손실: 23234.568 \t재구성 손실: 18196.725 \t잠재 손실: 5037.8438\n", "48 훈련 전체 손실: 17091.879 \t재구성 손실: 13951.564 \t잠재 손실: 3140.3154\n", "49 훈련 전체 손실: 15979.056 \t재구성 손실: 12713.727 \t잠재 손실: 3265.3289\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 = mnist.train.num_examples // 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 = mnist.train.next_batch(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 훈련 전체 손실: 17845.31 \t재구성 손실: 14199.457 \t잠재 손실: 3645.853\n", "1 훈련 전체 손실: 17223.674 \t재구성 손실: 13457.104 \t잠재 손실: 3766.5708\n", "2 훈련 전체 손실: 16330.138 \t재구성 손실: 12578.04 \t잠재 손실: 3752.098\n", "3 훈련 전체 손실: 16323.255 \t재구성 손실: 12578.617 \t잠재 손실: 3744.638\n", "4 훈련 전체 손실: 16297.912 \t재구성 손실: 12533.176 \t잠재 손실: 3764.7368\n", "5 훈련 전체 손실: 15681.15 \t재구성 손실: 11960.288 \t잠재 손실: 3720.862\n", "6 훈련 전체 손실: 16120.67 \t재구성 손실: 12325.412 \t잠재 손실: 3795.258\n", "7 훈련 전체 손실: 15783.96 \t재구성 손실: 12021.791 \t잠재 손실: 3762.169\n", "8 훈련 전체 손실: 16208.828 \t재구성 손실: 12365.744 \t잠재 손실: 3843.0837\n", "9 훈련 전체 손실: 15524.169 \t재구성 손실: 11801.077 \t잠재 손실: 3723.092\n", "10 훈련 전체 손실: 16092.582 \t재구성 손실: 12279.52 \t잠재 손실: 3813.0625\n", "11 훈련 전체 손실: 16111.75 \t재구성 손실: 12282.848 \t잠재 손실: 3828.9019\n", "12 훈련 전체 손실: 15926.159 \t재구성 손실: 12180.764 \t잠재 손실: 3745.3953\n", "13 훈련 전체 손실: 15271.382 \t재구성 손실: 11631.805 \t잠재 손실: 3639.5774\n", "14 훈련 전체 손실: 16211.1875 \t재구성 손실: 12341.906 \t잠재 손실: 3869.2817\n", "15 훈련 전체 손실: 15781.817 \t재구성 손실: 11920.02 \t잠재 손실: 3861.798\n", "16 훈련 전체 손실: 15513.055 \t재구성 손실: 11780.989 \t잠재 손실: 3732.0657\n", "17 훈련 전체 손실: 15282.611 \t재구성 손실: 11568.492 \t잠재 손실: 3714.1196\n", "18 훈련 전체 손실: 15077.107 \t재구성 손실: 11422.83 \t잠재 손실: 3654.277\n", "19 훈련 전체 손실: 15184.711 \t재구성 손실: 11399.879 \t잠재 손실: 3784.8323\n", "20 훈련 전체 손실: 15317.0625 \t재구성 손실: 11541.074 \t잠재 손실: 3775.988\n", "21 훈련 전체 손실: 15375.975 \t재구성 손실: 11662.023 \t잠재 손실: 3713.9507\n", "22 훈련 전체 손실: 15253.931 \t재구성 손실: 11569.6 \t잠재 손실: 3684.3308\n", "23 훈련 전체 손실: 14920.597 \t재구성 손실: 11226.293 \t잠재 손실: 3694.304\n", "24 훈련 전체 손실: 15152.121 \t재구성 손실: 11461.097 \t잠재 손실: 3691.0242\n", "25 훈련 전체 손실: 15161.9795 \t재구성 손실: 11527.926 \t잠재 손실: 3634.054\n", "26 훈련 전체 손실: 15351.327 \t재구성 손실: 11591.437 \t잠재 손실: 3759.8906\n", "27 훈련 전체 손실: 15188.266 \t재구성 손실: 11508.098 \t잠재 손실: 3680.168\n", "28 훈련 전체 손실: 14944.834 \t재구성 손실: 11275.673 \t잠재 손실: 3669.1616\n", "29 훈련 전체 손실: 14949.296 \t재구성 손실: 11173.085 \t잠재 손실: 3776.211\n", "30 훈련 전체 손실: 14824.383 \t재구성 손실: 11233.498 \t잠재 손실: 3590.8848\n", "31 훈련 전체 손실: 15053.771 \t재구성 손실: 11336.643 \t잠재 손실: 3717.1284\n", "32 훈련 전체 손실: 15209.582 \t재구성 손실: 11480.851 \t잠재 손실: 3728.731\n", "33 훈련 전체 손실: 15029.901 \t재구성 손실: 11239.151 \t잠재 손실: 3790.75\n", "34 훈련 전체 손실: 15018.421 \t재구성 손실: 11247.266 \t잠재 손실: 3771.1555\n", "35 훈련 전체 손실: 15295.654 \t재구성 손실: 11592.32 \t잠재 손실: 3703.334\n", "36 훈련 전체 손실: 15067.271 \t재구성 손실: 11287.572 \t잠재 손실: 3779.6997\n", "37 훈련 전체 손실: 14845.694 \t재구성 손실: 11252.967 \t잠재 손실: 3592.7273\n", "38 훈련 전체 손실: 14872.638 \t재구성 손실: 11183.228 \t잠재 손실: 3689.4102\n", "39 훈련 전체 손실: 14961.719 \t재구성 손실: 11297.793 \t잠재 손실: 3663.9263\n", "40 훈련 전체 손실: 14667.465 \t재구성 손실: 10977.892 \t잠재 손실: 3689.5732\n", "41 훈련 전체 손실: 15164.336 \t재구성 손실: 11456.284 \t잠재 손실: 3708.0515\n", "42 훈련 전체 손실: 14535.691 \t재구성 손실: 10862.055 \t잠재 손실: 3673.6365\n", "43 훈련 전체 손실: 14729.365 \t재구성 손실: 11080.487 \t잠재 손실: 3648.8777\n", "44 훈련 전체 손실: 15044.16 \t재구성 손실: 11426.916 \t잠재 손실: 3617.2446\n", "45 훈련 전체 손실: 14839.276 \t재구성 손실: 11058.229 \t잠재 손실: 3781.0476\n", "46 훈련 전체 손실: 14890.201 \t재구성 손실: 11144.563 \t잠재 손실: 3745.6377\n", "47 훈련 전체 손실: 14605.932 \t재구성 손실: 10951.763 \t잠재 손실: 3654.1694\n", "48 훈련 전체 손실: 14460.681 \t재구성 손실: 10878.129 \t잠재 손실: 3582.552\n", "49 훈련 전체 손실: 14584.321 \t재구성 손실: 10932.154 \t잠재 손실: 3652.1667\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 = mnist.train.num_examples // 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 = mnist.train.next_batch(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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7z4RykoYq70HRjihoqICgLvvvpv58+eTnJwc8DH+Eh6Ph/Xr1wMwefJk1q5dS0JCAgDnn38+Z5xxxlFxfhwMTdNwuVzytc1mC1qOja9Crww69W/qa4XFYsHpdLJlyxYA3nrrLSwWC3fddRcAHTp0EOW67bgP5znCWijX19ezePFiwBCy55xzDh06dAD2j7VpmsaGDRt47bXXALj44os56aSTiI6ODu6gfwUlUFatWgUYMaDOnTuHnfLg63VQh25VVRUAERERxMfHy2GlFmIwcTgcALzzzju89dZbANTW1uLxeIiPjwfgpZdeorW1FbfbDRgHrq7rREVFAWC32xk4cCC33norAKeccookVQXiMFCbffHixfzP//wPYMzz+PHjGT9+vIwJEMvnyy+/pGPHjn6CIxzwPUjV2vj8888BWLZs2X4VBU6nk5SUFMB4xmAKD7VWJk2axNy5c2lubgaMvdenTx9GjRol43z//fclFl5cXMwHH3zA2LFj5f+DjcfjYfv27Tz++OMAbNq0iezsbEaPHg3ATTfdREpKSsjPD1+PlfIE+r7/th4tTdOoqakB4N1332XGjBn07dsXgEceeYS8vLyAjxcMBbm8vBww8nssFosoxPHx8ZSWljJw4EAAoqOjWb16NdOnTwdg6dKlREZGyrjPP/982adKwf8taya8JIGJiYmJickfmLC0lJUW46v9nXDCCQwaNOigVpnX6+W1116TUoFI+inpAAAgAElEQVSYmBhOOumkwA/2MNE0DYfDIS6Qrl27EhUVFRIt3Fdz9Y1zt7S00NjYKHGs5uZmKioq2Lx5M2B4LXr27EnPnj0BQ6MMdvxWlcadcMIJfPrpp4DhjvSNbba0tOBwOOS5lOWvaoIjIyNpaGggNTUVMNabr7bf3taHCq1MmDCB3bt3A3DBBRdwzz33SBWBQn323r17ZfzhgqZpeDweP/ee77wnJyf7eX8iIyMZOHAgZ555pnytaFun397ous6mTZsAWLt2LTabjeOOOw6Ayy+/nCuvvFK8I8q6U252h8NBRUVFSMI2am737NnD888/Lx7Djh07csYZZ3DllVcCkJSUFDIrWdd1GafT6RS3f21tLbt27SIpKQkwnqWkpISioiLAOPMSEhLEi1lXV8eKFSskgzw9PT2gc63runjPNm/ezJQpUwDjvPANb8XGxqLrOuvWrQMM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/zx33303ELgeDGEplA+ESp5Smpmy5nz/v7m5WQ636OhokpKSQlIv25avv/5aMlR79uwZFkL4QBxsY+i6TlVVFU8++SRgFPtfdtllXHzxxUDospoPFfVcQ4YM8btSLj8/P2hjsFgsUsd76623SvZ9cXExjY2N4oVITEyksbFRYnWwvxB0Op18//33gFGnqqzsbdu28fHHH7eLIHE4HNx5552ybo8//nix9AsLC/3eudfrZefOnSLMWlpaqKmp8bOcAo06F7Zu3crnn38ujU6OPfZYsdRV/oaaa+WlUtcEXnbZZX7193v27CExMTEo47fb7dx+++2AkUGtMt3T09PZunWrJLRGRERQWloqFSqqRlnlztx9992cc845Qeuo90uoz9Z1nfLycokhd+7cGZvN5tfIKFzORF3XRVk4++yzAaQbo8fjYceOHbK2ApWcFnr1xMTExMTExAQ4CixlpQGr3rrKnZacnExcXJxo401NTcyePVviQ4WFhZx//vlByZb7Nb7//nvRCn37qh4ttLa2cvnll0vJxlVXXcVtt90WlNtc2gO1hiZOnIjD4RCrY9iwYUG18pX7btCgQeJleO211/xKXJqamnj77bfFusvMzCQ6Olrm2ul08tVXX0kZj8vlkv8bOnRou7kB1eeovsDLli2TLNTTTjuNvLw86SHw+eef8+KLL8r3RkREcPbZZ0u2eTCtoJ07d9LY2CiWZmVlpYwrOjrar0VlVFQUNptNPAv5+fkMGzaMBQsWALB+/Xo6d+4ctJIzVec9YcIECbG4XC727t0rJVJOp5PXX3+dVatW+f2cyqUZPXp0SPsz+OJbK15aWupXMulbcQLhEcJT7W2Vx6dfv3506tRJvFavv/46y5Ytk/Vx1VVXBWRthL1QVhto7969LFiwwG8xxsbGSkF8ZGQka9askQSIoUOHMnjw4JC/bNVnVcUQa2tr91uQ4YqKpYwdO5ZFixYxZMgQACZPnhy0WNuRommaHFgzZ87EarVKgolv0k8wiYmJ4a677gLg5JNPprKyUtatSnhRDfPT09P9mvvb7XY2b94sAjE/P58RI0YASNlde6AunFCtV5UwAONqT5fLJYk8qq2qUoCvueYapkyZElSlTe2nwYMHM3jwYEkqWrdunVzeMHr0aJKTkyU2HhER4Xeo6rpOY2OjCPGVK1dy+umnB0UoWywWSe7q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\n", "text/plain": [ "
" ] }, "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": "iVBORw0KGgoAAAANSUhEUgAAAagAAAEGCAYAAAAwpAFeAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzsvXd4lGXa/v+ZPumFJKQAgRBDINRQRERpFgTpvvKirorr6qKr7lfX3VVXRHexLa662EF9RQWXIihSRJEOoQYIgQChhoT0nkyf5/fH/O7bSQSBZCYE9jmPY4/Fycw899ztaud1XRpFUVChQoUKFSpaG7SXewAqVKhQoULFuaAKKBUqVKhQ0SqhCigVKlSoUNEqoQooFSpUqFDRKqEKKBUqVKhQ0SqhCigVKlSoUNEqoQooFSpUqFDRKqEKKBUqVKhQ0SqhCigVKlSoUNEqoQooFSpUqFDRKqG/3ANoBLXukgoVKlRcXdA09YOqBaVChQoVKlolVAGlQoUKFSpaJVQBpUKFChUqWiVaWwzK73C5XGg0GrRaVTa3ViiKgt1uB8DhcBAUFIRG02Q3tooWhGjf43a70Wq16rqpaBauOgElDohGo+F8va7E4VFx+eG9Rna7HYfDgcPhIDc3F4CwsDA6d+6MTqe7XENUcQ6IdXM6ndjtdgoKCliyZAlffvklABaLhREjRjBz5kwiIyMB1DN3ASiKIu8tRVFwOp3ybwaDodnC3vtuvFKgaWUNCy84GLGIF/M+t9vdQBiJz7aUZudwOLDZbJw9exYAvV6P0+nE5XLJzWKxWKiqqqJTp07ExsYCYDKZfD4+sendbrf8bkVR5MV/OTZt471nt9spKyujvLycVatWAVBZWclf//pXgoODr6iDdbXD5XIBnj1+8uRJ3njjDVatWkV9fT3g2cMhISGMGjWKv/71rwDExMSoQqoRFEXBarUCUFFRgdVq5cSJE+zatYvs7GwAIiMjueGGG0hMTKRfv36Xc7hNhcriU6FChQoVVxeuOBffxWrR3paSt2nbElq4oiicOXOG+++/n/3798vXQ0NDiYiIwGazSfPdbrcTGhrKyJEjefDBBwHo0KEDBoPBJ2MRz6mvr+fkyZO88sorJCYmAnDLLbcQFxeHxWLB7XYDEB8fT2xsbItouo3Xwmg00rZtW0JCQujSpQsAu3btwuFw+H0sAo2tOtVqOzfEPFVVVfHaa6+RkZGBXq8nISEB8Ow7jUZDTk4Oa9euBWDixIkEBARctjG3NrhcLnbv3s3TTz8NeM6ozWbDarVitVqpra0FwGazsXDhQqZPn94sC8p7b18p+/qKEVBN8Z8qioLL5ZLuCL1ef173nrigxd+as4CFhYWMGDGCwsJCXC6XFAj9+/fn5MmTVFZWUllZKcfUoUMHpkyZIt/ny3iL+O1FRUUsXLgQo9FIUlISAO3bt+fkyZPMmzePvXv3AhAcHMyXX34p39OSEEqF0WiU671//37KysqIiIjw+/NdLhcWi4Xa2lrpdklISPhVZUHM76lTpygsLCQ9PR2j0Qi0bMzlXK56l8uFw+FosOe1Wi06na7ZF5TFYgHgzTffJCsrC5fLRWpqKqNGjQIgLi6O3NxcDh48yLZt2wAYMWIEZrO5xS5Hp9PJyZMnAZg5cyY5OTl07dqV8ePHAzB06FBCQkJa9LIW90x+fj7Tpk1j/fr1khAUFBREbGwsXbp0YciQIfz0008ArFu3jpKSEvbv39/kOJLb7ZYCz2w2X3RMyzss4Iu78VJxxQiopkyKw+EgPz+f+Ph44JcXhlhsRVFwOBwoioLJZGryGMXm++mnn9Dr9YwePZopU6YwaNAgwLMxcnNzef/99ykuLgZg2LBh3HPPPYSHh/vlQhNj2rRpE9u2bSMlJYVhw4YBEBUVRZs2bThw4ABr1qwB4MSJEzz11FMsXrz4shETjEYj/fv3B2DRokU+uVAvBBELmD17NitWrKBdu3YATJ8+nZSUlAZzIaxyh8PBrl27AHj66acpLS1lzpw5DBw4UP4Of45XWMcOhwO73Y7FYpExoKKiIrZv387evXvp3bu3FLL9+vWjT58+GAyGJu83RVGoq6sDflYgunbtyowZM+jduzfgmaPKykr+/e9/s337dgD27dvHTTfddMF95QsSk6IofPjhh/z5z38GPHNkMpmwWCycOHECgO+//57XXnuN4ODgZj3rYuFyuXjllVcAeP3116mtrUWn0xETEwPA5MmTue++++jcuTNGo5Fx48YBcMMNN1BSUiKV2kuFYMWKvRocHEx4eDht27YlMDDwnHFocTfa7XZycnIwGAzSq6HXt5zYuGIEVFOwYMECvvnmGz744AMA2rRpg06nk4QB4ToSBy4vL08uQlNcEWKBb7vtNtq1a0evXr0aBPcVRaGqqoqamhq5UVNSUvymaXv/xp07d3LixAl69OghD2RQUBAul4vu3bvLz9hsNtatW0d5eTnR0dF+Gdev4Vzsy5awnjQaDTU1NWRmZrJnzx5ycnIAGDhwIO3atWtAdRcHPjMzkyeffBLwXL4GgwGXy+XXA+xyuaivr6e4uJhTp04BHjfo2bNnqa2tJTw8HPAIx3379nHmzBmqqqro0aMH4CGdWK3WZiliiqJw+vRpAI4cOYLFYiEhIYHk5OQGwsdoNHL69GmOHTsGwHfffceQIUMuKKB8oYzU19czY8YMuf/Hjx/Ps88+S1FREW+88QYAS5cu5dZbb2XMmDEtogD99NNPvPzyywBYrVYMBgN33XUXM2bMADzudb1eL8+AYD+6XC60Wi1t2rRp8rMdDodchy1btmA0GhkyZAgjRowgJCQE8HhuxPNtNhsAP/74I5988gkTJkyga9euzZmCJkElSahQoUKFilaJq9aCcrlcTJ8+HbPZLDW281kqbrebPXv2YDabm2XNCC0sJCSE9PR0zGYzbrdbxik2btzIzJkzeeaZZ6Sl5m/NraKiAoC9e/dSVVVFYWHhL1ybAQEBdOzYUb6/traW//znP/zhD3/w69gEGltM3i6k2NhYgoKCWmQMP/zwA+vWrcNut8s9c+DAAYqLi4mLi5Ovud1usrKymDlzJvv27QM8rhART/RHioBw3c2ePZuVK1c2+HtpaSmxsbGYzWap+TocDs6cOYNerycqKorbb78dgE6dOvnEpXXmzBnAY6k4HA40Gk2DvQ5QV1dHWFiYtGKKi4upq6u7YBqFL+Zv06ZNWK1WRowYAcBnn32G2WzG6XSydetWADIzM2Uszd+w2Wx8+eWX8rfFx8czb948hg4det47Z9myZYDH2oqKiuI3v/lNk+ZGrI2wmuvr63E6ncTExMjQBnj2jFjDo0ePAvD1119z9OhRBgwYcFlSBK5aAbVmzRoKCwsZP368NGG9F1ej0UhXjEajYejQoTIg2FwIN+KpU6eorKyUhzY3N5d33nmH7t27t1igUbhizp49i91ux2azNXBtGo1Gevfuzb/+9S8ARo8eTU1NDV988QWPPvoo4F8hKtytgAzGut1ueSH36NGjRQ6GYEpVVVWh1Wrp3LkzAMOHD8flcpGbmysPuMPhYPfu3ZSVlck4kHDJxMXF+XS+bDYbGRkZUlkQQf/Q0FA6deoEeFifnTp1Ii0tTbqF1q5di16vp1evXjz++OOkpqYCnr3Z3NiiRqMhKioK8CRS19TUUFNTQ3l5uRR+TqeT0tJSsrOzpbJx/PhxrFYrbrfbr/FNRVHYtm0bkZGRTJs2Dfg5t9DtdrN582bAs46+Xq/zjcdqtaLVahkzZgwAc+bMkffSud6fn5/P9OnTAY/yc88995Cent6k52s0GkJCQqSw7tChA6GhoSQnJxMYGCh/v2BeAtJVXFlZSadOneRea2lcMQLqYtkr4sJ48MEHMRgMvPTSS+eNCYiLz9cXoKIoHDx4kGeffRadTsfw4cMBz2WXmpp6WTQRu92OoiiUlZVJ1pBWq0Wv12MymWRwu2PHjmRlZXHs2DE5l76ivJ8P4jlOp1POjTi8LUUx37JlC+vWrcPpdBIcHMxvf/tbANLT0wkICMBgMGA2mwGPdT5o0CB++OEH+XmdTsf111/f7LnyTuIuLi7mhRdeYNmyZQ0SYOPi4hg7dqxko9lsNmJjYzEYDDJ2VlZWBkBiYiJJSUkNlDFfICUlBYDk5GRKS0uJiYnBZDJJBU9RFDIyMsjOzpbssfr6evlesc7+Eg5RUVFERkZKsosYU3l5uUycN5lMpKSkXHTyf1Mh2KHTpk2T8d7zxbgVRSEvL48bb7yR0tJSwMOIfP7555sV29RqtbIQQFhYGDqdDpPJhFarlftNsGf1er1ksVqtVkmquRy4YgTUxW4gUWrF6XTSpk0bqTVBy1WScLvdLF++XNJCBfsmNDQUjUZDSkoKoaGhgP+pyGJTBgYGUlVVRWlpqXQDCdo9/Mw4mzJlCkeOHEGn00lB5s/N6Xa7KSkpAaC2tpbExER0Op18Znx8vE+s2vNBCMC//OUv0t0TGRlJz549Ac9hNplMGI1GOQ673U5QUBDBwcFy/vR6PSNHjmzWegpNW1xMDz74ILt378Zut8sUhClTptC/f3/i4+Np27Yt4LloFUWhurqa6upqAGpqakhISGDMmDENXGq+2PcajUbu3xtvvJEdO3YQGxtLeXk5gYGBAJSUlPDVV19JFzNAnz59SExM/MUYxAUpPA3NZW2KM15UVCTZqd27d0dRFL777jvKy8sBaNu2rVQ6/AmNRkN4eDghISG/yuwU+ZPjxo2jpKSEuLg4AFatWnVea+tSIKzWgICA89LGxX0pUgPy8/O5/fbbL1sFEJUkoUKFChUqWiWuGAvqYuBwOGQNN7PZTFJSElarVVoM5eXlLVIlQVEUevfuzbBhwygvLyc5ORmA6upq3nzzTQwGA7feeivgyXEQ9FJfQ6PRSC0sODgYh8NBXV2djAmIscLPltzYsWN58803cblcFBQUAB43jr8sTqfTKSsN9OnTR1p1IpbSvXt36YbwB/lAxOjy8vIakEeEFWO324mMjGwQs7RYLBw+fJhTp07JeTMYDAQFBZ23QPHFjicnJ4f33nsPgD179sjn33333QAMHjyYsrIydu3aJbVqYWUGBQVx+PBhwBNzHD58OElJSQ3cOOAbK0r8brPZTG1tLQcOHCAgIEDGSdasWSPdjSLpe9asWdKL0DjnRhAtwDd5NiNHjuTdd9+V94FGoyEtLY3PPvuMmpoaALp06YLT6fSbi897PymKQkFBAVVVVQC0a9eOqKgotFqttOI3b97MY489RklJCV27duXrr7+W7/Xl+C50/7lcLknQqK2tZeTIkT579qXiqhFQwpU2ePBgwBNLadeuHZGRkRw/fhzwEAaioqL87k/V6XSMGzeO0aNHy7wCMUbwBB7F4T1x4gQnTpzAZDLJ5FRfBpBFYL9v374cOnSIiooKsrKyAOjVq5d0OQj3lSjHVFhYyPvvvw/AP//5T78EtUWyaVhYGPBzDpS3Sy88PFwe8MYXSXMPrffng4KCKCkpQaPR4HA4eP311+Xf4uPjCQgIkC7P4uJiTCYTBw8elG4prVbL2bNncTqdTS7Aq9FoSEhIkP5/kTjep08fuU7Lli2jrKyM8PBwua/Dw8Pp168fffv2lQSAwMBA+vfvj9lsRlEUv8V8jh8/zsGDB3E6nWRkZMi1DA4OJiwsjICAAP7yl78AyAvZG4KhWF5eLgPzIjbaHCQlJfH666/z5ptvAp7LPysrS5JMAFlWyF/Kl3dB6EWLFvHRRx9JBUKn00mXn9gvVqsVRVEYP348r7zyisx78rVC7Z1r2Fhxcbvd5OXlcfDgQcBT/cY7jtfSuGoElMPhoKKigrFjxwKeC0en02E0GuVkr127lj59+vi93IooJ3M+f3NMTIxMgq2trSUjI4MHHniAqVOnAvDcc8/5bHzioP+///f/WLFiBVqtliNHjgAeq0GwmLyp+BqNBrvdLkut1NXVyZiDr6HX6+nWrRvgObTichaVnK1Wq4y3iFgL/FxX0TuO1pQ5E4dv7NixzJ07F41GQ1hYmIylOBwOCgoKcLlcknhgsVhk4FvMm91u5+DBg5IEAJfeIkGj0RAREcGkSZMAzwWq1+uJiYmRVq9er+e2225Dq9XSvn17+bnAwEA+/fRTSXvv1q0b11xzDdCQKemrfSW8Evv27aOqqor6+nrcbrdU/iIiIggJCSElJUVaVd4Xo1BC6urq+P7773G5XJIp1rdv32aPT6PRMHr0aEn+KSgoYPXq1axYsUKu2eOPP05sbKxf7gK32y0TYz/77DM2btxIQUGB3N8Oh0PGpr2JQd27d2f69OlERES0iKen8X/bbDaWLVsm76677rrrFxa4eK+3wuivsV4VAsrtdmO1WomOjpY5MzqdDqfTicPhIDMzE/AcmpYom3Mx3y/eExwcTHx8PNXV1bLixaOPPuqz6gniOampqUydOpVVq1ZJMsAPP/zA4MGDiYqKkvTgyspKOnbsSF5enizHtGvXLoYNG+bzedNoNBgMBlmKSuRn7N27lyeeeALwaN29e/fmiSeeICQkRJIA8vLySE5OJigoqMGaXyqEhTlr1izuv/9+SktLMZvNUiDX1taSk5PDmTNnOHToEAA7duygvLxcBuPBIzhKSko4fvy41Hy9reeLhdFolFTkW265RX6HN+O0cc6RxWJhz549TJ8+Xa5tfHw8HTp0AH5Zwqa56+h2u6X1Vl5e3qC+n2BkitYR0dHRkighGIpVVVUyj+qDDz6goKCApKQk6Qr31WUnLFLwMOEOHDiAy+WSKQSTJk3yi2vdarWyf/9+vvrqK8AzF/369WPAgAFSKOXn53Pq1ClpdYOHkGM0GikpKZHkJn+isbdCEJb27NkjlcauXbvKJq8Cdrsdp9MpyUP+hEqSUKFChQoVrRJXrAXlLf2dTic1NTVERERIjUgEXpcvX86GDRsATxJqRESE333OcGltQdq1a4fL5aKoqAiATz/9VNZ48xX0ej3PP/88iYmJ0vWQl5fH0aNHCQsLk9p4QEAAKSkpbNu2TebebNy4kaFDh/pl3rRarcwJEVTuiIiIBk3c7rvvPqKjo7Hb7XLNRXFdrVYrX2tO+oBer5fuIO91VBSF/v37U19fLynLFRUVkv4tnifcgoImL8ZzqRBWJfw6vd87TiOsLG/yS3p6Om3atJFuRl+und1ul9UYEhMTiYiIICYmhqqqKlkVv66uDovFQl5enrQ8u3fvTlVVFRkZGfJ9mzdvJi4ujrq6OulWtdvtPqN/e1Opv/76axwOh6yq4Q/t3+FwMGvWLAoLC2Uy85gxY4iLi8NkMknLvKSkhB07drB//355Hg8fPszBgweZO3cur732ml+tE2+rXJx9RVEoLi6mqqpKFjxu3749Wq22QYUQb6vLO5blj/vhihRQoo2GcGeIS877srJYLMyZM4dFixbJC/Cuu+5qVpHMi4WoxnyxC1ZZWYnBYJBjF4mNvobZbGbixImyqnFVVRVJSUnU19dL1lxUVBS33norH3/8sbxo8/PzcTqdfjsw3u4rl8tFQkIC1157LeDJek9JScFoNKLVaqXLxuVyycvXH0Fk739rNBpMJpMUmpWVlRiNRhwOR4Mq4dOnT/cbI/NC492zZw9ut1te8v37929WxfLzQVEUamtrpYuva9euDB48mN69e2OxWFi4cCEA7777LhUVFdTU1MicmqCgIM6ePcvevXulqzY5OZkOHTrw0EMPyVwvf5CY6urq2LNnDxqNRlaX8MeFunz5cvbt20d8fDx33nkn4Mm30uv1uFwuuYcOHz5MdXU1cXFxksV3+PBhNBqN/Nu5KuD4EuLsiHvHZrPx8ccfk5uby7///W8AGa/3NgiEMmSxWKSA0uv1TXJpXwhXpIASmll+fj7g8beHhoYSGhoqJf3atWt56623MBgMkpHl76rYwpcsegpFR0ef97B5M3z++c9/4nA45IacOHGi38ZoNBpl8NxoNBIaGorRaJQaqyhRAw3berdEop44BIWFhVLrvvvuuyURorFy0VLlogTTTFCWrVYrRqMRvV4v42dTp06lXbt2fjmkF4LD4ZBVLURaQdeuXf1WTqisrEwKmHbt2hEXF4fdbsdgMMg1slqtOJ1O7HY7GRkZgEdIxMfH06lTJ5kIHRcXR8eOHUlISPBpMnFjLF26lNLSUpKTk6Uy5ksIhuePP/7Ijz/+SL9+/WSz0nbt2lFaWkpubq5UPk+ePElgYCAhISHS0hJKT2VlJWfPnpVr6e+2N2K+9+zZw/fff0+bNm2kIuhNQPImRISGhmK326XS2pz0il9DqxZQ5zMba2pq+Oabb8jNzQU87pWBAwdy0003SaE1d+5c7HY7Tz/9tGT2tRQ54uDBg7z77rv07t2bRx55RF7+QhNxuVyyesKcOXNYvHgxAQEBzJw5E8BvZe2F+0hUIPBmG3pT4bdv347b7ZabLi0tza8CyttNYLPZ2LBhgxSObdu29evFdbHjO3z4sGQ/VlRUYDAYaN++PTfddBPgsaAuh3ACOHr0KFu3bkVRFFlWKywszG9jsVgs0nuxbNkyTp8+TWpqKi6XSwpKm80mny8Yf0FBQaSnpzNs2DDJYhXldrzHKmoy+gJib3377bdoNBruu+8+v1hoBw4cADxtbWpra9m6datUsrRaLRaLRe4Z8FTgSE1NpXPnzlKxPXz4MKWlpYSEhMhWOOBfAeUteE6fPo3JZOKBBx44pxfA+44Q1lfjPEpfQyVJqFChQoWKVolWbUGdT4uKjIxk8uTJMlfmxIkTsn250I4eeOABpkyZwh133NFihQ6FphMbG8vRo0dZuXIlWVlZsipxWFgYFRUVzJs3j3nz5gGezqcGg4FHHnmECRMmNPgeX0Oj0WA0GqU7QpTa1+l0UgMqLi5m1apVuN1uGdAdNWqUX5sqete4q6iooKSkRGrYkZGRfq+deCHY7XY++ugj6foUSZYpKSlyzfzVEfnXIDTvRx55RFK6H374YcC/9ROjo6Oldm+1Wlm5ciUZGRkYDAZJozYYDAQHB9O3b18eeeQRwGM1mM3mBrlr54Iv11rsrfXr1wPQuXNnv+wl4fVISUnh0KFD2O12maYhPBc6nU5S3NPS0hgxYgRhYWFyHbVaLe3atWPixIkkJSW12L0l1jI4OJjOnTtzxx13XHCORFFZcVepJAkvCFNZJFmKS847DyMxMRG9Xu93nr43xAK1a9eOF198kUceeYTvv/9eBomdTifV1dUygx2QreGfffZZnxSEvBD0er00y+vr6ykrKyMiIkJu0nfffRer1YrZbJa5EOJQ+QPeAkq0sSgoKGDQoEEALVKa6tfgdDrZuXMnmzZtkiVyhEv5iSeeoOP/30fL203aXFxMUq3oXwUetxLAgAED5Fr5M7Detm1b/vjHPwLw9ttvc+zYMeLi4ggMDJSVJLRaLb/97W+55pprJEnpYnMQfTl2oVRUV1djMBgYNGiQX/aTiL29/fbb9OnTh7Vr10rCSnp6OqNGjSIsLEzGwQWpy5vkM3jwYAYOHHhOt6e/ILpDg8fFd7FM58bMUL/tN38Ft5qIVjWY5sDpdJKbm8vzzz/Pjz/+KF8LDAwkPDxcXsDTpk1r8XL2QiBYrVbq6uooLS2ViZPz58+XpZDmzJkDQO/evf1KzRfC0el0yuoMQrG4UHM7f6OmpobJkyezc+dOqS1269aNF154gX79+snL15eX3oUElCjrJfr77Nu3j8DAQDZs2ECfPn1+9bO+gneKh9CeGzMqL7flC8h6dlOmTKFt27YcOHDAb1VRBLxLc8GF90bj2E5Lwm63y+aEy5cvZ/LkySQmJp5zzN6NDW02GyaTScaqLvAbm/yjrkgL6kqAXq8nNTWVhQsX/qLu1eU+uOLZZrMZk8lEcHCwZBJFRETwxRdfMHbs2Bbp+ivKFYFnzlqi/cHFwLtuYnV1NUFBQZJc8vDDD9O7d+8WSVnwHov4t91u54033uDUqVOAZ94mTJhAWlpai+2rxm1aWitE7T29Xk9QUJD0sPgTTc07uxx3gqIokrCVmppKcHDwecchlBKhULrdbvma2+32S3qFSpJQoUKFChWtEqoF5Wf4OovfF2hM2w4ICJCuqujoaJ8U67xaYDabCQwMJCUlRVblFp1zvWm2vnTPeLt8zuXuczqdVFVVyTWLiopi9uzZrd6auRy45ZZbAJgxYwbBwcGtxkJvDRBEB3HeRR3Kc+1lkQICnth1YGBgi7jf1RiUChW/ArvdjsViwWQySZfe5VY4XC4Xubm5vPTSSwD8/e9/p2PHjpeVTNLaUVZWJpWNy71+rQnn6lZ9PvKDt4tPdJW+SDR5wlUBpULFFQpft9BQ8d8J71qWfoIqoFSoUKFCRatEkwWU6hNQoUKFChWtEqqAUqFChQoVrRKqgFKhQoUKFa0SqoBSoUKFChWtEqqAUqFChQoVrRJqoq4KFSpUtCKIpFjvNALRUfq/Df99v1iFChUqVFwRUC0oPKVj8vPzadu2rV9KoQhNyOl0YrVaycvLk31z2rdvT9u2bTEYDP91CZdOpxOn00lZWRngaceg1+sJCQmR1d3/G7VGFc2D2+3GYrGQk5PD0qVLASgoKODs2bOUlJTIlhc33HAD9913H3FxcT4tEyVayHh3xPVunS7eI/7tXc3B7XZTWFjI0qVLZQdnUbA4OTlZdt3+bynZ9F8roBRFweFwAJ4mfWfPnqWyspIePXoA/qmhZ7fb+e6778jMzJQCaujQofTq1YuOHTvKTedd7bwp1QLEhm9cy63xZX+5qieDp57Xvn37WLJkiWw8eeTIEVwuF8HBwXTv3h2Av/3tb3Tr1s2vba9bO9xud4OePT/++CNFRUXyAhS9u66//npZld6f8+Wd3N+alCpRqXzVqlW89dZbbN++XfZd866ZKP69du1aXn31VVJTU/nyyy8BT0Xv5vwmRVGk4iXWDJAuusbtKbz7oYnWM1arle3bt8t+X3V1dSQkJMj+bM2F+P1utxuHw0F9fT3gaVu/cuVKDhw4QGFhIeDpo5WUlMRbb73VIt0NGuOqqiThvfnEf3sLGu9L32q1snfvXgAWL16M2WxmwoQJ9OozP0CoAAAgAElEQVTVC/BdR1JFUairqwNg4cKFLFy4EIvFQnp6OuBpbuhwOIiOjua6664DPA0ChUbnLWAutDFEQz2Xy0VOTg5r164lJycH8GiQZ86cITAwUDZ67Ny5M/feey/dunVrsTpz4jDW19cze/ZsioqKiIyMBKBjx45UVVVx9OhR2UNLp9Px+9//nt///vetRkiJi8Ttdjfohio6jPpyDhVFoby8nHfeeQeAefPmUVlZSWhoqNwbdrsdl8tFXFwckyZNAuAPf/gDYWFhPrVAhaAsKCiQF39paSkFBQV06NABnU7H1q1bAc/6Dhw4kLS0NCk0/dGOQcDlcjFr1iwAXn/9dSorKxvcBVqtVs6Fd4sIMa777rsPgPfee6/ZZ99ut3PmzBmOHz8OeDp+JycnExcXR/v27QFPgebGFpRoX1FXV8ecOXP417/+BXiERGxsLGvXrpUNMi91Xb3nQjROLSoqYt26dZw9exaArKws9u3bR3l5uVTenU4ner2eYcOG8dVXXwE0pZ+W2g8KPI20hDAQzQHNZnODC0NRFGpra/nggw9YvXo14OmBNH36dNLS0nx+CTqdTikIs7KyGDhwINddd53sLWQ0GlmxYgXr169n165dADz44IP07Nnzki87Ubyxrq6O1atXs2vXLmmdhIeHExsbS3l5ubxENm3aRGZmJtdddx2///3vAUhISECv1zf7kj1fdW/xmtFo5KGHHkKj0cjOo2LuHQ4HmzZtAmDWrFl8/vnnpKenM3DgwMumsQu3EcC6detYsGAB2dnZspdOmzZt6Ny5M88++yzXXHMN4FkPcSk3ddxOp5N58+bx4YcfAmCz2ejUqRMTJkxg4MCBAGRkZLBmzRqOHDnCu+++C8CWLVt4+eWX6dWrV7P3tHejury8PObMmcOxY8cAz+UrrAaXyyXnqKamhsDAQDp16sTIkSMB+OMf/ygrsPsaVquVxYsXA1BVVQV4lExxmXbv3p2+ffsSEhIiL98lS5Zw7NgxFEUhIyMD8Mx3cwWU6Gu2ZcsWAPbu3YvNZuOmm27iwQcfBDxzKoSM9/+7XC7MZjOxsbENvm/UqFG0b9/+ogTT+c6esLhra2v55ptvWLlyJSUlJXJ/2O12kpKSCAgIkO3qa2trcTgc7Nu3T7riQ0JCWq7vWIs8RYUKFSpUqLhEXDUWlAguHj58GPC4HoYMGdIgmCjom9OnT+fjjz8mJCQEgLfeeouuXbv63HpSFIWqqippQV1//fUMGjSI8PBw+SyNRsOjjz5KdnY2b775JgDffvstKSkpl9waQGhXQUFBTJs2jWPHjpGUlAR4tB6dTkdpaSkbNmwAPBadzWajrKyMhQsXAjB16lTCw8ObrUWeb9zeFlSbNm3O+R6DwcCwYcMAjwY3a9Ys1q9fz7XXXtviFpSwnJYvX86LL74IeLq0ulyuBv1w6uvrOX36NGVlZUycOBGACRMmEBMT06yAttVqZf369TJmGRQUxNSpU7nvvvukdZaWlkavXr349ttvpVcgMzOTF154gQULFhAcHNzk53tDp9MRHx/PpEmTZHwkJCSE4uJiTCYT0dHRct/k5ORQWFgoY2bg8Qz4y4LS6XTS6oiPjychIYEBAwbw6KOPAhAbGyuJSKKvUXh4OP/4xz+or6+nvLwc+NnKaA60Wi1RUVHSwj19+jQFBQUkJSU1IP80DkF4Wz6LFy+WYzKZTIwePfqiXaQXOiN2u126p/V6vYwt9evXj7S0NAA+/vhjwGNlVlZWUlNTI60q4WZsCVw1AsrhcPDjjz9Kl1ZiYiIGg0HGCsCz+b788kv+7//+D0VReOaZZwCYOHGiX+IbiqJw6tQpEhMTAQ9rSLRU9o6LGQwGevbsSe/evQEoKirC7XY3uTW8Vqulbdu20o3ojYSEBP73f/8XgMmTJ1NZWcnSpUvZvHkzALm5ufTu3dtnMbimQjy/X79+BAQEYDQaW1Q4iYvq4MGDzJ49m2+//Zbq6mrA43IJCwuja9eu0l1ks9moq6sjOjqamJgY+T3NbWQoej+JWJdOp6Nbt24NWJ9hYWEMGTKE+Ph4cnNzAcjOzubUqVNUVFQQFBTUrDGIz4oYW79+/ejatSvgcaeJtuodOnSQ87Ft2zYWLFggFUYxdn/BYDDwySefAB73Ynh4OGazWcZyNRqNJCRUVFQAUFhYiMFgwGAwyNiQr2Lyer1eEn2Cg4OlIBCxXjGmc2H37t38+OOP8t4yGo1ce+21l/T8c5GrhAIbFhbGtddei16vp1evXvKeCAsLQ6/XU11dLQkeNTU1srGhiBW35Dm8KgSUoiiUlZWRnZ3NmTNnAEhPT8fhcOByueRiHT58mLfffhu73c6dd97JQw89BPjv4NTV1bFu3TppDQQHBzewnLzHr9FoJHFi69atftsEGo1GjkFRlAY+efA0dmsN1G5xOLOyssjPz6dz584t9myn0ykF9kcffURWVhY9evSQGnpCQgIhISFotVr2798vxyuILkOGDAEgMjKywYXUFFgsFiIiIqTAVhSFDRs2kJ6eLq0RrVaLwWAgJCRECsf9+/ej1+t9TkwQ+0d4H8xmM+Hh4bhcLvR6vbzYAgIC5BqKOJAgMfljb+t0OknGEP/vDbfbjc1mo6CgoIGVGRoaSrt27bj77rt9OkaNRiPXIiwsDIfDIZVT8XcBb6HocDh4/PHHsdlscu1GjRpFeHh4s5UMb+9FSkoK7du3/0W8OT8/n6effppvv/0W8JwFjUZDly5dJLmqJXHVCKja2loURZEtnpOTk2Uwr7S0FPCw6EpKSoiNjeWNN97we4vs/Px8jh8/zj333APwqxaR1WqVAfeYmJgWaRWvKAr79u1j+fLl0u1xzTXXXDbrSeSOVFVV8dxzzwHw9ddfYzKZpBXaEmPIz89n/vz5ABw6dIhx48YxdOhQKdg3btzIyZMnsdvtks0WGRlJ//796du3r3Rd+mJ/RUREMGzYMKl46fV6jh07RmFhIXFxcYDHerDb7eTk5EhGlslkIj09nYiICL/sI2+rCjz7V7DXALmf0tPTpduotra2gXvbX2MS8Gb1Wq1WfvrpJ5YuXSrHdt1115GcnMztt98ulUNfCXRvRdBoNGI0Gi/4u91uNyUlJRw8eBBAWix///vfL3nOfm3NBeM0MDCQmpoasrKyAPjPf/7DsmXLKC4ubpCbFRwczNtvv+33+/KcY23xJ6pQoUKFChUXgavCggKPG6Ffv36kpqYCP+cS2Ww2SfdcsmQJ4eHhrFixQmaT+wuCIBEdHf2rVGNB0S0rK5MU+eHDh/stmOyN2tpaFixYwOnTp5kwYQLgCYC2pI9ZURTpFvrhhx/48MMP2bVrl6QKG41GOnfujNvt9nl+0bk07rq6Or755hv5/KSkJCIjI6moqJBujw0bNmA2m+nYsaO07NLT0xk8eDDx8fHSAhVxj+bAaDTy4IMPkpeXB3gsAUVRyMzMlBqtyWQiLy+PZcuWSQumU6dOPPzww363hjUaDS6Xi927d1NYWEhYWBgAZ8+eZdiwYZhMJhnPy8/PJyoqioCAAL+7kcW5EvP2xBNPsGXLFux2e4Nk5vHjx9OzZ09JJHE6nbjdbp9YeWJ/eaeL/NoettvtPPXUU9JdKkID/nCtaTQaLBYLH3zwAbNnzwY87n0REhHjNJlMjBw5krS0tMvi+r8qBJTT6eTUqVPEx8dLwWM0GlEUhePHj/Paa68BngV45ZVXWuQSFoHFkSNHnpNFJS4um81GZWUl9fX1ckO2b9++RSoB5OTkcOjQIUaMGMEjjzwC+DeZ8nxjEbkzWVlZlJSUEB0dzejRowEYNmwYhw8flheHrw7JudbfZrORkZHBpk2bpLIQExNDdnY2GzduZN++fYDHFdOtWzfS0tIIDw8HYODAgcTGxv7CDdLc8QrCy7333gt4qm1UV1cTHh5OZmYm4KmEkp2dzYkTJ2TcY8iQIS1yqQhFbM2aNVRWVsr42/Dhw9Hr9WzZskXG806ePInJZCI1NVXmvvnrHNpsNv7xj3/IvDBBcDEajZJwUl1dzaJFizh58qQkKJnNZtLT030qoLzXoLHC4q2gHThwgB07dmA0GomJiWHKlCm/+LwvUVxczGeffSZDIMKtJ+KZ4JmP6Ohon5FHLhVXtIASk1ZTUyMrEojXqqqqKCoqYsaMGZw+fRqArl278pvf/KZFNAGn00mbNm0aUG/FmEUlC4AzZ87gdruJjIyUiba+SJS9GISEhJCcnPwLam1LWlBarVYG0f/0pz/x1FNPNSjLZLfbWbx4MRs2bKB3797NJh2cD263m5ycHObPn8/JkyelBWswGIiKiiI0NFQKzV69ejF06FDy8/PJz88Hfl6zc1UuaS50Op3Uonfu3ElNTQ07d+5kx44dgEdoKYpCTEwMHTp0ADwpDS3BfBS07fDwcHr27CnjTeHh4VRWVhIfHy/XVyTT9uvXj5tvvhnw0OZ9pYx5s3Wff/555s6dKxUNvV5PcHAwycnJkv7dt29ftm3bxpIlS5g3bx7gIXd89NFHdO/e3Wdz53a75Xn3ppm73W7Onj3Le++9B3hiQJWVlcTExDBu3Dip/PjKovOGqJCekpIivzs4OJjo6Gg6d+7M8uXLAWS1iZaIiZ8LV7SAEot++vRpQkNDiY+PlwHQjIwM5s2bx44dO2Sw8dlnn22RQJ/L5cJmsxEdHd0gB0a8fubMGSk0nU4nkZGRkhXWEhBCPCIigpiYGFasWMGKFSsAmDJlCoGBgS1qzjfOqPeGCDAvWrSISZMm+ZzNJ+aitraW2bNns2rVKoxGo6Qdd+vWjZEjR3LNNddIrVKn06EoCsXFxfICLCgokO49X1uhIj0C4JtvvqGmpqaBoHY4HCiKwpkzZygoKAA8NR5bQuvVaDTEx8fz8MMP43A4pJCoqakhJCSEHj16yLFmZWVx9OhRjh07JgWULy49kUoi6OOlpaWcOXOGfv36ScLKnXfeyaBBgyTlGzxrP2bMGF599VXmzJkDeITB7Nmzef/9931WgePYsWPMmzePHj16cMMNNwAeivuiRYv4+uuvOXHihHy2yWQiMDCQI0eOMHfuXMBTBSM8PNynZ1Kj0dCuXTsWLlwoxyn2dWFhIevXrwc8CnR5ebm0OlsaKklChQoVKlS0SlyxFpTD4ZDl6HNycujcuTMGg0FqIytXrmTfvn1oNBpZCyw5OdmvuRhCezx16hRHjx6VyXBC+ygvL5dBbKGdhYaGSgqqdzXzlkB4eDjjxo2jsrJS1uerqqpi6tSpREZGtopK1WIuSktLOXLkiM8tKOHe3LJlC+Xl5URHR5OQkCD9/6NHj5Y19bxdd3a7Hb1eL91sx44dIy0tjdDQUJ+TOQ4fPixdUMXFxbJWm6BGp6WlsX//ftauXSsLBn/77bc88MADPhvHr0Gv18vitcKDoSiKnDcRF2vfvj0rVqygZ8+ezd7r3i1s8vLyqKmp4cCBA4AnbvKXv/yF1NRU6TE533NMJhOPPfYYCxYsADwurfXr1/vErSbm4vHHH2fz5s0YjUZJ0CgsLMRiscgCseDZV06nU1osot7ha6+9xvTp0y+5ssyFoNPpGhStBc+8xsXFybiw2+2mvr6ekpISSYBpSVyRAsrhcHD27FnJ0ImIiKBDhw4EBATI6t07d+7E7XbTtWtXbrrpJsCzce12Ozqd7hf9l3yx8KIczWuvvYbb7aZNmzbExcXJjXbw4EG6dOkiM8zhZ7ZRaGhoi1XrFr/VYDDQsWNH7r77br777jsA9uzZQ9u2bbnzzjv9Fu+5VJjNZhRFkevtK7hcLmprawEP6yw9PZ2JEyfSo0cPOnXqBCDLGTVuV6IoCjk5ObKApiil449yWWvWrJHu7ODgYG655RbuueceBg8eDHjWsaysjBtuuEG6uUpKShrksvgTYn68846Cg4MxmUzodDqpBFitVgIDA33qrjp9+jRfffUVx44dkxfo+PHjZdWGC51rwUIUF7Jg1Nrt9mYxIN1ut+zdtHHjRqxWK/X19ZId6i2UxJ4xmUwYjUbsdrtsdwHw/fffExISwpNPPiljo74SVI2/R6yl2G/guW+FEeDLZ18MrjgBJRh7Wq1W9kcJCQnBZDKRnZ0tEyyFNnzPPfc0eJ9gg3lvDF8cFpfLJS/5vXv3cscdd8ikV6FBRkZGkpCQgMlkkswdUQWgJZPgvNlFAQEBdO7cWbKYsrOz2b17Nx07duT666+X77ucKC0txe12SwXAFxC9cERpLKfTya233kq3bt0aaJXi0m3co6u2tpYDBw7IPXTLLbcQERHh87lyOp2cPn1aKguDBw/mvffeIygoqMGzoqOj6dWrl4xB1dXVYbfbWyRdQcCbkabX6+WcCaElaN7x8fHNnifxndXV1SxZsoSKigppnUyYMOGiGoCKtimff/65ZPnBzxayIC01Bd4JsGJOvAWeiBvq9XoZJ0tNTaVHjx7k5eWxefNmKSRKSkrYuXMnFRUV0vJsjpD4tR5zglXbuOKNUMRaGleMgBJa2IkTJ9i5cyc33nijZAfV19fz/fff8/rrr0trJTExkU8//ZRu3bo1OAznqubgC42grq5O9m8BeOihh6S7JyUlBfBcNsLsF2MSXWSbWnevORB1AIODg6WVabfbmT17NnV1dbI/1eUUUCL4r9VqG1iezYUofSMuDb1eT2JiIiaT6Rdr0Zhs4HQ6yczM5OjRo7ImXXp6ul9yjlwuF6dPn5ZFf2fOnNmgZI6AYEMKd3JFRQW1tbUt6pbxZqeKNjeiHiV4GgQOGTKk2WV74Ocza7PZOHXqFNXV1bISy5IlS0hPTz8n2cfbyhP3xnvvvSfvF61Wy0033SQJMU2BcMuKihCiWaHZbJbn3+12o9frue6665g+fTrgEVCimsq+ffv49NNPAU/+2IQJE5rlPhaeGvg518tsNv9C8RLVLLwFlBDYlwMqSUKFChUqVLRKXBEWlHfwNT8/n+zsbMLDw6V2OH/+fLZt20ZRUZG0BD744AO/1SE7F86cOSNbJ/fv3/8XjRLBU/jzzJkzhIWFybELWvLlIiQIV6dwIQ0YMACz2UxJSYnPacrCpSLg3eX0fHA4HNTU1NC7d2/69+/vs7GIPBRR/buqqupXmyx6a6D79+9n/vz5hIaGygTn5lYMPx/cbjft27eX1llsbOx5n2Oz2aTmGxAQ0OIxRO/u0SEhIXLO1q1bB3jIQw6HwyeWppiDxMREGUcS5++LL74gPDycyZMnk5CQACBdnVVVVTKWOX/+fOneE98XExPDO++806xUAZfLRUFBQYN1EnEu8VpAQACTJk1i5syZMt9JVJzQ6XQNuhEcPHiQ1NTUJo9JnDsxP9XV1RQWFspneH+vCKF4x8gCAgJ81m7+UnFFCChh9oKHLVVUVMSXX34pTfqSkhJMJhNPP/207AzbnB48TUFsbKwsiV9SUkJRUZGsfi0C19u2bePQoUOMGjWqQRvs1sCWE2NwuVxUV1cTEhLilyC7qJxeVVWF3W4nJibmF+3mvWMZu3fv5uzZs6SkpPisr5F4lghKg0fBOHLkCCEhIdL1ISDcgaIH0ty5c4mOjuaZZ56RCbT+WkOTycTdd98tq0bU19f/IgFXURQqKyvJyMiQ4x4wYIBP5+ti4V0p3+l0YrFY5NhFW5CLiQ9dLKKiorj//vt5//33JdGhsrKS119/nffee0/Gf2NjY1EURfbsAk/um0hY7dWrF+Bp+d5ct6iiKLLMmvhvu92OVquV3/273/2Ov/3tbw1ihN4sUa1WS58+fQDo0aOH7LTblHkT3yfuxLKyMlavXs3BgwcZMmSITEAPDQ2lsLCQuXPnyrsVPHvwcjD44AoSUOISu+aaaygrK+PEiROy0VanTp0YMWIEsbGxly1eEhoayqhRowBPA8RJkyYxYMAA2rdvL6sNlJSU0KdPH5KSkn5xKV8uCJ+8sA6++OILioqKePrpp/1S9kg0YVuyZAl79uwhPT2dcePGAZ7LRrD1BO03KyuL4OBgbrjhBp8SScTFJBSFiooKFixYQHl5Odddd518lsViITc3ly+++EI2ekxNTeXFF18kISHB7+un0+no2rUrRUVFgIfE0qVLFyIiIqQCUVVVxTPPPENxcbEUSv/4xz9a1IISl7AgGwjhn5WVJUkAb7/9ts8bgxoMBmbMmIHZbJYxm5KSEux2O2VlZXK/CXavt5Ws0+lITU3lueeeY/z48YBvKtBrtVratGkjLaDy8nJpOYpebM8//7wUOOez2sX5O1eLnqaMSXxfaGgoiYmJ7Nmzh/nz57Nnzx7AUyHlm2++YceOHQ2Ea2BgIPHx8U1+dnOguVw1ls6Dcw7GO7DpdDqpr6+ntrZWkiTMZrNPtbKmwDtAvH//fj7++GNKSkpITk6W5WcGDRpEWlraRdFfWwrCOhBdT1999VXS0tJ4+eWX5cXiy7EKy+jgwYN89913fPfdd7IuW5cuXQgICKCkpEQy9rp168aUKVNIS0vzOQnB23W8detWVq9eTU1NDZGRkfIwFxYWUlVVRVhYmGQ6/s///A+RkZEtpgw5HA7ZzXTXrl2cPn0anU4nyQebN2+WjLE//vGPAEyfPr3F6ioK4bRnzx62b98OeASHyWSiXbt29OjRA0CW/fLH3ne5XLIo9N/+9jf2799PbW2tFOKCieltDdx9991MmzaN+Ph4n7Md7Xa77BW2bNkyNm7cyJNPPimtlcvpORHpFfv27ePEiRPSLZuVlcWqVaukgAePK3LWrFlMnTr1V4teXwBN/qEqSUKFChUqVLRKXBEWFJy7FXNrsUIaQ9A1hTvB27d8ucfsPY82m41Fixbxz3/+U9YGDAwM5KabbuKTTz7xiwYuni8KaJaVlfH1118DHldG+/btMZvN0qXQoUMHSa/1x9x559MUFRVx+vRptm/fLvOJrrnmGlJSUujSpYscU1NjAU2FyNkS48zPz2fr1q3S5bh7925cLhe9evWSNeWio6NbZGyKolBTU8Nnn33GO++8I11qRqOR0aNHM2PGDFkLs6U8B4IUIGr0AbKNhHerj8ud33c5IebI4XDIvVVaWsqHH35IZmamrHB+zz338MADDxAWFtactWv6B68UAaXCNxCCE+D48eP89re/JS8vj0GDBgEet0f//v2Jioq67MK0JWGz2dBqtTidThwOh8z4F3EEnU4nL7TLPS/C5S2IQyK+4T3GloLb7ZZtK1544QVJVLj55pt59913adOmzX+1ILgS4S0TfLTXVQGl4tLhHdvzddmnKw3nOweCYv7fOCeXAqfTSXZ2tiSd+DPepOKKgyqgVKhQoUJFq4RKklChQoUKFVcXVAGlQoUKFSpaJVQBpUKFChUqWiVUAaVChQoVKlolrohSR02F0+lEq9VKhlZLNQRUoUKFChXNx1UroGw2G0uWLCE+Pl72YxLUVxUqVKhQ0fqhuvhUqFChQkWrxFUloNxuN/X19dTX17Nx40ZWr17Nf/7zHwIDA8/ZXVPFz/BO2m1taM1jU3HlQ+wvdZ+1Plw1ibqKolBWVsYnn3wCeOpKderUiVGjRsmePa2lVE1LwrsKvOirJVprVFZWcujQIVatWiV79tx+++088MADhIeHX9aYnRijxWKhsLCQ4uJiUlJSZF03NZ6owhdoLJS8q4Y0RaEVdTjV/dkAaiUJu93Opk2b2Lx5MwBpaWmMGDGCsLCwi95ofqhB1eB77XY7bre7RYuNehfLdLlc1NXVkZ2dDXhaXmRmZpKTkyOLxdrtdpKTk5k2bZpsDRASEtIiYxUQ7QDAI6hyc3P54Ycf6NmzJyNHjgR807fnUsck2hKcOHGCiooKYmJiZDfU4OBgAgICZFdUgcYFg69kiMvXZrPJdgxOp5Pjx49z6NAhkpOTZQuc2NhYQkJCGjRXbI1zIHqhCYXIYDDIOofiNb1ef9ENUK/0sliN5cHlrsV3VZAkFEXBYrGwadMmjh07BsDkyZMvSTj5C06nkwMHDgCeQqylpaWMHDmS999/H0D2QvIHRKVpgLy8PHJycjCZTLL3zZAhQ7jllltwOp2yl9WyZcv47LPPeOyxx2R/nTfffLNFewtVVFTIxncxMTEkJyezc+dO+VtaEsJtvHbtWtkQb9euXWi1WoKDg+nYsSMA7du3p2vXrowbN05WEjcajbhcLp9U8RaX5c6dO8nOzqZfv3506tQJQFbpbtxp19cQdQmdTqes9v7ZZ5+xcuVKampqsFqtch+ZTCaSk5N57LHHGDJkCOBZy9ZmWbjdbux2u5xfnU4nrSoxl3q9/oKCRxTu9f68wKUqKEJAelty3t2mvdGc9Xa73ZSVlbFmzRoAVq9ezcaNGykvL5fr1LNnT95880169+59WdZODcqoUKFChYpWiavCgnK73WzdupXMzEy6desGQMeOHS+79eR2u/nhhx+44447AGQrgkWLFpGYmAjACy+84DfNpKqqimXLlgGwdOlSYmNjefLJJ6XWf65q02lpafTp04epU6eyaNEiAP70pz/J8fobNpuN+vp6EhISAI/2Kv6Xk5PT4q7RwsJCZs6cyXfffSdbcOh0OlJSUhgyZEiDmJjT6WT79u3ExsYCHquqbdu2zQ6822w25s2bB8D7779PTEwMpaWlpKWlAR5LTbjXhDvWaDT6Zf/rdDqMRqO0lDZv3szJkycbuMkAamtrKS8v59FHH6VXr14AfPTRRyQlJfl8XG63u8nxImEZic87nU55LsRrLpfrvB4Et9uNxWKRnhDvfmeNrShvS0i81tjacrlcnDlzhp9++omePXsCHitGtFLxtvSa4zp2u90cOXKEZ555hoyMDADZgdjhcMjfu3fvXiZPnszq1avp3LmzHHdL4aoQUHa7nfXr15Ofn89TTz0F/HqM4lwtJtxuN263W77WXKGhKAq5ublMmTJFCiaxoWw2G++99x4AU6ZMoWvXrs161rngcrlYsZTUZhMAACAASURBVGIF//rXvwBPX6O77rqL5OTkX/1tOp2Om2++mbS0NBmrysjIoEOHDn7fmOLQxMfHN1g/q9XK6tWrGTVqVIu4Gl0ul2xd/rvf/Y68vDzZTBE8Ld+nTZtGaGhog0ssMzOTjRs3yjho9+7dSUtLk722mjqWb7/9lpdffhnwuITHjRvHuHHjpKv25MmTfP7552RmZpKcnAzAU089RVxcnM/XTKPRSIEIMGbMGIqKiqivr8fhcMgL1G63Y7fbqa6ulgScNWvW8NBDD/lcQDX+jeJ8e7vlhDDw/rt4XavVShedECLe7/+1litarfYX7eLF+8V3ajQaeb+Isyda0Gs0Gtkw0O12c+LECZ577jnq6urk6x07dpRt6r1/Q3PuKIvFwsMPP0xmZqYc/9ixYxkxYgR1dXVs3boVgHXr1pGXl8ezzz7LggULgJYlKF3RAkosVnFxsdQ4unfvDlxYyntrLiL4KzYS8Att51JRW1vLyJEjqa6ult8TERGBoihUVVVRUVEBwL333su2bdt8evEqikJdXR0rV66UmzwuLo7+/ftf1OYyGo089thjPPzwwwB88cUXjB8/HpPJ5LMxngu5ubls3ryZBx98UL6mKArLly/n2LFjDB061O9C0ul0kpGRwaRJkwBPB9ugoCAmTZrEQw89BHgEj0j49lZounTpwtKlS9m9ezfgsWBHjBjRrAv5xIkTvPTSS5KUMGnSJO655x4CAgLks5OSkjCbzWzfvp2ffvoJgPDwcJ577jm/zJeIvwHcf//99OrVC7vdTklJCVlZWQD89NNPHD9+HLvdLveg9/nyNbzPs9vtpra2Vlre8DP5oTHDzvvsizE2ZvFdyFLx/rsYh4hFeY+nsrJSkn80Gg1xcXEEBARQVFQEQH19PV9++SXFxcWkpqYyduxYwLOW4nf44p5wu928++67ZGZmotPp+OijjwC47bbb5LjvvfdewLO+y5cvZ/PmzXIPNhbI/sRVIaD27t2LzWYjLi5Omtrn21DerB1vlo7BYECr1TY4TE2Fy+Vi+vTpkhknmF6TJ0/mwIEDbN26VWpXhw8f5tixY3Tp0qXJzzvX87ds2UJ1dTU2mw2AG2+88ZIEjM1mk26c3bt3c/LkSZ+O0RtizufOnUvfvn0bXCAOh4OCggL69u0rW677C263m5ycHO69917ZutxgMDBmzBhmzJhBmzZtAM9+acxMUxSF06dP89VXX8k5HzBggOzI2xQ4nU7Gjh1LXl4e48aNA+Cll176xQVhNptJTU2lpqZGPltYgP6CuLwjIyMZNmwYACUlJfTo0QOAAwcOkJub2+DyT05O9pvbXVEUuY9OnDjB4sWLMRqNDB06FPCwCgMCAiTLEDxrJxij4uLXaDTo9fpLHmdjr4xGo5FKjNPpJCAggJqaGnnJ19XVERoaSnV1NcePHwc8d0FtbS2TJ0/md7/7nVQCfK1kWK1W5s+fj8PhYPTo0dx2221AQ69TUFAQgOysbbPZJHGpJQWUSpJQoUKFChWtEle0BSW0xeXLl9O5c2duu+22C+bHKIqC1WptQGUOCAggKirKZ5pBYWEhn3/+OW63G71eL83lRx55hM8//5xdu3ZJV4fD4WDHjh0XjA1dCtxuN7m5udhsNum7Hjx48Dnpr+eC0+nkm2++kWOsr6+Xc+0PiBid2Wzm5ptvbjCu+vp6CgoKGD58+EXnojQFiqJQX1/Pc889R35+vtSge/bsyeuvv05kZOQvrCbvOEV5eTkTJkzg7NmzUksPCQlpUs6bmPdZs2aRm5tLSEgIf//73wEauPYEDAYDbdu2beBWqq6ubjJ54FIgrASHwyHdjADZ2dnY7XYURSEmJgaAXr16+WU8wk135swZAN5++222bdtGQECA9FQMHz6cbt26NSgeLdJTKioqpKWr0+nk/F9Kwu651tibpq7VauU8AISFhbF792727NnT4DMDBgzgzjvvPOc6+woWi4WioiJ0Oh0TJ0781XvHarXKOJ2Y35iYmBYjSlzRAkrEcex2O2lpaaSnp//qxCmKQnFxMXv37pVsFfBUVLBYLIwcOVKyspoSbxEbe/r06VRWVqLRaOjSpQt//vOfAc+FFRMTQ1hYmDT1tVotx48fx+l0+kxAabVaamtrqa6ubpBnJQ5y4/c2/g25ubnU1NTIOQgKCvJrsq5gx40ePZrQ0FDpegE4dOgQRqORAQMG+PWydTgczJ8/n02bNqHT6SQJYP78+URERJzz2SKPBKB///6cPn0ajUYjlYJbbrmlSWMWruHXXnsNl8vF8OHDZTWU812E0dHRBAUFUV9fD3hioL/GPvMVRFzJYrGQkZHB0qVLAaSLNDAwkOeeew7gvPPYXCiKwtmzZ3n77bcBWLt2LXa7nRtuuIF+/foBnrih2M/i3FdVVXHw4EHMZrMUtNHR0ZSXl6MoSgNFozkQF7x3EndeXh7ff/8927dvp2/fvgDccccdDB482K/CCTyuvKCgIGprazl8+LB05QcGBsr1zM3NBWDDhg0oioLBYGhA8FAF1AXgdrvZtGkT4LlA+/Xrd8FExdLSUl588UVKS0u57bbbuOGGGwAoKipi9erV5OTk0L9//yaPSVQa2LRpE4qiYDQaufvuu2XswuVyERUV1UD4OZ1OTp06hd1ul9afLxY/JSWFkpIS+XsqKytxuVw4HI4GjCVBqRVWzOLFi6murqZ9+/Yy4G0wGPwmoLyFpqBnu1wu8vPzAfj3v/9NWFgY7du3/wWzypew2+2sW7cOm81GbGwsr776KvCzttg4CO9yuTh16pSsbJGXlwd4Dvl9990HwLXXXnvJAkJRFHnR1tXVodVqGTNmzAUvh9DQUJKSkqRgEONsCSiKQmlp6f/H3nmHR1ml/f8zJZNJb5BJAwIJSeihhA4iLEgVFRQbKyqsoviKlLUtFtB3fVdcd1ldVsWCBcSGCyKR7oJK7y0hmE4KSUjP9Pn98fzOYSZEpMwk4M73ut5rfUNgzjzPOedu3/t7s337dkpLSwHlEnQ4HNx0003ccsstgHsK/E19dlVVFU8//TTp6emAsn/69OnD3XffLRmyYj3l5eUcOnQIgJUrV1JVVYW/v780EuHh4ezbt4/k5GRZW+vcufOvkiR+DYL9KO6CI0eO4HA46Nq1K0OHDgWUaD0oKMjjl7+fnx833HADn332GW+++Sa5ubkALFiwgMDAQHbv3s2CBQsAJRsEipEW76851YeuWwNlNBql0kFubi7dunX7xQhEeAjz589nz5493HHHHYwbN06m9AICAqisrCQ9PV32+4iNdDkQ3fWgXP4RERFMmjRJvtDa2lqOHTtGeXm5S5rhzJkzMqJyF+x2OyEhIdLoFRYW0rZtW8rLy8nIyACUw6jT6SgvL+fTTz8FFGM9Z84ckpOT2bhxI6B4nKWlpbRq1cqtawTl+4v0odFoJCIigtOnT/Pqq68CSrF/4cKF0qi7+/A6y1CJYjUg1T/i4uJkT9bZs2cBKCoqIjc3l2eeeUZeyKDIHb355pvceeedAFc02qW+vl5GIXa7HR8fHxITE5u8FJx1FisrK116b/z8/DCZTDLF6CkZL1D2ekxMDDfeeCPZ2dmA4gz6+/szefLkXyUuXQ2sVisffvghq1evludcr9djtVpZvXo1e/fuBc6ncL/99lsyMzMB5Tzq9XqCg4M5ePCg/JnFYqF79+4yiu7cubNbogaNRiMdvZtuuokePXqwZ88emUFQq9XN0rup1Wp56aWX2Lx5M4WFhbLHbsuWLfj6+lJRUSHLHyJN7Kno99fgJUl44YUXXnhxTeK6jKAcDge5ubkUFRUBSmrIZrO5pMkETCaT9Gj379/PoEGDuOeeewgNDZUeUVVVFUVFRXTr1k2qLFwJhAabKOYbjUbeeecdUlNTAYXMsXv3bpliExCNgu5KXwnKc21trYxOjh8/TlVVFVVVVbIXo76+nujoaE6ePCl/9sc//pGBAwdSWVkpvb3CwkJqa2s9knt2OByyZmO1Wjl8+DBffPGFjI5VKhXjxo3zWC3FuY/JbrdjtVopKiqSDc4rVqzAZrPh7+8vte9MJhM//vgjFRUV0qsMCwvjz3/+M3ffffdV1RKzsrJkqljUsw4dOiQ/W6SxRUQASmS3bt06srKy5N4SlHNR2xQtFQ6Hw+39bCqVCr1eT0JCgqxdmEwm4uPjPUotByXyFdGPgMPh4OTJk2RkZMjoRPQ/iVQ2uNZfRcQgno3ZbJbKCaKp1h0Q+02n0xEdHc2JEycksWT06NHNVtuJiopi06ZNzJgxQ2ZUrFYrDQ0NWK1Wl3X4+PjQt29fSfJozkjqujVQOTk58kEFBARw+PBhysvL5YbU6/VUVFTwt7/9TR6aiRMn8uKLL0rjJHL0JSUlDBgwgPHjx0vjciWXsfi7ycnJnDp1iqqqKpYtWyaNppCfCQwMdEnpRUVFufXSUKvV9O3bl08//VSmoOrr67Hb7cTFxdGxY0dASfGJ4q14lqLvwZkBplKp5AH2BES/h8lk4tChQ2RnZ8tC9tixY2UfmSfh5+fH4MGDOX36NCaTSRrs/Px81Go1vXv3lgSa9PR0SdARh/aNN95g3LhxV010iY6OZtSoUQD88MMPJCQkUFlZyTvvvAMo5AOR0hPPpU+fPrJvTTg5JpOJ4uJi/Pz80Gq10nB5kjRRXFxMTk4OoFx2vXr1IjY21qOf6ePjw4wZM8jLy5OpO0G0EWQHON/zpFar5VmLjIwkOjoavV5PWFgYoDQ922w2JkyYINP8njAa4oxt27ZN7qXm7C9SqVQkJiayceNG6RAVFBRw8uRJ3n//fX766SdASe+HhYUxfPjwZp9qANepgbJardTW1krViIiICFq1asW+ffvkPKi8vDzpPf7pT38CYObMmfj4+EhPWXiVNpuNm2+++arlfISBWrJkCW3atOGrr77CbDbLjd6lSxf69OnDqlWr5KZUqVRNjmm4WsTExBAWFiaL5iUlJfj4+NC7d286dOgAKIah8Wc61ytEDUWj0bjUWtwJjUYjn5vBYGDIkCGkp6dL43jXXXc1i8fm4+PDnDlzaN++PRkZGTI6MRgM9O3bl8TERKlmXlpaikajISAggMcffxxQvN8rqTk1RqtWrWRn/+nTp3E4HAQFBclL5MCBAxw8eJDU1FQGDx4MKAy1c+fOsWzZMvl7dXV11NfXo9Fo5P+BZwvcP//8s4zYhVKCc6bCExDe/apVq+Q78/X1paqqipMnT/LBBx8ASt2wvr6eqKgoRo4cCShEom7durnUV4QBczaqnli/w+GgsrKSoqIiqVUoHLXmhFarlRmMwMBAIiMj2b59u1RD0ev1xMfH07FjxwvUU5plfc32SW6E1Wqle/futG3bFlAuY0EVFV6I8JJ+97vfMWXKFEB5GcI4OTOcRH/G1V4wYpNHRUXxf//3fzzxxBMUFBRIcoHBYMBoNLJr1y6XtIRGo3F7BBUfH8/cuXN59NFHAUVPb+LEifTt21cehItd/L6+vvJSq6urY8eOHUyZMsUjOlxiHVqtFn9/f+rr62Une9++fd3+eU1BpVIRGxvLjBkzsNlscn+IC33dunWsWrUKUNI/QUFBPPnkk8yaNQu4sraEpqBWq+V3F6oMzkalc+fO3HXXXTgcDnmJCj248PBw6UgYjUZatWolSRKNe7g8AWdZL2FYPe1cCMWG1q1buzwng8FAeHg4y5YtA5ToLjQ0lLFjx0p1iS5duriogjQnhO6ezWbjkUceATwb3V4KVCoVhw8fZv369TLDEx0dzbhx4zAYDC3ynLwkCS+88MILL65JXHcRlChYarVaOVpDq9XK/h6R9hgxYgRFRUX07t1bkinq6uqw2+0YjUYiIyNlI57Q4XOXhyC8OkFRdv53dTodrVu3dhGljYiIcKunqVKppCq5GJnx/fffM2DAAIKCgppUe27890VtSvyeoA97EsKrLCkpoV+/fkDz5+V9fHxcajZGo5Hs7GwWLFggRT2DgoJ49dVXuffeez2a9vilqKepKFaj0RAXF8eJEycAJW0tIpjm8HytVisZGRlybWq1mvDwcMxms0uk11h41Z19bc7/htlsZvbs2WzevFl+dp8+fbjzzjslmcmTqty/lEoVP29oaODo0aMEBAS0yBiLptZUV1fHK6+8wpkzZ6SyRqdOnejQoYNs4m1uXHcGSlwiBoPBRS6ooaGBiIgI7r33XuC8PE92drZsOK2srCQgIIABAwa49Ah5aqM2pYKsUqlkUycoxrFjx46/qph8JVCr1ZJB2LVrVxoaGigtLZWXr1BTbvz9hRyUmGBrt9spKyvzeIOe2Wzm888/p6GhQaqJN/ehEClgQbbJysrisccekyM3QKll3nvvvc0+dv7X4JxiCw4O9rgigYBw+ux2uyRu2O128vLyKC4ulpddU/UdZ7iDvQrK2b///vtZv369/KxHHnmE559//oqkpy7lcxsb3cayYuDaOF1XV8fp06dp27atdHKaU6GhKeTm5pKXl0dAQICcNda7d2+ZCm0JXHcGCs7n3EVRFJQCn8jdA5K2nZiYKF+6r68ver0enU7ndlLC5aw9JyfHxXPs1auXx3L14jsKqZKzZ8/K5kWDwUBaWtoFI8nr6ur4xz/+4WJI09LSPGagBFklNzeXo0ePSmX65oZ4Bjk5ObJ2kZ6eLplpKSkpAMyZM+eaM06Ai5drNBqbZW6PGCVx6NAhLBaLvISNRiP79++nTZs28l2GhoYSHR1N69atXXTuhIL41UI4Xh9++CGbNm1CpVIxf/58AJ566im3kFiawsU0LeF8M7pOp5NrFDJUMTExv7qups6dO+8usaadO3dSWlpKVFSUZPr26dOHmJiYFhn3DtepgRIprIvRHsVLFQwV57/bkrBYLC4GSqfTSZ01T0OtVtOhQwdJLqmsrKSiosKll2T37t189913nD17VjKyAgMDSUpK8pgXJYxzSUkJmZmZ2Gy2C95bc8HhcLBlyxa++uorQFEHcTgc+Pn5MXPmTODKVEaaA84yR3q93qMRr7MCx8mTJ/n3v/9NcXGxS5SQlZXFF198IVPxw4YNkwLKYm9FRka6TQRYfPbevXtRq9XccsstPPXUU8CVqXpcKZx768S61Gq1VAYBpSyRmJjoQkZqjMbvr7EiiLsgmJ9vvPEG9fX1GI1Gef4SExMJDAxssenkXpKEF1544YUX1ySuywjqUtDSkdIvQYzFdq4VNLd356zcLEZTi9rB0aNHcTgctG3bVnqkd999N4899pjHnqnwztq0aUPPnj2JjY2V49Wb+z06HA4yMzNdGpP9/Px47rnneOCBB1zWe62hc+fOHDt2DFAyB83x7CwWCwUFBdTX11NSUuKS+qypqcFms0lNO6EPqVarZeuFr6+v24gcghotRtwsWrSoWc+WM0SWR/y3oLOLvePv78/gwYOJjIyURKCm6tXQ9Ah7d6KsrAxQ+tgEOUqI7EZHR7dYeg9+wwbqWoXISzurYLRk/4M4PILZ9MILL/CnP/3J5TA1Ry8LKF38H3zwgcuo7uaGSqWiU6dOMn0cFhbGokWLuO22267JupMzQkND5bsS+8zT0Ov1DBw4kNjYWIKDg+WEgfz8fPz9/enQoYO84Pr3709AQAAqlcoj4r/ic2bPnk1sbKzLqJnmhnMqTvQ5Ov/Mz8+PNm3auKi4OKfwnI2Rw+GQMm6eMFDODc46nY6wsDBJkvDz82s2JmhTUDWndPol4JpajCdgNBrp1auXbKj88MMPGTt2bAuvygsBm81GQ0ODpGt37drVI8wvT+Cbb75hyZIlACxbtoy4uDiPOxfOF6rFYpEKKUePHqVnz54EBwe7jFP31LgUcGXJtWSU+0t3alNMv8Y/bzzaBc5/F09FUKIGNXz4cAAWLlwom5ndNALoiv+y10A1MxwOB4WFhbIwHBERcV1cfl5c+zCbzdIbFnp0/017y3kSbkt+b2FInMehOPcVOv9eY2PkPBVZ4DfwDq/4C1ybyXQvvPDCCy/+6+GNoLzwwgsvvPAkvBGUF1544YUXvy14DZQXXnjhhRfXJLwGygsvvPDCi2sSXgPlhRdeeOHFNQmvgfLCCy+88OKahNdAeeGFF154cU3CK3XkhRdeeATNMd9ItMkIxXBn/AYaXP/r8ZswUA6HA7vdjsViobi4GFBGN9TX11NQUCB11bp06UJQUBD+/v74+vrKznOh/eapDS100Wpra8nPz+fo0aNERUUBihhjaWkpBQUFUl7nyJEjWK1Wfve73/HII48AyrgATx44T0rQXC7E+4TzqgB2ux2TyURlZSWgjAAJCgq66vUKgVGhdSb2kZgBFR8fj1ardbn8NBpNi80Tu1bgLHFktVqxWCyUlZVx6tQpAH788UdsNhsjR46kV69egKLb524JIpVKhc1m+1Wh1at5V00ZP3fCeY1CWcJms1FbWwsoWnlBQUH4+fldtvhtSw9BvFr8Jhp1HQ4HdXV17Nu3j61btwKKgRIaamJOjk6n49y5c3IMtZg2e+utt9K+ffuLTvu8UlitVgoKCgA4ePAgeXl51NXVuQiP5uXlcfz4cX766SdAORAGg4GZM2dKAxUYGOjWdYm1nTlzhg8++EAqGvfo0YObb76ZsLAwFzXm5oAQxczOzpYGqkOHDqjVaqqqqli+fDlbtmwB4IEHHuDWW2+9KqVlu90uDV5NTQ1HjhyhurqahoYGDhw4AEB5ebl0dsRzGDNmDL///e8vqkTtSQgD3ljDrbnXAIqaeW5uLlu3buU///kPx48fl3+u0+mwWCz069cPgOeffx6DweCRdTrfY42NU+OfXy5sNpucY3W1a3ce6FhYWMj27dvZs2cPAOHh4Rw9epSSkhIKCgooLy8HFOcpJCSEZ555hjlz5gBXpzUonDCbzUZ1dTUWiwVQFPA9NPvJ26jrhRdeeOHFbwvXdYpPeCP19fW8//77vPbaa/LP4uLiiI6ORqVSkZWVBUBRURFVVVXSY/j+++8BRVJ++vTpbh/z4HA4OHfunPycoKAgBg0aRFRUlBw3oNfrqampYfXq1ezfv19+r/vuu49Zs2ZJD92dEJ5lQUEBN998M1lZWTISadu2LZmZmYwbN06mZvz9/ZtFHdrhcLBnzx7+/ve/c+uttwLKRE+NRoNWq2X79u0cPXoUgAMHDsjfuRLY7XbMZrNUlf/mm2+wWCx06tSJ+Ph4OQXWbDazdetWtm/fzunTpwFYuXIlhw4dolu3bsyaNQvwvOiv8wTbrKwstm3bRrdu3QBlD1mtVhISEuQk1MYpYXFWHA6Hy4iHK4X4986cOcOHH37Irl27KCwslPvaYDBQVVVFSUkJ69atA2DSpEm0atXKI6NUGj975zTxxX5HRJ4Xe3cqlYqSkpKrmnztcDgwGo2sWLECgOXLl5Obm0t9fT0NDQ3y93x8fOToG1EasNvtnDt3jldffVVOdQ4ICLjsNYgpxgcOHGDv3r388MMP7Nu3Tz6niIgI+vfvz6JFiwgODr7i7+pOXNcGShiaNWvW8Omnn1JVVSU3Wl1dHTU1NRw8eFDmcm02GxaL5YLQX6fT4evr6/bhZiKE7t27N6Bc/k1d9lqtls6dO8shbgMGDOCpp55y2yjsxjAajQDcc889nDhxAofDIS+2wMBAjhw5QmlpqbxIevbs2SwjJyorK1mwYAGlpaXMmzcPwGXQW25urqwZpaamXtUlq1arZd0JYOTIkYSHhxMWFoaPj4/LLKxBgwZhsVhkOvDUqVNs3ryZ7du307FjRwCmTJnisRlWwtEBePbZZ/nqq6+oq6uTxiAiIoKkpCRiYmKkmnl4eDixsbGEh4djtVo5cuSI/N0HH3yQ+Pj4q1qTuNR++OEHvv/+e0wmEzExMUybNg1QLtAVK1ZQWFgoz99HH33EwIEDPT7rSxgnm812wfw1UM4lKPeHyWTCz89Pzo4SdSCr1SrPyWeffcZrr73GoUOHruhMOhwOamtrWbJkCW+88QagnEExE0o4SVqtlq5duzJ9+nSSk5N55ZVXAPj0008xm81YLJarmknm/Ay2b9/Ozp07qampkeM28vLyOHr0KLt27ZJORXh4eIvWsK5bAyUKiQCnT5+mpKTEZUhbSUkJJSUl1NTUyBcjLh5R9OzevTsAQ4cOlYV4d0YKNpsNf39/6RH5+fnJSMU5h19SUsLixYvln7344oseM04Wi4Wnn34aQOa+O3bsyHPPPQdA7969OXToEN999x3fffcdoFxGaWlpHhuYJhyNRYsWceDAAeLj4+natSugHCoRWRUVFREbGwsoBuVq1xIUFCQ9UfHuf2k4m1arldGswWAgJSWF4uJiduzYASh1TE9dvDabjXfffReAzz//XO5psVf1ej0ajYbDhw/LeqvJZCI4OFg6SVVVVfJ77Nu3j2+++eaq6xgA2dnZBAcHY7fbGTp0KEOHDgUUB9HPz4/a2loZITjXFj2BxsSNmpoaORk5KCgIs9mMWq3mzJkzAOzcuZOsrCwMBgM33HADoBhWjUZDbW2trAEdPnwYg8HA2bNn5aTny4HdbqeiooJTp04RHR0NwODBg5kxYwaRkZHS0QDFWRaO8ksvvQQoz23v3r0kJSVd1TsT+zoiIoLExEQKCwspLy+Xe0Nkl/bv38+QIUMAJbPQvn37FjNS162BgvOHxGKxSJaXcypEq9USFBQkvcWePXuiVqv5+eefCQwMlF56SkqKyyZxBwQbx2QySe9MGEe73U5eXh4Au3fv5r333uP06dPcc889gBJpeQI2m40333yTt956C1CeX0JCAunp6cTExMh1h4aGolKpWLlyJQDFxcV069bNIxNlHQ6HTNutWLECm83G1KlTXQy01Wpl8eLF2O127r77bsA9pBHnsdyXMzVUTCE+duyYfCaenGBbWFjIBx98AJz3vHv06MGoUaMAiI2Npby8nIKCAnn5BgQE4OPjQ2FhiwuCXAAAIABJREFUoUsax2w2c/bs2au+cMRFmZCQwIkTJ7Db7SQlJcl/Nzc3l507d1JbWysNd0JCQrOMYHc4HDQ0NJCdnS2ZsT/88IN0YkWqNjQ0lMTERNq3by+jmKioKDp27IhWq5V7sE+fPoSEhFzx/ler1RgMBl5++WXp5AQFBf0iE9Rms2E0GmVkExMTQ0pKCvPmzbsqUpB4ZwaDgccff5zbb78ds9ksHYgVK1awbt06ysvL5f30yCOP8Oqrr9KlS5cWGQLpJUl44YUXXnhxTeI3EUEJurAz59/f35+wsDAGDRrEE088ASgenKAxh4WFyV4kT6SuHA4HBQUFHD58mB49esifmc1mjh07xurVqwGFuGE2m3n00Udlwd1T47APHjzIs88+K4ulAQEBLFy4kOjoaBfPLCgoiKqqKk6ePAmcL3h7onBqs9lYvHgxoFC9o6KimDZtmsuY6/z8fI4cOUJISAh33nknwFV5kk3hcp65w+Fg1apVnD59moSEBACPpffsdjtr1qyR6SZfX18GDhzI9OnTJYlFo9FQXV1NfX29jARiY2Px8fGhoKCAzz77jA0bNgBK6k/Uia4G4vsOHDiQzZs3U1VVxQ8//CDrTUuWLJEpPZGdeOyxxzwShQs4v8Pa2lpKSkr497//DSi9hWVlZeh0Orl3kpOTeeKJJ4iJiZF729fXV+4955TY1dD4VSoVvr6+krTVeK3OsNvt1NXVsX79etl2UlRUxJNPPsnNN998RZ8vIL5XUFAQQUFBREREAOdrcj169OC2227j73//u+wnDQ4O5uTJk8THx8t0+K99B3fiujZQAmazWdYQxEPv0KEDPXr04NFHHyUxMRFQDpXVaiU5ORmLxSLTDZ4wTkVFRbz//vvk5+fLNENwcDBGo5HS0lJZ9O7UqROzZ8+mT58+bk8zirWAkiaaNGkSDQ0N8vtOmDCBkSNHulz2IgUpGEYADQ0NlJWVXVH+/ddQVFQke9cA/vrXvxIWFibXaLVaefnllzGbzUyePJnIyEjAM4dD1C6sVqv899VqNVqtVv4ZwNmzZ8nKyqJfv3488MADAB5hW4Ly7I8cOSINQnh4ONHR0aSkpBAaGgootdXg4GCsVitJSUmAcumUl5cTFRXF9OnTSUlJAeDcuXMEBARc9fMTf99gMDB48GC++eYb8vPz2bx5MwCZmZnYbDZ8fX159NFHAaVRvjkuNZVKRUhICAUFBdLJEqQfnU7H4MGDAfjHP/5BSEiISz2vKTQ1hv1K1vRL31382zabjdLSUp566ik2b94sjfm0adMYPXq024y7WIdzehuUPqjf/e53DBw4kPz8fLkmPz8/qqqq5O8LhqhzitJTDcHXtYESxXWTyYRWqyUgIIDk5GRAqSuNHDmSuLg4F2KC2AzOrD13P1ij0chbb73F2rVrsVqt8mV36tSJpKQkWrduLYkTbdq0oWvXrh7zLEW09M9//pOioiJUKpX87Pnz5+Pn54fVapXPSHhw4eHh8vmUl5ezc+dOUlNT3fqs7HY777zzjixkJyQkMHr0aEmMAMjKymLjxo34+voyc+ZMj9UwBOnm4MGDbNiwQUYiZWVltG3blurqampqaoDzdNzbbruNAQMGAJ4zmA0NDcTFxUkmaEREBG3btiU8PFwaRbVajU6nw2azSaeivLwcm81GWFgY8fHxdOnSBVCMq1DJcAd8fHxISEhAq9Wye/duyXS0Wq0EBQUxc+ZM5s+fD+DR6MkZDocDi8XC6dOn5f4X9ehJkybx/PPPA0oGoSXqKgKi1UE4PhUVFTz22GNs374dq9UqCRUPPvigVMPxBJz3rkajISAggA4dOgCKg/Tdd99RX18v71atViujd2fFF0/gujVQYhMCtG/fnuDgYKqqqqQiwvHjxwkJCaF3794uBXfxdxrL17gD4mVlZmZy4sQJqqurUalUkj4+YcIEoqOjKSsrk8Vsi8VCaWmpR9JnDodDXkbr168HlCKwSC9269atSc8uICCAAQMG8MUXXwAKrTovL8/tLEez2cyGDRuk0Rk4cKAkkgiK73333UdNTQ33338/7dq1c5s6QFNwOBx06tSJ9u3by5Ta1q1b+fHHH9m1a5e8JMaPH09tba28QDwF0bN03333MXLkSEC5+GNiYlw6/p292JKSEkAxWuHh4QQFBbkY9cbp3KuFSqUiIiKCrKwszp49K9sAfH19GTx4MA888MAFqSFPw2w2s3btWtatWydTjiEhIdx666089thjkmBzOetx99qFM7F27Vp2794NKESOjIwMHA4HkZGRfPTRR4BCkmhuQyqcxm+++YbXXnuNyMhIyax98MEHgabVO9wNL0nCCy+88MKLaxLXbQRls9lkOqG4uJjw8HACAgJknwzAvn37eOmll2TOuXXr1oSGhqLX60lJSfGIVwRKWigsLIwhQ4YwZswYbrnlFgApRlpTUyM99C1bthASEiLrZO6E3W6X4p2VlZWEh4czd+5cl+J6Y90yjUaDn58fycnJMqpzViFwFxwOB9nZ2TLtCApJIjs7Gz8/P5599llAiYRbtWpFv379qK6ult6vVqu9IN13Ne9TpVLh4+ODj48PgYGBMupNSkrioYceoqGhQUajK1eu5Ntvv5WNlnB12mi/BIfDgV6vx9/fX7YBiPqYMynDWZtPqB3odDpJnW/8XAwGg1vXuW/fPvLz82WfESi9WSdPnuTrr7+W5B9PN+iKfXr48GFefvllCgoKZLSYkJDApEmTiImJuSbEUx0OBwcPHuTPf/4zP//8M6CsX6/XM3z4cJ577jk6deoEeGZvXQwNDQ38+OOPgEJ2ycnJQafTMX78eEA5E54U13bGdWegRLG6rKxMNpgNGjRI9jOIl/nDDz+wYcMG0tPTZarKZDIRGxvL/PnzZU7enesS/QRnzpxh/PjxDBs27ALFbaHaINhf//znPzEajYwZM8btOXq73c7evXsBZdMlJiYybdq0JkVgG282tVot+7c0Gg3+/v5u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\n", "text/plain": [ "
" ] }, "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", "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})" ] }, { "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/UCwAAGgRJREFUeJzt3XmMXWX5B/Az7dBVlpYKDbE2sYEWE6kKSihLbAbRQl1oGxbZTI1BWohoVLSISisNUtIopo2KEhUQtzYaYyLWAiqxpqIFI7FlJ2WnTAuFbnT5/fdL3/dc586d524z9/P573s559zjcubLmWfec7oOHDhQAMBADWv1CQAwuCkSAEIUCQAhigSAEEUCQIgiASBEkQAQokgACFEkAIR0t+A7LaUf2rpafQI0let5aOvX9eyOBIAQRQJAiCIBIESRABCiSAAIUSQAhCgSAEIUCQAhigSAEEUCQIgiASBEkQAQokgACFEkAIQoEgBCFAkAIYoEgBBFAkCIIgEgRJEAENLd6hPoNDt37ix91tvbm+TNmzcn+Ywzzkjy+eefXzrGZZddluQzzzxzoKcI9NP+/ftLn+3atSvJTz31VJJ//etfJ3nfvn2lY3zoQx9K8rvf/e4kjx49urRPV1dXn+faSO5IAAhRJACEKBIAQhQJACFdBw4caPZ3Nv0LW2nHjh1Jvv7660vbLFu2LPw93d3p301cd911feYGat3Ej1YYMtdzpZ+F+SD8tddeS/Kdd95Z2icfpm/atKnPYwwbVv73+be85S1JvuCCC5K8ZMmSqvvUafjer4O4IwEgRJEAEKJIAAixILEG+eKjxx57rLTNWWedleSXXnopyaNGjSrtc/vttyc5/53pueeem+RXX321dIzFixcn+Sc/+UmSFy5cWNpn/Pjxpc+gU+TX87Zt20rb3HXXXUlevnx5kl944YWqxz3yyCOTPHXq1CRXWpD4+uuvJ/nJJ59M8rPPPlva59hjj03y8OHDS9s0ijsSAEIUCQAhigSAEOtIarBu3bokn3rqqTUfY968eaXPfvGLXyR5IH//nf+edc6cOUmeMWNGaZ9rrrmm5u/pB+tIOsuguZ7z2cWLL76Y5BtuuKG0z09/+tMk5w9drfTwxHxOmq/hmjJlSp/HLIqi+MpXvpLk//73v0m+8sorS/vMnTs3yYccckiSB7iuxDoSABpPkQAQokgACFEkAIRYkNiHLVu2JPmcc86p+RhXXXVVki+88MLQOf0v+eKjo48+Osn5HwrAUJf/IVH+JtL8raJ/+9vfSsfIB/T5dTVr1qzSPvni3+OPPz7J+RC80sD+4osvTnL+hwD58L0oimLPnj19fk8juSMBIESRABCiSAAIMSM5yN69e5Ocv6Bm69atSa60wOeTn/xkkr/zne/U5+Sq2LVrV5LvvvvuJOe/H4ahpNLC6vyayF8Gdf/99yd5xIgRpWO8973vTfLs2bOT/NGPfrS0z9ve9rYkV1sYWOnFVkcccUSSn3766SRXeuDq7t27kzx27NjSNo3ijgSAEEUCQIgiASDEjOQgd955Z5KvuOKKJPfnoWdf//rX63pO/fWb3/wmyc8//3yS84c4wlBSaUayYcOGJP/qV79Kcj5TOOWUU0rHyB+emM9MRo4cWdonn7VU+7mRr1UpiqL4+9//nuT8es7ntZU+y1+o1UjuSAAIUSQAhCgSAELMSA6yffv2JFf73Wb++9KiKD+Lp1m2bduW5HPPPTfJP//5z5t5OtBUb775ZumzO+64I8mvvPJKkg8//PAk58/FK4qiOO2005Lc3Z3+yKy0BiT/uVHt5YH5+rWiKIrf/va3fW5z6KGHlvaZMGFCn9/TSO5IAAhRJACEKBIAQhQJACGG7X3Ih2T5i63yBYxFURSjRo1q6DkVReXh3Q9/+MMkT5kypeHnAa2SXwPPPvtsaZv77rsvyfnL384+++wkf/CDHywdo9bFhf2Rn3v+Rz5FURQvvPBCkvOFj+eff35pn0oD+GZxRwJAiCIBIESRABBiRnKQ/PeS48aNS/LNN9+c5HxBU7PceOONpc/+9a9/JXnGjBnNOh1ounzO8Pvf/760zZNPPpnkfPHgzJkzk1zpAYzVvreSWh/S+Pjjj5e2yV/KNXXq1CRfffXVpX3yGVAzuSMBIESRABCiSAAIMSM5SL4WI183Mm3atGaezv/LX1q1bNmyqvtcdNFFjTodaLn8IY3Lly8vbZPPGfKZ50knnVTz9/ZnHUm1hzbm5/XLX/6y6jEvv/zyJB911FFV92kmdyQAhCgSAEIUCQAhigSAkI4dtm/cuLH0WaWHp7XCww8/nOQLL7wwyZUWTv3nP/9J8vHHH1//E4M2kV+rL7/8cmmbfAFiT09Pko899tgkV1rQV21wXmn4nm+T/2HA9773vST/+c9/Lh3j1FNPTXL+M6AeD4+sJ3ckAIQoEgBCFAkAIR0zI3nttdeSfNppp5W22blzZ5IrvTymEfIFSpdcckmSd+/eneRvfOMbpWO8853vrPt5Qbt65plnkpzPQ4qivGjvi1/8YpLzWeNAFhtWsnfv3iTfdtttSf7ud7+b5IkTJ5aOcc011yS5GS/Mi3BHAkCIIgEgRJEAENIxM5L8xU+9vb2lbebPn5/kWbNm1f088nlHURTFvHnzkvzggw8mefz48Un++Mc/XvfzgsFkx44dSa60BiR/KGP+0NVKc5Va7dmzp/RZPhP55je/meT8xVbf/va3S8d4xzvekeR2WzeSc0cCQIgiASBEkQAQ0jEzkltvvTXJlV5SdcMNNyS50u9da7Vly5Ykz549u7TN+vXrk/z5z38+yddee22S8xf0wFCXP7/qscceS/KIESNK+xx33HF9btOfuUO152b94Q9/KO1z44039nmMJUuWJPnkk08uHaMe85tmGlxnC0DbUSQAhCgSAEIUCQAhHTNsf9e73pXku+66q7TN2rVrk/yJT3yi5u954oknkjxjxowkv/TSS6V9jj766CQvWLAgyYbrdLp8YJ0v7M0flFgURXHMMceEvqMoygsOb7/99iQvXbq06nFuuummJF9wwQVJHmyD9UoG/38CAFpKkQAQokgACOmYGcnkyZOrbpPPTarNSJ5//vnSZ/nLc/KZyOc+97nSPjfffHOS2/0BbdBs+TUxffr0JB922GGlffKHI+7bty/J+Vyl0gMYf/zjHyc5n4nkL8wriqL49Kc/neTzzjsvyfVY6Nxu3JEAEKJIAAhRJACEdFX62+kGa/oXFkX5RTgnnHBCaZv8gWyPPvpokn/3u98l+VOf+lTpGPnvTN///vcn+f777y/t0909pEZVBjydpSnXc/5zauvWrUnOX0pXFOUZZv4Cufy6+8c//lE6xpo1a5Kcz13yYxZFUdxyyy1JHjlyZGmbQaRf17M7EgBCFAkAIYoEgBBFAkBIxwzbcz/60Y9Kn+ULiQbitNNOS/JnPvOZJA/kQZCDjGF7Z2mLP5657bbbStvkiwfzffIFiJX+6CV/2OvVV1+d5I985COlfUaNGlXhjActw3YAGk+RABCiSAAI6dgZyebNm0ufXXrppUm+7777knzGGWckOX9hTVEUxYknnpjkIbbYsD/MSDpLS67n/AGM+eLhoiiKhQsXJjlfDDx27Ngkn3nmmaVjXHXVVUk+5ZRTktwB17cZCQCNp0gACFEkAIR07IyEhjEj6SxtcT3nM5OiKIre3t4kb9++PckTJ05McqWHKw7Fl1DVyIwEgMZTJACEKBIAQsxIqDczks7ieh7azEgAaDxFAkCIIgEgRJEAEKJIAAhRJACEKBIAQhQJACGteCuLBWswdLiecUcCQIwiASBEkQAQokgACFEkAIQoEgBCFAkAIYoEgBBFAkCIIgEgRJEAEKJIAAhRJACEKBIAQhQJACGKBIAQRQJAiCIBIESRABCiSAAIUSQAhCgSAEIUCQAh3S34zgMt+E6ap6vVJ0BTuZ6Htn5dz+5IAAhRJACEKBIAQhQJACGKBIAQRQJAiCIBIESRABCiSAAIUSQAhCgSAEIUCQAhigSAEEUCQIgiASBEkQAQokgACFEkAIQoEgBCFAkAId2tPgGAdnXgwIHwPnnu6uqqeox8m/7s00ruSAAIUSQAhCgSAEIUCQAhhu0BmzZtKn22du3aJC9cuLAp5zJnzpwkL126NMlTp05tynlAK+zfv7/02d69e5Pc29ub5I0bNyb5tddeKx1j3bp1SX7ooYeS/Mgjj5T22bNnT5J37tyZ5DFjxpT2yZ188slJ/sEPfpDkI444ouoxmskdCQAhigSAEEUCQEjXQBbcBDX9C/tr5cqVSc7nHatXr27m6dRV/vvgomjY3KS9V05Rby25nvOZSKX5xuLFi5O8YcOGJD/99NNJ3rFjR9XvzecfI0aMKG0zbFj67+f5PsOHD0/ytm3bSsfIfy5/9atf7TNX+t466df17I4EgBBFAkCIIgEgpGPXkdTjIWgrVqwofdbT05Pkeswh8vUqixYtKm1TbX6Tz3uKwtoSBq98hpCv9yiKorjnnnuS/PLLLyf57W9/e5Lf9773lY5x9tlnJ/mtb31rkseNG1faJ1/jsWvXriT/9a9/TfLll19eOsarr76a5PXr15e2aSfuSAAIUSQAhCgSAEIUCQAhHTtsrzQozwfS+eB8wYIFDT2n/hrIwsh2OXdohHwIXhRFMXPmzCRPnz49yfmDTseOHVs6Rj0W+eWLJ4877rgkv/HGG6V98j8GOvbYY/v8563mjgSAEEUCQIgiASDEQxvbULUFiP2ZkeQzoCbOSNrrl7c0Wkuu5/znVv5gxKIoit27dyd59OjRST7kkEPqf2IV5Od2+umnJ7nSYsP8YZD5C7QmT55cp7OrykMbAWg8RQJAiCIBIKRj15G0s2nTptW8T/438daNMJTl6yhGjhxZ2iafMzRr7UW+buQvf/lLkv/5z39WPcapp56a5EmTJsVPrIHckQAQokgACFEkAISYkbSBfN1INfk8pCiKYtWqVfU6HRgSmjETyechRVEUTz/9dJIvuOCCPvc5/PDDS8f4/ve/n+R6PPOrkdr77ABoe4oEgBBFAkCIIgEgxLC9ySoN1qstQMyH60uXLq3rOQGV5Q+HfPPNN5P83HPPlfY555xzktzb25vkfPHkkiVLSseYMmVKTefZau5IAAhRJACEKBIAQsxImix/SVV/9PT0JHnq1Kn1Oh2gD/v27Uvyiy++mOQrrriitM+jjz6a5Hwx4Wc/+9kkV3rAarsvQMwNrrMFoO0oEgBCFAkAIV3530k3QdO/sJXmzp2b5NWrV1fdJ183MsgeyNictwfRLobM9VzpZ+GuXbuSfMMNNyR52bJlpX3ytSann356kteuXZvk7u62HlX363p2RwJAiCIBIESRABCiSAAIMWyvs/yhjNUeyFhJC/43qSfD9s4yqP/PerBKbzt8+OGHk3zWWWcl+YUXXijtM2bMmCTnCxSPOeaYgZ5iKxi2A9B4igSAEEUCQEhbr4QZjAbyUMYVK1Y04EyAvuSzyEovqbr00kuTvGXLliRXWkz4hS98IckTJ04c6CkOGu5IAAhRJACEKBIAQqwjCVi5cmXps4ULF/a5T/5AxqIYdA9lrMY6ks4yaK/n119/Pcnz5s0rbXPvvfcmOf95efbZZ5f2ueuuu5I8evTogZ5iO7COBIDGUyQAhCgSAELMSAK6umofB2zcuLH02dSpU+txOu3CjKSzDJrreevWrUmeP39+kv/4xz+W9tm9e3eSJ0yYkOSHHnqotM9RRx2V5IH8nGgjZiQANJ4iASBEkQAQokgACPHQxj7U4yVV+XB9iA3WoS1U+qOhfLieLx58/PHHqx7jyCOPTPK1116b5PHjx5f2GeTD9QFxRwJAiCIBIESRABBiRnKQesxE8ocymolA4+3Zs6f02be+9a0k5zOR/KGNhx12WOkY5513XpIvueSSJA8fPrym8xyq3JEAEKJIAAhRJACEmJEcZNGiRTVt3wEvqYK2tH///iQ/+OCDpW3uuOOOJG/btq3PY86cObP02ZIlS5J86KGHJnnYMP8uXhTuSAAIUiQAhCgSAEIUCQAhHTtsr8eD1Xp6ekqf5YsaLUiE+tuxY0eSb7rpptI2L730UpLzAf3EiROT/KUvfal0jHyRouF6Zf5bASBEkQAQokgACOmYGcnKlSvDx8gXIFaakZiJQP3lL5167rnnkrxhw4bSPt3d6Y+30aNHJ/nOO+9M8vTp00vHMBPpH/8tARCiSAAIUSQAhHTMjKTSPCNXbQayYMGCup4T0D/5uq9JkyYledasWaV9nnnmmSRfeeWVST799NOT7CVVA+eOBIAQRQJAiCIBIKQr//vsJmj6F9JU8YeYMZi4noe2fl3P7kgACFEkAIQoEgBCFAkAIYoEgBBFAkCIIgEgRJEAENKKhzZasAZDh+sZdyQAxCgSAEIUCQAhigSAEEUCQIgiASBEkQAQokgACFEkAIQoEgBCFAkAIYoEgBBFAkCIIgEgRJEAEKJIAAhRJACEKBIAQhQJACGKBIAQRQJAiCIBIESRABDS3YLvPNCC76R5ulp9AjSV63lo69f17I4EgBBFAkCIIgEgRJEAEKJIAAhRJACEKBIAQhQJACGKBIAQRQJAiCIBIESRABCiSAAIUSQAhCgSAEIUCQAhrXixFTXq6qr+bpk5c+YkedWqVY06HWi6/fv3J7k/10StBnLMAwfK7/V64403knz99dcn+YEHHkjyjBkzSsf42te+luSRI0fWfG7N5I4EgBBFAkCIIgEgpKvS7/garOlfONhs2rQpydOmTau6z8aNG5M8derUup5TDer/y2vaWfh6zn8G5fOQ//XZwYYPH176bNiwxv97cqXzWrNmTZIvuuiiJO/cuTPJkydPLh1j3bp1ST788MMHeopR/bqe3ZEAEKJIAAhRJACEKBIAQixIbAO1DtdXrFhR+qyFw3Woq0pD8krD9Hawd+/e0mc/+9nPkrx9+/Yk5//5pkyZUjrG6NGj63B2zeOOBIAQRQJAiCIBIMSMpA0sWrSopu17enoadCbQfI14AGOzbNmypfTZ3XffneR80eIRRxyR5Ouuu650jO7uwfWj2R0JACGKBIAQRQJAyOD6RdwQkK8ZKYqiWL16dZ/75C+tsmYEWmPfvn1JvuWWW0rb9Pb2JjlfNzJ//vwkT58+vXSMwTY3ckcCQIgiASBEkQAQokgACPGGxCYbyBCtBf8bRQyuKSFRg+r/nFGPPPJIkk888cTSNq+//nqSJ02alOR///vfSa709sM2GrZ7QyIAjadIAAhRJACEWJDYYCtXrmz1KQADlL+4avbs2UnO5yFFUV6AeNlllyX50EMPTXIbzUMGzB0JACGKBIAQRQJAiHUkdZY/lHHatGk1H2Pjxo1JHmQPaRz8v/ClFkP6es4fqHrxxRcneefOnaV98ocwrlu3LsmjR4+u09k1hXUkADSeIgEgRJEAEGIdSZ2tXbu25n1WrFiR5EE2E4EhYc+ePaXPFi9enOTdu3cnecyYMaV9br311iSPGDGiDmfX3tyRABCiSAAIUSQAhCgSAEIM2wPyxYdFURQLFy6s+Tg9PT31OB2gBvli7AceeKC0zaOPPtrnPh/72MdK+0yZMqWm7+3PNvmDINtNe58dAG1PkQAQokgACDEjCRjIAxnnzJlT+qweCxDzeY1FjZDK5w67du1Kcr74sNI2+QLE8847r7TP8OHDk7x///4+c/4dleTfW2lm0soXZLkjASBEkQAQokgACDEjqUGldSO1WrVqVR3OpLqVK1cmecGCBU35XmhX+WzijjvuSPK9995bdZ8Pf/jDST7mmGOqfu++ffuSnM9qduzYUfV78wc/5nOYoiiK7u7W/Th3RwJAiCIBIESRABCiSAAI6erPA8TqrOlfWC9z585N8urVq6vuk7/9sAOG3q1bFUUrtO31nA+sn3rqqSR/4AMfSPLmzZtLxxg7dmyS169fn+TJkyeX9skH49WG4JXezFhtkWKlNzMecsghfe4zQP26nt2RABCiSAAIUSQAhFiQ2Id8UV9/ZiL5Qxk7YCYCbenNN99M8tKlS5P84osvVj3G/Pnzk5y/tKrSXKLWl1DlM5WiKC9arLaosdJnzXyIozsSAEIUCQAhigSAEDOSPixcuLDmfXp6ehpwJkBfKs0MnnjiiSSvWbMmyfncYdy4caVjfPnLX05yPs+oxxyi0jHyhzLm//lasP6vT+5IAAhRJACEKBIAQsxIDpI/S6ua/DlaRWHdCLRCPu8oiqK49dZbk9zb25vkUaNGJfmaa64pHePoo49OcrPWZuRrUfLvrXWtSqO119kAMOgoEgBCFAkAIYoEgJCOfbHVpk2bSp9NmzatpmO026KgNuHFVp2lJRdBfu099thjpW1mzpyZ5JdffjnJ+Uup/vSnP5WOMWnSpCQ3a9i+d+/eJOcv6coXLBZF9QH9AHmxFQCNp0gACFEkAIR07ILERYsW1bxPpQWIQPPlM4Ply5eXttm6dWuS85dQvec970nyhAkT6nR2tak0a83nHZVmIrlmvsgq544EgBBFAkCIIgEgpGNnJKtXr666zZw5c5LsgYzQHnbs2JHke+65p7RNvhZj/PjxST7rrLOSXOlBiANZK5bPKvJj5P+80myjlfOOgXBHAkCIIgEgRJEAEKJIAAjp2GF7PkgvivIAfunSpc06HaAG+WD8hBNOKG3zyiuvJPmkk05K8vTp0/s8ZlFUH3r3Zyg+2AbnA+GOBIAQRQJAiCIBIKRjX2xFwwz9XwhzsLZ4sVW++LAoimLXrl1Jzh98OHLkyD7/OUVReLEVAM2gSAAIUSQAhJiRUG9mJJ3F9Ty0mZEA0HiKBIAQRQJAiCIBIESRABCiSAAIUSQAhCgSAEIUCQAhigSAEEUCQIgiASCkuwXf6aF+MHS4nnFHAkCMIgEgRJEAEKJIAAhRJACEKBIAQhQJACGKBIAQRQJAiCIBIESRABCiSAAIUSQAhCgSAEIUCQAhigSAEEUCQIgiASBEkQAQokgACFEkAIQoEgBCFAkAIYoEgBBFAkDI/wGFTBgPKf9LcAAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "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[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": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "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.5.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 }