Skip to content

Instantly share code, notes, and snippets.

@solaris33
Last active November 8, 2017 11:54
Show Gist options
  • Save solaris33/7b70fb9534eb1043262dde09c13c72fd to your computer and use it in GitHub Desktop.
Save solaris33/7b70fb9534eb1043262dde09c13c72fd to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
# MNIST 숫자 분류를 위한 Stacked AutoEncoder 예제
# 절대 임포트 설정
from __future__ import division, print_function, absolute_import
# 필요한 라이브러리들을 임포트
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
# MNIST 데이터를 다운로드 한다.
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
# 파라미터 설정
learning_rate_RMSProp = 0.01
learning_rate_Gradient_Descent = 0.5
training_epochs = 400 # epoch 횟수 (iteration)
softmax_classifier_iterations = 1000 # Softmax Classifier iteration 횟수
batch_size = 256
display_step = 1 # 몇 Step마다 log를 출력할지 결정한다.
examples_to_show = 10 # reconstruct된 이미지 중 몇개를 보여줄지를 결정한다.
n_hidden_1 = 200 # 첫번째 히든레이어의 노드 개수
n_hidden_2 = 200 # 두번째 히든레이어의 노드 개수
n_input = 784 # MNIST 데이터 input (이미지 크기: 28*28)
# Stacked Autoencoder를 생성한다.
def build_autoencoder():
# 히든 레이어 1을 위한 Weights와 Biases
Wh_1 = tf.Variable(tf.random_normal([n_input, n_hidden_1]))
bh_1 = tf.Variable(tf.random_normal([n_hidden_1]))
h_1 = tf.nn.sigmoid(tf.matmul(X, Wh_1) +bh_1) # 히든레이어 1의 activation (sigmoid 함수를 사용)
# 히든 레이어 2을 위한 Weights와 Biases
Wh_2 = tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2]))
bh_2 = tf.Variable(tf.random_normal([n_hidden_2]))
h_2 = tf.nn.sigmoid(tf.matmul(h_1, Wh_2) +bh_2) # 히든레이어 2의 activation (sigmoid 함수를 사용)
# Output 레이어를 위한 Weights와 Biases
Wo = tf.Variable(tf.random_normal([n_hidden_2, n_input]))
bo = tf.Variable(tf.random_normal([n_input]))
X_reconstructed = tf.nn.sigmoid(tf.matmul(h_2,Wo) + bo) # Output 레이어의 activation (sigmoid 함수를 사용)
return X_reconstructed, h_2
# Softmax Classifier를 생성한다.
def build_softmax_classifier():
# Softmax Classifier를 위한 파라미터들
W = tf.Variable(tf.zeros([n_hidden_2, 10]))
b = tf.Variable(tf.zeros([10]))
y_pred = tf.nn.softmax(tf.matmul(extracted_features, W) + b) # 예측된 Output : 두번째 히든레이어의 activation output을 input으로 사용한다.
return y_pred
# 학습에 필요한 변수들 설정
X = tf.placeholder("float", [None, n_input]) # Input 데이터 설정
y_pred, extracted_features = build_autoencoder() # Autoencoder의 Reconstruction 결과, 압축된 Features(h_2=200)
y_true = X # Output 값(True Output)을 설정(=Input 값)
y = build_softmax_classifier() # Predicted Output using Softmax Classifier
y_ = tf.placeholder(tf.float32, [None, 10]) # True Output
# Optimization을 위한 파라미터들
# Autoencoder Optimization을 위한 파라미터들
reconsturction_cost = tf.reduce_mean(tf.pow(y_true - y_pred, 2)) # squared error loss 함수
initial_optimizer = tf.train.RMSPropOptimizer(learning_rate_RMSProp).minimize(reconsturction_cost)
# Softmax Classifier Optimization을 위한 파라미터들
cross_entropy_cost = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1])) # cross-entropy loss 함수
softmax_classifier_optimizer = tf.train.GradientDescentOptimizer(learning_rate_Gradient_Descent).minimize(cross_entropy_cost)
# Fine Tuning Optimization을 위한 파라미터들
finetuning_cost = cross_entropy_cost + reconsturction_cost
finetuning_optimizer = tf.train.GradientDescentOptimizer(learning_rate_Gradient_Descent).minimize(finetuning_cost)
with tf.Session() as sess:
# 변수들을 초기화한다.
sess.run(tf.global_variables_initializer())
# Step 1: Stacked Autoencoder pre-training
total_batch = int(mnist.train.num_examples/batch_size)
# Training을 시작한다.
for epoch in range(training_epochs):
# 모든 배치들을 돌아가면서(Loop) 학습한다.
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
# batch 데이터를 이용해서 트레이닝을 진행한다.
_, cost_value = sess.run([initial_optimizer, reconsturction_cost], feed_dict={X: batch_xs})
# 일정 epoch step마다 로그를 출력한다.
if epoch % display_step == 0:
print("Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(cost_value))
print("Stacked Autoencoder pre-training Optimization Finished!")
# Step 2: test 데이터셋을 autoencoder로 reconstruction 해본다.
reconstructed_image = sess.run(y_pred, feed_dict={X: mnist.test.images[:examples_to_show]})
# 원본 이미지와 재구축(reconstructed)된 이미지를 비교한다.
f, a = plt.subplots(2, 10, figsize=(10, 2))
for i in range(examples_to_show):
a[0][i].imshow(np.reshape(mnist.test.images[i], (28, 28)))
a[1][i].imshow(np.reshape(reconstructed_image[i], (28, 28)))
f.show()
plt.draw()
#plt.waitforbuttonpress() # 버튼을 누를때까지 작업 정지
f.savefig('reconstructed_mnist_image.png') # reconstruction 결과를 png로 저장한다.
# Step 3: Softmax Classifier를 학습한다.
for i in range(softmax_classifier_iterations):
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(softmax_classifier_optimizer, feed_dict={X: batch_xs, y_: batch_ys})
print("Softmax Classifier Optimization Finished!")
# Step 4: 학습된 모델이 얼마나 정확한지를 출력한다. (Before fine-tuning)
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print("Accuracy(before fine-tuning): ") # Accuracy ~ 0.9282
print(sess.run(accuracy, feed_dict={X: mnist.test.images, y_: mnist.test.labels}))
# Step 5: Fine-tuning softmax model
# Training을 시작한다.
for epoch in range(training_epochs):
# 모든 배치들을 돌아가면서(Loop) 학습한다.
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
# batch 데이터를 이용해서 트레이닝을 진행한다.
_, cost_value = sess.run([finetuning_optimizer, finetuning_cost], feed_dict={X: batch_xs, y_: batch_ys})
# 일정 epoch step마다 로그를 출력한다.
if epoch % display_step == 0:
print("Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(cost_value))
print("Fine-tuning softmax model Optimization Finished!")
# Step 6: 학습된 모델이 얼마나 정확한지를 출력한다. (After fine-tuning)
print("Accuracy(after fine-tuning): ") # Accuracy ~ 0.9714
print(sess.run(accuracy, feed_dict={X: mnist.test.images, y_: mnist.test.labels}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment