본문 바로가기

코딩/텐서플로우

비전공자의 코딩 독학 - 파이썬&텐서플로우(14) <오토인코더>

반응형

안녕하세요.

오늘의 파이썬 코딩 독학 주제는 오토인코더(Autoencoder)입니다.

 

 

1. 오토인코더란?

과거에 설명드렸듯이

2019/12/27 - [코딩/텐서플로우] - 비전공자의 코딩 독학 - 파이썬&텐서플로우(1)

 

비전공자의 코딩 독학 - 파이썬&텐서플로우(1)

안녕하세요. 오늘의 파이썬 코딩 독학 주제는 텐서플로우입니다. 1. 텐서플로우(tensor flow)란? 구글에서 공개한 오픈소스 머신러닝 라이브러리로써 C++, JAVA, R등 다양한 언어를 지원하지만 파이썬에 가장 최적..

bebutae.tistory.com

머신러닝의 방법에는 크게 세가지 종류가 있습니다.

 

그 중에서도 아무런 설명이나 라벨 없이 단지 대량의 데이터만 입력시켜

컴퓨터가 스스로 데이터를 정의하도록 하는 것을 비지도학습이라고 부릅니다.

그러한 비지도학습 중에서 가장 널리쓰이는 신경망이 오토인코더입니다.

 

오토인코더는 위 그림과 같이 입력값과 출력값을 같게 하며,

중간 계층의 노드 수가 입력값보다 적은 것이 특징입니다.

이로인해 입력데이터가 압축되며, 노이즈 제거에 효과적이게 됩니다.

 

 

2. 전체 소스코드

이번에도 MNIST데이터셋을 이용해서 학습을 진행해보겠습니다.

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("./mnist/data/", one_hot=True)

learning_rate = 0.01
training_epoch = 20
batch_size = 100
n_hidden = 256
n_input = 28*28

X = tf.placeholder(tf.float32, [None, n_input])
W_encode = tf.Variable(tf.random_normal([n_input, n_hidden]))
b_encode = tf.Variable(tf.random_normal([n_hidden]))

encoder = tf.nn.sigmoid(tf.add(tf.matmul(X, W_encode), b_encode))

W_decode = tf.Variable(tf.random_normal([n_hidden, n_input]))
b_decode = tf.Variable(tf.random_normal([n_input]))

decoder = tf.nn.sigmoid(tf.add(tf.matmul(encoder, W_decode), b_decode))

cost = tf.reduce_mean(tf.pow(X - decoder, 2))

optimizer = tf.train.RMSPropOptimizer(learning_rate).minimize(cost)

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

total_batch = int(mnist.train.num_examples / batch_size)

for epoch in range(training_epoch):
    total_cost = 0

    for i in range(total_batch):
        batch_xs, batch_ys = mnist.train.next_batch(batch_size)

        _, cost_val = sess.run([optimizer, cost], 
        feed_dict = {X:batch_xs})

        total_cost += cost_val

    print('Epoch:', '%04d' % (epoch + 1), 'Avg. cost=', 
    '{:.4f}'.format(total_cost / total_batch))

print('최적화 완료')

sample_size = 10

samples = sess.run(decoder, feed_dict={X: mnist.test.images[:sample_size]})

fig, ax = plt.subplots(2,sample_size, figsize=(sample_size, 2))

for i in range(sample_size):
    ax[0][i].set_axis_off()
    ax[1][i].set_axis_off()
    ax[0][i].imshow(np.reshape(mnist.test.images[i], (28, 28)))
    ax[1][i].imshow(np.reshape(samples[i], (28, 28)))

plt.show()


3. 소스코드 설명

(1) 오늘은 세가지 라이브러리를 사용할 예정입니다.

아래 코드를 통해 라이브러리를 올려주세요.

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

 

(2) 다음으로는 MNIST데이터셋을 세팅해주시고

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("./mnist/data/", one_hot=True)

 

(3) 다음으로는 하이퍼파라미터를 정의해주겠습니다.

learning_rate = 0.01
training_epoch = 20
batch_size = 100
n_hidden = 256
n_input = 28*28

learnin_rate는 최적화 함수에 적용할 학습율을,

