본문 바로가기

AI/대학원

Autoencoder 정리 및 코드 구현

오토인코더 (Autoencoder)

오토인코더는 인공 신경망을 기반으로 한 비지도 학습 기법으로, 입력 데이터를 압축한 후 다시 복원하는 과정에서 중요한 특징을 학습합니다. 이는 데이터의 차원을 축소하는 동시에 중요한 패턴을 찾아내는 데 사용되며, 비선형성을 다룰 수 있다는 점에서 PCA보다 더 강력할 수 있습니다.

오토인코더의 구조

  • 인코더(Encoder): 입력 데이터를 압축하여 저차원 잠재 공간(Latent Space)으로 변환합니다. 이 과정은 신경망의 은닉층을 통과하며, 입력 데이터의 주요 특징을 학습합니다.
  • 디코더(Decoder): 인코더가 축소한 잠재 표현을 다시 원래 차원의 데이터로 복원합니다. 목표는 원래의 입력과 최대한 유사한 출력을 생성하는 것입니다.
  • 잠재 벡터(Latent Vector): 입력 데이터가 인코더를 통과해 압축된 후의 표현으로, 이 벡터는 데이터의 주요 정보를 유지하고 있습니다.

오토인코더의 종류

  1. 기본 오토인코더 (Vanilla Autoencoder): 가장 단순한 형태로, 인코더와 디코더로 구성된 기본 구조입니다.
  2. 변분 오토인코더 (Variational Autoencoder, VAE): 잠재 공간에서 확률적 특성을 추가하여 생성 모델로도 사용할 수 있습니다.
  3. 스파스 오토인코더 (Sparse Autoencoder): 은닉층에서 활성화되는 노드 수를 제한하여 희소성을 강조하는 방법입니다.
  4. 심층 오토인코더 (Deep Autoencoder): 여러 개의 은닉층을 가진 더 깊은 구조로, 복잡한 데이터의 패턴을 학습할 수 있습니다.
  5. 컨볼루션 오토인코더 (Convolutional Autoencoder, CAE): 이미지 데이터에 적합한 구조로, 컨볼루션 층을 사용하여 공간적 패턴을 더 잘 학습합니다.

오토인코더의 장점

  1. 비선형 데이터 처리: 비선형성을 다루며, 복잡한 데이터 패턴도 학습할 수 있습니다.
  2. 특징 추출: 데이터의 중요한 특징을 자동으로 학습합니다.
  3. 생성 모델: VAE 같은 모델은 데이터를 생성하는 데 사용할 수 있습니다.

오토인코더의 단점

  1. 복잡성: PCA보다 구조가 복잡하고, 학습 시간도 더 많이 필요합니다.
  2. 과적합: 복잡한 신경망 구조를 사용할 경우 과적합이 발생할 수 있습니다.

PCA  와 요약 비교

  • PCA는 선형 차원 축소 기법으로 분산이 큰 방향으로 데이터를 투영해 차원을 축소하며, 주로 데이터의 노이즈 제거와 시각화에 사용됩니다.
  • 오토인코더는 비선형 차원 축소와 특징 학습이 가능하며, 신경망 기반 구조를 사용해 더 복잡한 데이터 패턴을 처리할 수 있습니다.

이 두 기법은 모두 차원 축소와 데이터 특징 학습에 사용되지만, PCA는 선형적 특성, 오토인코더는 비선형적 특성을 다룰 수 있는 점에서 차이가 있습니다.

# 필요한 라이브러리 임포트
from sklearn.datasets import fetch_openml
import numpy as np

from sklearn.neural_network import MLPRegressor
from sklearn.metrics import accuracy_score

import matplotlib.pyplot as plt
%matplotlib inline
# MNIST 데이터 다운로드 및 로드
mnist = fetch_openml('mnist_784', version=1)

# 이미지 데이터와 라벨을 분리
X, y = mnist['data'], mnist['target']

# 데이터를 정수로 변환 (y가 문자열 형식으로 되어 있을 수 있음)
X = X.to_numpy().astype(np.uint8)
y = y.to_numpy().astype(np.uint8)

# train과 test로 나누기 (MNIST는 이미 섞여 있는 상태라 슬라이싱으로 나눠도 됨)
train_x, test_x = X[:60000], X[60000:]
train_y, test_y = y[:60000], y[60000:]

# 데이터 정보 출력
n_train = train_x.shape[0]
n_test = test_x.shape[0]

print("The number of training images: {}, shape: {}".format(n_train, train_x.shape))
print("The number of testing images: {}, shape: {}".format(n_test, test_x.shape))
# 이미지 중 하나를 무작위로 선택
idx = np.random.randint(train_x.shape[0])  # train_x의 데이터 수만큼 무작위 인덱스 선택
img = train_x[idx].reshape(28, 28)  # 28x28 형태로 이미지 reshape

# 이미지 시각화
plt.figure(figsize=(6, 6))
plt.imshow(img, cmap='gray')  # 그레이스케일로 이미지를 출력
plt.title("Label : {}".format(train_y[idx]))  # 라벨 출력
plt.xticks([])  # x축 눈금 제거
plt.yticks([])  # y축 눈금 제거
plt.show()
 

# Define the Structure of an Autoencoder
# Input shape
# Latent variable shape
# Encoder shape
# Decoder shape
n_input = 28*28

# Encoder structure
n_encoder1 = 500
n_encoder2 = 300

n_latent = 2

# Decoder structure
n_decoder2 = 300
n_decoder1 = 500
# Build a model
# Both for Encoder and Decoder, use tanh as a nonlinear activation function
# optimizer -> Adam
reg = MLPRegressor(hidden_layer_sizes = (n_encoder1, n_encoder2, n_latent, n_decoder2, n_decoder1),
                   activation = 'tanh',
                   solver = 'adam',
                   learning_rate_init = 0.0001,
                   max_iter = 50,
                   tol = 0.0000001,
                   verbose = True)
reg.fit(train_x, train_x)

# test & evaluate
idx = np.random.randint(test_x.shape[0])
x_reconst = reg.predict(test_x[idx].reshape(-1,784))

plt.figure(figsize = (10,8))
plt.subplot(1,2,1)
plt.imshow(test_x[idx].reshape(28,28), 'gray')
plt.title('Imput Image', fontsize = 15)
plt.xticks([])
plt.yticks([])
plt.subplot(1,2,2)
plt.imshow(x_reconst.reshape(28,28), 'gray')
plt.title('Reconstructed Image', fontsize = 15)
plt.xticks([])
plt.yticks([])
plt.show()

# Build a model with Relu
# Both for Encoder and Decoder, use tanh as a nonlinear activation function
# optimizer -> Adam
reg_relu = MLPRegressor(hidden_layer_sizes = (n_encoder1, n_encoder2, n_latent, n_decoder2, n_decoder1),
                   activation = 'relu',
                   solver = 'adam',
                   learning_rate_init = 0.0001,
                   max_iter = 50,
                   tol = 0.0000001,
                   verbose = True)
reg_relu.fit(train_x, train_x)

# test & evaluate with Relu
x_reconst_relu = reg.predict(test_x[idx].reshape(-1,784))

plt.figure(figsize = (10,8))
plt.subplot(1,2,1)
plt.imshow(test_x[idx].reshape(28,28), 'gray')
plt.title('Imput Image', fontsize = 15)
plt.xticks([])
plt.yticks([])
plt.subplot(1,2,2)
plt.imshow(x_reconst_relu.reshape(28,28), 'gray')
plt.title('Reconstructed Image', fontsize = 15)
plt.xticks([])
plt.yticks([])
plt.show()