본문 바로가기
프로그래밍/인공지능

오토인코더(Auto-Encoder)

by austag 2023. 8. 4.

음 오토인코더는 처음보는 것 같은데요, 이 알고리즘도 딥러닝을 이용해 가상의 이미지를 만드는 또 하나의 유명한 알고리즘입니다. 오토인코더(Auto-Encoder)는 비지도 학습 방법이고, 입력 데이터의 특징을 효율적으로 담아낸 이미지를 만들어냅니다. 완전히 가상의 이미지를 만드는 GAN과는 다르죠. 안경을 안쓰고 보는 것처럼 흐릿하게 나옵니다. 근시가 있는데 안경을 쓰지 않으면 그 물체의 특징이나 색, 형태는 보이지만 흐릿하게 보이는 것처럼 이미지가 생성됩니다.

 

그렇다면 흐릿하게 나오는 이 알고리즘이 어디에서 쓰일까요? 영상 의학 분야 같은데이터가 충분하지 않은 곳에서 사용할 수 있다고 합니다. 학습 데이터는 현실 세계의 정보를 담고 있어야 하기 때문에 가상의 이미지를 넣으면 결과가 다르게 나올 수 있지만 오토인코더는 특징만을 뽑아내기 때문에 활용이 가능한 것입니다. 학습 데이터 수를 늘려줄 수 있는 효과를 보여줍니다.

 

오토인코더의 원리를 알아봅시다.

입력층과 출력층의 크기는 같고 은닉층은 수를 줄여 차원을 줄여주었습니다. 이때 소실된 데이터를 복원하기 위해 학습을 시작하고 입력 데이터의 특징을 효율적으로 응축한 새로운 출력이 나오는 원리입니다. 

 

핵심이 되는 인코딩, 디코딩의 코드 입니다.

# 생성자 모델
autoencoder = Sequential()

# 인코딩
autoencoder.add(Conv2D(16, kernel_size=3, padding='same', input_shape=(28,28,1), activation='relu'))
autoencoder.add(MaxPooling2D(pool_size=2, padding='same'))
autoencoder.add(Conv2D(8, kernel_size=3, activation='relu', padding='same'))
autoencoder.add(MaxPooling2D(pool_size=2, padding='same'))
autoencoder.add(Conv2D(8, kernel_size=3, strides=2, padding='same', activation='relu'))

# 디코딩
autoencoder.add(Conv2D(8, kernel_size=3, padding='same', activation='relu'))
autoencoder.add(UpSampling2D())
autoencoder.add(Conv2D(8, kernel_size=3, padding='same', activation='relu'))
autoencoder.add(UpSampling2D())
autoencoder.add(Conv2D(16, kernel_size=3, activation='relu'))
autoencoder.add(UpSampling2D())
autoencoder.add(Conv2D(1, kernel_size=3, padding='same', activation='sigmoid'))

인코딩은 차원을 축소해주고 디코딩에서는 차원을 늘려 입력값과 출력값이 똑같도록 해줍니다. 인코딩에서 MaxPooling으로 크기를 반으로 줄여주고 디코딩에서 UpSampling으로 크기를 2배 해줍니다. 인코딩은 2번 줄이고 디코딩은 3번 늘리는데 수가 왜 맞지 않을까요? 디코딩 코드에서 잘 찾아봅시다. 5번째 Conv2D 코드.... 뭔가 빠진게 있지 않나요?

padding을 넣지 않아 크기를 유지시켜주지 못합니다. 줄어들었다는 얘기죠. 이것으로 크기가 같아지는 것입니다.

autoendoder.summary()로 확인을 해보면

크기가 커진 부분과 작아진 부분을 확인할 수 있습니다.

 

자, 이제 전체 코드를 돌려보겠습니다.

from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D, Flatten, Reshape

import matplotlib.pyplot as plt
import numpy as np

#MNIST 데이터셋 불러오기
(X_train, _), (X_test, _) = mnist.load_data()
X_train = X_train.reshape(X_train.shape[0], 28, 28, 1).astype('float32') / 255
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1).astype('float32') / 255

#생성자 모델
autoencoder = Sequential()

#인코딩
autoencoder.add(Conv2D(16, kernel_size=3, padding='same', input_shape=(28,28,1), activation='relu'))
autoencoder.add(MaxPooling2D(pool_size=2, padding='same'))
autoencoder.add(Conv2D(8, kernel_size=3, activation='relu', padding='same'))
autoencoder.add(MaxPooling2D(pool_size=2, padding='same'))
autoencoder.add(Conv2D(8, kernel_size=3, strides=2, padding='same', activation='relu'))

#디코딩
autoencoder.add(Conv2D(8, kernel_size=3, padding='same', activation='relu'))
autoencoder.add(UpSampling2D())
autoencoder.add(Conv2D(8, kernel_size=3, padding='same', activation='relu'))
autoencoder.add(UpSampling2D())
autoencoder.add(Conv2D(16, kernel_size=3, activation='relu'))
autoencoder.add(UpSampling2D())
autoencoder.add(Conv2D(1, kernel_size=3, padding='same', activation='sigmoid'))

#컴파일 & 학습
autoencoder.compile(optimizer='adam', loss='binary_crossentropy')
autoencoder.fit(X_train, X_train, epochs=50, batch_size=128, validation_data=(X_test, X_test))

#학습 결과 출력
random_test = np.random.randint(X_test.shape[0], size=5)

#테스트 이미지 랜덤 호출
ae_imgs = autoencoder.predict(X_test)

plt.figure(figsize=(7,2)) #출력 이미지 크기

for i, image_idx in enumerate(random_test):
  ax = plt.subplot(2, 7, i+1) # 랜덤 이미지 나열
  plt.imshow(X_test[image_idx].reshape(28, 28)) # 테스트 이미지
  ax.axis('off')
  ax = plot.subplot(2, 7, 7+i+1)
  plt.imshow(ae_imgs[image_idx].reshape(28, 28)) #오토인코딩 결과 입력
  ax.axis('off')

plt.show()

결과에서 첫 번째 줄이 원본 이미지이고, 두 번째 줄이 오토인코더 이미지 입니다.


이미지 생성은 항상 신기한 것 같습니다...

그만큼 어렵구요ㅎㅎ....

 

참고: [모두의 딥러닝]

'프로그래밍 > 인공지능' 카테고리의 다른 글

전이 학습 - 2  (0) 2023.08.06
전이 학습(transfer learning) - 1  (0) 2023.08.05
생성적 적대 신경망(Generative Adversarial Networks)  (0) 2023.08.03
RNN - LSTM & CNN  (0) 2023.08.01
RNN - LSTM 활용  (0) 2023.07.31