training_epoch는 전체 데이터를 학습할 횟수를,

batch_size는 미니배치로 학습할 데이터의 개수를,

n_hidden는 은닉층의 뉴런개수를,

n_input는 MNIST 이미지의 크기를 나타냅니다.

 

(4) 이번에는 플레이스홀더를 설정해주겠습니다.

오토인코더를 이용하여 비지도학습을 할 예정이므로

Y값은 설정하지않습니다.

X = tf.placeholder(tf.float32, [None, n_input])

 

(5) 이제 인코더를 만들어주겠습니다.

W_encode = tf.Variable(tf.random_normal([n_input, n_hidden]))
b_encode = tf.Variable(tf.random_normal([n_hidden]))

encoder = tf.nn.sigmoid(tf.add(tf.matmul(X, W_encode), b_encode))

은닉층에는 n_hidden개의 뉴런을 설정해줍니다.

그 후 가중치와 편향변수를 설정한뒤, 해당 값들을 입력값과 곱하고 더해줍니다.

마지막으로는 sigmoid함수를 활성화 함수로 설정해줍니다.

 

(6) 이번에는 디코더입니다.

W_decode = tf.Variable(tf.random_normal([n_hidden, n_input]))
b_decode = tf.Variable(tf.random_normal([n_input]))

decoder = tf.nn.sigmoid(tf.add(tf.matmul(encoder, W_decode), b_decode))

디코더 역시 인코더와 비슷하게 구성하였습니다.

 

(7) 다음으로는 가중치를 최적화시켜줄 손실함수를 만들어보겠습니다.

오토인코더는 출력값을 입력값과 가장 비슷하게 만드는 것이 목적며

이를 통해 압축된 뉴런들을 이용하여 입력값의 특징을 알아낼 수 있습니다.

그러기 위해서는 입력값인 X를 평가용 실측값으로 사용하고,

X와 결과값의 차이를 손실값으로 설정해주면 됩니다.

이는 거리함수로 구해주겠습니다.

cost = tf.reduce_mean(tf.pow(X - decoder, 2))

 

말은 길었는데 코드는 단순합니다.

참고로 tf.pow()함수는 거듭제곱을 수행하는 함수입니다.

 

(8) 이제 최적화 함수의 차례네요.

RMSPropOptimizer를 이용하겠습니다.

optimizer = tf.train.RMSPropOptimizer(learning_rate).minimize(cost)

 

(9) 다왔습니다.

학습을 진행하기 위한 코드를 작성해주겠습니다.

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

total_batch = int(mnist.train.num_examples / batch_size)

for epoch in range(training_epoch):
    total_cost = 0

    for i in range(total_batch):
        batch_xs, batch_ys = mnist.train.next_batch(batch_size)

        _, cost_val = sess.run([optimizer, cost], 
        feed_dict = {X:batch_xs})

        total_cost += cost_val

    print('Epoch:', '%04d' % (epoch + 1), 'Avg. cost=', 
    '{:.4f}'.format(total_cost / total_batch))

print('최적화 완료')

 

(10) 다음으로는 결과를 좀더 직관적으로 확인하기 위해

matplotlib를 이용한 그림으로 표현해보겠습니다.

우선 10개의 샘플 이미지를 가져와서

디코더를 사용해 출력값으로 만들어줍니다.

sample_size = 10

samples = sess.run(decoder, feed_dict={X: mnist.test.images[:sample_size]})

 

 

(11) 이번에는 numpy를 이용해 데이터를 28*28크기의 이미지로 재구성해주고,

matplotlib의 imshow()함수로 그래프 상에 출력합니다.

fig, ax = plt.subplots(2,sample_size, figsize=(sample_size, 2))

for i in range(sample_size):
    ax[0][i].set_axis_off()
    ax[1][i].set_axis_off()
    ax[0][i].imshow(np.reshape(mnist.test.images[i], (28, 28)))
    ax[1][i].imshow(np.reshape(samples[i], (28, 28)))

plt.show()

 

 

4. 결과 확인

아래 그림과 같이 결과가 나오면 됩니다.

수고하셨습니다.

반응형