글 작성자: 만렙개발자

딥러닝에서 가장 대표적인 unsupervised learning 방식 중 하나인 autoencoder를 살펴보고자 한다.

 

auto, 그리고 encoder는 각각 왜 붙여진 이름일까.

 

encoder와 decoder를 먼저 보자.

 

encode는 입력이 특정한 형태로 변환하는 것을 말한다. 가장 간단한 예로 문장을 입력하면, 어떠한 값들로 변환하는 것도 encoder가 하는 일이다. 인공신경망이 학습하기 위해서는 문자보다는 숫자가 에러를 계산하기에 적합하기 때문이다. 그럼 decoder는? (encoder가 만든 것을) 원래의 형식으로 복원하는 역할을 한다. 예를들어 숫자를 넣으면 문자로 변환해주는 것처럼 말이다.

 

그렇다면 autoencoder는 무엇일까? 입력과 출력을 같도록하는 구조를 말한다. 노이즈 제거에 탁월하며, unsupervsied learning 방법 중 하나이다. 입력값에 특별히 label 혹은 정답 데이터가 따로 있는 것이 아니라, 입력값 그 자체가 정답이되므로 supervised되는 것이 없다. 따라서 unsupervsied 이지만, 좀 더 엄밀히 말하자면 self-supervised learning이다. 입력값이 정답이 되므로, 스스로 답을 주는 self-supervised라고 할 수 있다. 

 

input -> encoder -> decoder -> output

 

ref: https://excelsior-cjh.tistory.com/187

위와같은 구조가 있다고 하였을 때, input에 최대한 똑같게 output이 나오도록 하는 것이다. 이게 도대체 무슨 의미가 있냐라고 생각할 수도 있다. 자세히 들여다보면 input과 output의 개수와 중간에 hidden layer의 노드의 개수가 다르다. 그렇다는 것은 hidden layer에서 차원이 축소가 되었고, output이 input을 충분히 잘 표현한다면 그 축소는 매우 의미있는 축소가 될 것이다. 또한 입력 데이터에 노이즈를 더해 입력하여 인코딩하고, 디코더를 통해서는 노이즈가 없었던 원본 데이터를 복원하도록 하는 문제를 설계할 수도 있다. 이러한 문제설정을 통해서 단순히 input을 output으로 뱉어놓는 것이 아니라, input을 output으로 변환하기 위해서 표현(representation)하는 중간 상태를 잘 만드는 것이 목표이다. 

 

그런데 이러한 표현을 잘 하도록 학습하기 위해서는 문제(loss)를 잘 설계해야한다. 단순히 입력이 출력으로 나오는 문제를 조금 변형하여야 하는데, 일반적으로는 퍼즐 맞추기, 노이즈 제거, 해상도 매칭 등이 있다. 

 

ref: Unsupervised Learning of Visual Representations by Solving Jigsaw Puzzles

 

그럼 오토인코더가 갖는 의미는 무엇일까?

 

1. 모델이 데이터를 바라보는, 이해하는 시각/표현을 latent vector를 통해 얻을 수 있다.

 

일반적으로 인코더는 차원을 축소하기 때문에 입력받는 것을 문제를 해결하기 위한 어떠한 벡터로 변환된다. 결국 풀고자 하는 문제는 입력값을 출력값으로 되돌리는 것이기 때문에, 그 벡터는 입력값에 대한 정보를 최대한 압축하듯이 잘 담아낸다. 이러한 값은 representation, (latent) feature, embedding 등의 용어로 혼용된다. latent vector를 잘 생성하고 활용하는 것은 이후에 이 정보를 이용해 어떠한 작업을 하는지에 영향을 미치기 때문에 마치 데이터를 가공하는 전처리과정처럼 매우 중요하다.

 

2. 오토인코더에서 decoder 부분은 특정한 vector로부터 학습된 형태로 변환(복원)하는 기능을 갖는다.

 

일반적으로 autoencoder는 encoder와 decoder가 대칭적인 구조를 갖는다. 위에서 생성/추출한 latent vector를 이용해 원하는 결과 이미지를 생성해낼 수 있다. 이러한 '생성'의 측면으로 보았을때, decoder는 generator가 될 수 있는 것이다. 대표적인 generative 모델로는 GAN이 있지만, VAE도 있다.

 

autoencoder는 linear autoencoder, 각 단계의 weight를 초기화하는 Stacking Autoencoder, 학습 데이터에 노이즈를 추가한 Denoising AutoEncoder(DAE), regularizer를 추가한(=noise 역할) Stochastic Contractive Autoencoder(SCAE), 테일러 전개를 이용해서 stochastic을 deterministic하게 바꾼 Contractive Autoencoder(CAE), latent variable을 찾고자 만들어진 Variational Autoencoder(VAE)

 

Linear Autoencoder는 비선형의 activation function이 없어서, 기존의 머신러닝(PCA)으로도 매칭이 된다. 

 

간단한 autoencoder 코드입니다.

 

from keras.layers import Input, Dense
from keras.models import Model

encoding_dim = 32

def create_encoder():
	input = Input(shape=(784,)) # 28x28
	encoder = Model(input, encoded)
    
    return encoder

def create_decoder():
	encoded_input = Input(shape=(encoding_dim,))
	decoder_layer = autoencoder.layers[-1]
	decoder = Model(encoded_input, decoder_layer(encoded_input))
    
    return decoder
    
def create_autoencoder():
	input = Input(shape=(784,)) # 28x28
    encoded = Dense(encoding_dim, activation='relu')(input)
    decoded = Dense(784, activation='sigmoid')(encoded)
    autoencoder = Model(input, output)
    
    return autoencoder

 

### VAE

 

VAE는 어떤 데이터에 대해서 그 데이터에 영향을 주는 어떤 잠재변수(latent variable) Z가 존재한다면, 그 Z를 찾는 데 목적이 있다.

variational inference 방법을 이용하여 letent variable(z)를 좋은 것들만 뽑아낸 것

 

ref: Unsupervised Learning of Visual Representation by Solving Jigsa Puzzles