AI/K-Digital Training

024. Autoencoder라는 높은 벽

찌리남 2021. 10. 1. 12:00
728x90

사실 다른 모델들과 비교하면 Autoencoder를 높은 벽이라 부르기 어렵습니다.

오히려 쉬운 편이라고 볼 수 있습니다.

그런데 제가 어렵게 느꼈습니다. 

그러면 개인적으로는 높은 벽이라 부를 수 있겠죠..

 

오토 인코더는 기본적으로 비지도 학습이라고 봅니다.

그 이유는 따로 레이블 되어 있지 않기 때문이죠.

레이블이 없는 문제는 보통 지도 학습이라고 보지 않습니다.

 

오토 인코더는 latent representation(잠재 표현)이 입력 데이터의 밀집 표현을 학습하는 인공 신경망입니다.

또는 입력 데이터의 패턴을 학습해 비슷한 데이터를 생성해내는 알고리즘이라고 보면 됩니다.

그래서 입력 데이터를 차원 축소해 낮은 화질의 이미지를 생성하거나

오토 인코더 그 자체로 feature-extraction 하는 알고리즘으로 작동합니다.

그리고 일부 오토 인코더는 훈련 이미지와 매우 비슷한 이미지를 출력해내는데

이를 생성 모델이라고 부릅니다. 하지만 차원을 축소한다는 특징 때문에 이미지가 흐릿하고 실제 같지는 않습니다.

실제와 비슷한 이미지를 생성해내는 모델은 GAN(generative adversarial networks)로 생성이 가능하다고 합니다.

 

오토인코더의 학습은 입력을 출력으로 복사하는 것이 기본입니다만

다양한 방법으로 입력 데이터나 네트워크에 제약을 가해 데이터를 효율적으로 학습하게 합니다.

다시 말하면 제약 조건 아래서 같은 값을 구하는 모델을 학습하는 것이 오토 인코더의 목표입니다.

 

오토 인코더는 인코더와 디코더로 구성됩니다.

인코더는 패턴을 파악해 컴퓨터가 이해하기 효율적인 방식으로 바꾸고

디코더는 컴퓨터의 표현으로 바뀐 입력을 출력으로 바꿉니다.

인코더와 디코더 사이의 내부 표현은 입력 데이터보다 저차원이기 때문에 과소 완전이라고 부릅니다.

아래의 그림에 나온 것처럼 출력층의 뉴런 수가 입력층의 것과 같습니다.

오토 인코더는 이처럼 출력을 입력을 재구성한 것과 같아 재구성이라고 부릅니다.

 

출처:https://www.v7labs.com/blog/autoencoders-guide

오토 인코더도 MLP(다층 퍼셉트론)처럼 여러층의 신경망을 구성할 수 있습니다.

대신 전형적으로 가운데 은닉층을 기준으로 구조가 대칭입니다.

다음은 Keras에서 28*28 크기의 MNIST 데이터셋으로 SELU, Sigmoid 활성화 함수를 사용해

구글 코랩에서 적층 오토 인코더를 구현한 코드입니다.

from tensorflow import keras

stacked_encoder = keras.models.Sequential([
                                           keras.layers.Flatten(input_shape[28,28]),
                                           keras.layers.Dense(100, activation="selu"),
                                           keras.layers.Dense(30, activation="selu"),
])
stacked_decoder = keras.models.Sequential([
                                           keras.layers.Dense(100, activation="selu"),
                                           keras.layers.Dense(28*28, activation="sigmoid"),
                                           keras.layers.Reshape([28, 28])
])
stacked_ae = keras.models.Sequential([stacked_encoder, stacked_decoder])
stacked_ae.compile(loss="binary_crossentropy",
                   optimizer=keras.optimizers.SGD(lr=1.5))
history = stacked_ae.fit(X_train, X_train, epochs=10,
                         validation_data=(X_valid, X_valid))

한번 레이어를 지난 다음 활성화 함수를 거치는 구조는 심층 MLP와 비슷합니다.

다른 점이라면 Encoder와 Decoder가 대칭적으로 존재하고 은닉층의 구조 및 벡터의 크기도 대칭이라는 것입니다.

각 픽셀의 강도는 픽셀이 검정일 확률을 나타내므로 크로스 엔트로피 손실을 사용합니다.

 

위에서 설명한 적층 오토 인코더는 레이블 없는 데이터는 많고 레이블 된 데이터는 적은 경우에 유용합니다.

모든 데이터를 사용해 오토 인코더를 학습시킵니다. 

그러면 학습된 오토 인코더는 데이터들의 패턴을 알게 됩니다. 

학습된 오토 인코더의 하위층 위에 신경망을 잇고 레이블된 데이터를 학습시킵니다.

이런 학습 방법은 레이블이 있는 데이터를 만드는 비용은 굉장히 크기 때문에 유용합니다.

출처:https://www.researchgate.net/figure/A-Deep-Learning-Neural-Network-Stacked-Autoencoder-Network-with-Unsupervised-Training_fig1_340305199

 

마지막으로 위에서 제가 구현한 적층 오토 인코더처럼 구조가 대칭일 때 인코더와 디코더의 가중치를 묶을 수 있습니다.

가중치를 묶으면 학습시킬 파라미터의 수가 절반으로 줄어서 훈련 속도를 높이고 오버피팅의 위험을 줄일 수 있습니다.

말로 하면 이해하기 힘든 부분인데 구현한 코드를 보시면 적층 코드에서 Dense층만 묶어서 대칭으로 배열한 것을 알 수 있습니다.

dense_1 = keras.layers.Dense(100, activation="selu")
dense_2 = keras.layers.Dense(100, activation="selu")

tied_encoder = keras.models.Sequential([
                                           keras.layers.Flatten(input_shape[28,28]),
                                           dense_1,
                                           dense_2
])
tied_decoder = keras.models.Sequential([
                                           DenseTranspose(dense_2, activation="selu"),
                                           DenseTranspose(dense_1, activation="sigmoid"),
                                           keras.layers.Reshape([28, 28])
])
tied_ae = keras.models.Sequential([tied_encoder, tied_decoder])

오토 인코딩의 기본적인 개념들만 살짝 훑었습니다.

사실 이미지 데이터를 학습시키려면 CNN의 아이디어를 가져온 합성곱 인코더가 적절합니다.

그리고 시계열이나 텍스트와 같은 시퀀스에 대한 학습은 RNN을 따온 순환 오토 인코더가 적절합니다.

그 외에 희소 오토 인코더, 그리고 cs231n에서 꽤 긴 시간 할애해 설명하는 변이형 오토 인코더도 있습니다.

뭐 파도파도 끝이 없는 분야다 보니.. 하나 알게 되면 모르는 것이 더 늘어나는 느낌입니다.

 

다음 수업에서는 GAN을 다룬다고 하니 기대됩니다.

GAN은 마이야히와 다메다메를 만드는 기술이라 하니 가슴이 웅장해집니다.

728x90
반응형