딥러닝의 정석 예제 코드 chapter 6 임베딩과 표상학습 autoencoder mnist
본 글은 딥러닝의 정석(Fundamentals of Deep Learning) 6장 임베딩과 표상학습의
autoencoder mnist 예제와 PCA와의 비교 예제 소스코드를 싣고 있다.
[Autoencoder mnist 소스 코드]
딥러닝의 정석의 예제 코드는 github에서 받을 수 있으나 몇몇 구문에서 오류가
발생하여 수정했다. 학습데이터는 MNIST가 사용되었으며, n_code는 책의 예제와
다르게 입력을 받지 않고, 2로 고정하였다.
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
from tensorflow.python import control_flow_ops
import os,shutil
import matplotlib.pyplot as plt
import numpy as np
from io import BytesIO
from IPython.display import clear_output, Image, display, HTML
tf.reset_default_graph()
tf.set_random_seed(777)
mnist = input_data.read_data_sets("../MNIST_data/",one_hot=True)
# Architecture
n_encoder_hidden_1 = 1000
n_encoder_hidden_2 = 500
n_encoder_hidden_3 = 250
n_decoder_hidden_1 = 250
n_decoder_hidden_2 = 500
n_decoder_hidden_3 = 1000
# Parameters
learning_rate= 0.001
training_epoches = 200
batch_size = 100
display_step = 1
def layer_batch_norm(x, n_out, phase_train):
beta_init = tf.constant_initializer(value=0.0,
dtype=tf.float32)
gamma_init = tf.constant_initializer(value=1.0,
dtype=tf.float32)
beta = tf.get_variable("beta", [n_out], initializer=beta_init)
gamma = tf.get_variable("gamma", [n_out],
initializer=gamma_init)
batch_mean, batch_var = tf.nn.moments(x, [0], name='moments')
ema = tf.train.ExponentialMovingAverage(decay=0.9)
ema_apply_op = ema.apply([batch_mean, batch_var])
ema_mean, ema_var = ema.average(batch_mean),
ema.average(batch_var)
def mean_var_with_update():
with tf.control_dependencies([ema_apply_op]):
return tf.identity(batch_mean),
tf.identity(batch_var)
mean, var = control_flow_ops.cond(phase_train,
mean_var_with_update,
lambda: (ema_mean, ema_var))
reshaped_x = tf.reshape(x, [-1, 1, 1, n_out])
normed =
tf.nn.batch_norm_with_global_normalization(reshaped_x, mean, var,
beta, gamma, 1e-3, True)
return tf.reshape(normed, [-1, n_out])
def layer(input, weight_shape, bias_shape, pahse_train):
weight_init =
tf.random_normal_initializer(stddev=(1.0/weight_shape[0])**0.5)
bias_init= tf.constant_initializer(value=0)
W = tf.get_variable('W',weight_shape,initializer=weight_init)
b = tf.get_variable('b',bias_shape,initializer=bias_init)
logits = tf.matmul(input,W) + b
return
tf.nn.sigmoid(layer_batch_norm(logits,weight_shape[1],phase_train))
#return tf.nn.sigmoid(logits)
def encoder(x, n_x, n_code, phase_train):
with tf.variable_scope('encoder'):
with tf.variable_scope('hidden_1'):
hidden_1 =
layer(x,[n_x,n_encoder_hidden_1],[n_encoder_hidden_1],phase_train)
with tf.variable_scope('hidden_2'):
hidden_2 =
layer(hidden_1,[n_encoder_hidden_1,n_encoder_hidden_2],[n_encoder_hidden_2],phase_train)
with tf.variable_scope('hidden_3'):
hidden_3 =
layer(hidden_2,[n_encoder_hidden_2,n_encoder_hidden_3],[n_encoder_hidden_3],phase_train)
with tf.variable_scope('code'):
code =
layer(hidden_3,[n_encoder_hidden_3,n_code],[n_code],phase_train)
return code
def decoder(code, n_code,n_out, phase_train):
with tf.variable_scope('decoder'):
with tf.variable_scope('hidden_1'):
hidden_1 =
layer(code,[n_code,n_decoder_hidden_1],[n_decoder_hidden_1],phase_train)
with tf.variable_scope('hidden_2'):
hidden_2 =
layer(hidden_1,[n_decoder_hidden_1,n_decoder_hidden_2],[n_decoder_hidden_2],phase_train)
with tf.variable_scope('hidden_3'):
hidden_3 =
layer(hidden_2,[n_decoder_hidden_2,n_decoder_hidden_3],[n_decoder_hidden_3],phase_train)
with tf.variable_scope('out'):
out =
layer(hidden_3,[n_decoder_hidden_3,n_out],[n_out],phase_train)
return out
def loss(output, x):
l2 =
tf.sqrt(tf.reduce_sum(tf.square(tf.subtract(output,x)),1))
loss = tf.reduce_mean(l2)
return loss
def training(cost, global_step):
tf.summary.scalar('cost',cost)
optimizer =
tf.train.AdamOptimizer(learning_rate=learning_rate,beta1=0.9,beta2=0.999,epsilon=1e-08,
use_locking=False, name='Adam')
train_op = optimizer.minimize(cost,global_step=global_step)
return train_op
def image_summary(label, tensor):
tensor_reshaped = tf.reshape(tensor,[-1,28,28,1])
return tf.summary.image(label,tensor_reshaped)
def evaluate(output, x):
image_summary('input_image',x)
image_summary('out_image',output)
l2 =
tf.sqrt(tf.reduce_sum(tf.square(tf.subtract(output,x,name='val_diff')),1))
val_loss = tf.reduce_mean(l2)
tf.summary.scalar('val_cost',val_loss)
return val_loss
if __name__ == '__main__':
n_code = 2
if os.path.exists('mnist_autoencoder_logs/'):
shutil.rmtree('mnist_autoencoder_logs/',ignore_errors=True)
with tf.Graph().as_default():
with tf.variable_scope('autoencoder_model'):
x=
tf.placeholder(tf.float32,[None,784],name='input')
phase_train =
tf.placeholder(tf.bool,name='phase_train')
code =
encoder(x,784,int(n_code),phase_train)
output =
decoder(code,int(n_code),784,phase_train)
cost = loss(output,x)
global_step =
tf.Variable(0,name='global_step',trainable=False)
train_op =
training(cost,global_step)
eval_op = evaluate(output,x)
summary_op =
tf.summary.merge_all()
saver =
tf.train.Saver(max_to_keep=200)
sess = tf.Session()
summary_writer =
tf.summary.FileWriter('mnist_autoencoder_logs/',graph_def=sess.graph_def)
sess.run(tf.global_variables_initializer())
# Training Cycle
for epoch in
range(training_epoches):
avg_cost = 0
total_batch=
int(mnist.train.num_examples/batch_size)
for i in
range(total_batch):
minibatch_x, minibatch_y = mnist.train.next_batch(batch_size)
_,
train_cost =
sess.run([train_op,cost],feed_dict={x:minibatch_x,phase_train:True})
avg_cost += train_cost
avg_cost /=
total_batch
if epoch %
display_step == 0:
summary_str,val_loss = sess.run([summary_op,eval_op],
feed_dict={x:mnist.validation.images,phase_train:False})
print('epoch:', epoch+1,' cost:',avg_cost,' validation loss:',val_loss)
summary_writer.add_summary(summary_str,sess.run(global_step))
saver.save(sess,'mnist_autoencoder_logs/model-checkpoint',global_step=global_step)
print('Training Finished')
test_loss = sess.run(eval_op,
{x:mnist.test.images,phase_train:False})
print('Test loss:', test_loss)
학습 결과는 아래와 같다.
epoch: 1 cost: 11.421402502926913 validation loss: 9.763931
epoch: 2 cost: 9.326198120117187 validation loss: 8.790714
…(중략)…
epoch: 198 cost: 4.9356590782512315 validation loss: 4.8779087
epoch: 199 cost: 4.927698595740578 validation loss: 4.9566693
epoch: 200 cost: 4.932985106381503 validation loss: 4.8705215
Training Finished
Test loss: 4.883771
Tesnsorboard로 본 학습 cost와 val_cost의 그래프다.
[PCA(Principal Component Analysis)와 autoencoder 비교 소스]
PCA를 사용할 때와 autoencoder를 사용할 때 어느 쪽이 embedding이 잘
이루어지는지 비교하기 위한 코드다.
from sklearn import decomposition
from matplotlib import pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("../MNIST_data/",one_hot=False)
pca = decomposition.PCA(n_components=2)
pca.fit(mnist.train.images)
pca_codes= pca.transform(mnist.validation.images)
#MNIST 원본, PCA 재구성 이미지 출력
plt.imshow(mnist.validation.images[0].reshape((28,28)),cmap=plt.cm.gray)
plt.show()
pca_recon = pca.inverse_transform(pca_codes[:1])
plt.imshow(pca_recon[0].reshape((28,28)),cmap=plt.cm.gray)
plt.show()
plt.imshow(mnist.validation.images[1].reshape((28,28)),cmap=plt.cm.gray)
plt.show()
pca_recon = pca.inverse_transform(pca_codes[1:2])
plt.imshow(pca_recon[0].reshape((28,28)),cmap=plt.cm.gray)
plt.show()
plt.imshow(mnist.validation.images[2].reshape((28,28)),cmap=plt.cm.gray)
plt.show()
pca_recon = pca.inverse_transform(pca_codes[2:3])
plt.imshow(pca_recon[0].reshape((28,28)),cmap=plt.cm.gray)
plt.show()
autoencoder를 사용한 결과와 위 코드를 사용하여 나온 재구성 이미지를 비교하면
아래와 같다. PCA보다는 autoencoder를 사용한 embedding이 잘 이루어지는 것 같다.
관련 글:
댓글
댓글 쓰기