핸즈 온 머신러닝 (Hands-On Machine Learning with Scikit-Learn & TensorFlow) / 오렐리앙 제론 지음 , 박해선 옮김

을 읽고, 추후 기억을 되살릴 수 있게끔 나만의 방법으로 내용을 리뷰한다. 따라서 리뷰의 내용 별 비중이 주관적일 수 있다.

 

챕터 15. 오토인코더

데이터들을 효율적으로 표현할 수 있는 coding을 학습할 수 있는 인공 신경망을 오토인코더라고 부른다. 따라서 오토인코더는 차원축소에 유용하며 특성 추출기처럼 작동하므로 심층 신경망의 비지도 사전훈련에 사용될 수 있다. 또한 훈련 데이터와 비슷한 새로운 데이터를 생성할 수 있는데 이를 generative model이라고 부른다. 오토데이터는 입력과 같은 출력을 특정 조건하에서 학습하며 배운다.

 

15.1 효율적인 데이터 표현

더 긴 수열이라도 규칙이 있는 수열이라면 규칙과 몇 개의 항에 대한 정보만으로 수열을 기억할 수 있다. 숙련된 체스 플레이어들이 체스 판을 기억할 때에도 익숙한 패턴이라면 매우 효율적으로 판을 기억한다. 이처럼 오토인코더가 입력을 받아 효율적인 내부 표현으로 바꾸고 이를 다시 해석하여 입력값과 가까워 보이는 출력을 한다. 이를 인코더와 디코더라고 한다. 출력층의 뉴런 수가 입력 개수와 동일하다는 것을 제외하면, 일반적으로 MLP와 동일한 구조를 가진다. 오토인코더가 입력을 재구성하므로 출력을 reconstruction이라 부르고, 비용 함수는 재구성 손실을 포함하고 있다.

 

내부 표현이 입력 데이터보다 저차원이면 undercomplete라고 하고 입력을 완전히 복사할 수 없으므로 중요한 특성을 학습하게 된다.

 

15.2 과소완전 선형 오토인코더로 PCA 수행하기

오토인코더가 선형 활성화 함수만 사용하고 비용 함수를 MSE로 설정하면 일종의 PCA가 된다. 예를 들어 3D 데이터를 투영할 최상의 2D 평면을 찾는 오토인코더를 만들 수 있다.

 

15.3 적층 오토인코더

오토인코더가 여러 개의 은닉층을 가진다면 적층 오토인코더 (stacked autoencoder, deepautoencoder) 라고 한다. 하지만 너무 강력해지지 않도록 주의해야한다. 적층 오토인코더의 구조는 전형적으로 가운데 은닉층을 기준으로 대칭이다. 예를 들어 MNIST를 위한 오토인코더라면 784개의 입력, 300개 뉴런의 은닉층, 150개 뉴런의 은닉층, 300개 뉴런의 은닉충, 784뉴런의 출력층이 있을 수 있다.

 

15.3.1 텐서플로 구현

적층 오토인코더는 평범한 심층 MLP와 매우 비슷하게 구현할 수 있으며, He 초기화, ELU 활성화 함수, l2 규제등을 사용할 수 있다. 차이 점은 타겟값 y가 없다는 것이다.

 

15.3.2 가중치 묶기

오토인코더가 완벽하게 대칭이라면 디코더의 가중치와 인코더의 가중치를 묶어, 디코더의 가중치를 인코더 가중치의 Transpose로 정의할 수 있다. 이러면 파라미터 수가 절반 가까이 줄어서 과대적합의 위험을 줄여준다. 텐서플로에서 이를 정의하려면 직접 층을 정의하는 것이 더 쉽다. (편향은 규제하지 않음)

 

15.3.3 한 번에 한 층씩 훈련하기

전체 오토인코더를 한 번에 훈련하는 것 보다 한 층씩 훈련하는 것이 더 빠르다. (입력, 은닉층 1, 출력)을 사용하여 입력을 재구성하도록 학습한다. 은닉층 1의 파라미터를 복사한 후 (은닉층 1, 은닉층 2, 은닉층 3)을 사용하여 은닉층 1의 출력이 은닉층 3의 출력을 재구성하도록 만든다. 마지막에 (입력, 은닉층 1, 은닉층 2, 은닉층 3, 출력)과 같이 층을 쌓는다.

 

다른 방법은 적층 오토인코더를 하나의 그래프로 만들고, 위와 같은 학습을 하도록 연산을 여러 개 만드는 것이다. 훈련 연산 1은 은닉층 2와 3을 그냥 지나치게 만들고, 훈련 연산 2는 은닉층 1을 동결하고 은닉층 2와 3을 학습한다. 훈련 연산 2에서 optimizer를 minimize할 때 var_list를 설정하면 훈련 할 변수를 지정할 수 있다. 효율적으로 하기 위하여 모든 입력에 대해 은닉층 1의 출력을 캐싱하여 은닉층 2의 입력으로 사용하는 것이 좋다.

 

15.3.4 재구성 시각화

입력과 출력을 시각화하여 비교해보면 오토인코더가 제대로 훈련되었는지 확인할 수 있다.

 

15.3.5 특성 시각화

은닉층에 있는 각 뉴런을 가장 크게 활성화시키는 훈련 샘플을 찾는 것은 비교적 큰 특성들을 잡아내기 때문에 최상단의 은닉층에 유용하다. 첫 번째 은닉층의 특성을 시각화하기 위해서는 각 뉴런에 연결된 가중치를 픽셀의 강도로 하여 확인하는 방법이 있다. 랜덤한 입력 이미지를 오토 인코더에 주입하고, 관심 있는 뉴런의 활성화를 관찰해서 경사 상승법을 수행하여 이미지를 훈련시키는 방법 또한 유용한 기법이다. 분류 문제를 위해 비지도 사전훈련에 오토인코더를 사용하고 있다면 분류기 성능 측정을 기반으로 검증하여도 된다.

 

15.4 적층 오토인코더를 사용한 비지도 사전훈련

레이블되어 있는 훈련 데이터가 많지 않은 경우, 먼저 적층 오토인코더를 훈련시킨 뒤 하위층을 재사용해 실제 문제를 해결하기 위한 신경망을 만드는 방법이 유용하다. 레이블된 훈련 데이터가 많지 않으면 분류기를 훈련할 때 하위층들을 동결하는 것이 좋다.

 

지금까지는 층의 크기를 제한하여 과소완전 오토인코더를 학습하였다. 코딩층의 크기를 입력과 같게 하거나 더 크게하여 과대완전 오토인코더를 만들 수도 있다.

 

15.5 잡음제거 오토인코더

입력 데이터에 잡음을 추가하고 노이즈가 없는 원본 입력을 복원하도록 훈련시킨다면 단순히 입력을 출력으로 복사하지 못하므로 데이터에 있는 패턴을 찾게된다. 순수한 가우시안 잡음이나 드롭아웃처럼 무작위로 입력을 꺼서 발생시킬 수 있다.

 

15.5.1 텐서플로 구현

tf.ramdom_normal(tf.shape(X)) 혹은 tf.layers.dropout(X, dropout_rate, training=training) 을 사용하여 구현할 수 있다. 

 

15.6 희소 오토인코더

좋은 특성을 추출하도록 하는 다른 제약의 방식은 희소이다. 비용 함수에 적절한 항을 추가하여 코딩층에서 활성화되는 뉴런 수를 감소시키도록 한다(평균적인 활성화 정도). 더 적은 뉴런으로 표현하려면 중요한 특성을 학습하게 되기 때문이다.

 

뉴런에 대한 평균 활성화 정도를 구한 후, 목표 희소 정도를 정해 MSE 혹은 KL 발산 값을 비용 함수에 추가할 수 있다. KL 발산은 MSE보다 훨씬 강한 그래디언트를 가져 빠르게 학습하게된다. KL 발산의 공식은 p log (p/q) + (1-p) log ( (1-p)/(1-q) ) 이다.

 

15.6.1 텐서플로 구현

loss에 재구성 손실과 sparsity_weight * sparsity_loss 를 합쳐서 훈련한다. kl_divergence는 함수를 직접 작성한다. 코딩층의 활성화가 0 또는 1인경우 KL 발산 식을 계산할 수 없으므로, 코딩층에 로지스틱 활성화 함수를 사용하는 방법이있다. 재구성 손실을 MSE 대신 크로스 엔트로피 등 더 큰 그래디언트를 가지는 함수를 사용하면 수렴 속도를 높일 수 있다. sigmoid_cross_entropy_with_logits() 함수를 사용하면 로지스틱 활성화 함수 적용과 크로스 엔트로피 계산을 같이 해준다.

 

15.7 변이형 오토인코더

변이형 오토인코더 (variational autoencoder)는 인기 있는 오토인코더의 한 종류이다. 이는 확률적 오토인코더(probabilistic autoencoder)로, 훈련이 끝난 후에도 출력이 부분적으로 우연에 의해 결정되며 생성 오토인코더 (generative autoencoder)이므로 훈련 세트에서 샘플링된 것 같은 새로운 샘플을 생성할 수 있다. 이 오토인코더는 RBM과 유사하지만 더 쉽고 빠르다.

 

변이형 오토인코더는 인코더와 디코더로 구성되어있는데 입력에 대해 코딩을 만드는 대신 평균 코딩 mu와 표준편차 sigma를 만든다. 코딩은 평균이 mu이고 표준편차가 sigma인 가우시안 분포에서 랜덤하게 샘플링된다. 인코더와 디코더는 각각 입력에서 mu와 sigma를 만들고, mu와 sigma에서 출력을 복원한다. 변이형 오토인코더의 비용함수는 코딩을 가우시안 분포에서 샘플링된 것처럼 보이게 한다. 따라서 새로운 샘플을 매우 쉽게 생성할 수 있게 된다.

 

비용 함수는 두 부분으로 구성되어 있다. 하나는 재구성 손실이고 하나는 잠재 변수 손실이다. 잠재 변수 손실은 코딩을 가우시안 분포에서 샘플된 것 같이 만든다. 목표 가우시안 분포와 실제 코딩 분포 사이의 KL 발산을 사용한다(sigma^2 + mu^2 - 1 - log(eps + sigma^2)). 자주 사용하는 번형은 sigma가 아니라 gamma = log (sigma^2)을 출력하도록 인코더를 훈련하는 것으로, 이는 스케일이 다른 sigma를 잡아내기 조금 더 쉬워서 수렴 속도를 빠르게 해준다.

 

15.7.1 숫자 이미지 생성

가우시안 분포에서 랜덤한 코딩을 샘플링한 다음, 이를 디코딩하면 오토인코더가 손 글씨를 생성하게 해준다. 숫자 대부분은 그럴싸해보인다.

15.8 다른 오토인코더들

수축 오토인코더 (contracitve autoencoder, CAE) : 비슷한 입력은 비슷한 코딩이 되게 한다.

적층 합성곱 오토인코더 (stacked convolutional autoencoders) : 적층 오토인코더에 합성곱 층을 사용한다.

확률적 생성 네트워크 (generative stochastic network, GSN) : 데이터를 생성하는 기능을 추가한 잡음제거 오토인코더의 일반화된 모델이다.

WTA 오토인코더(winner-take-all autoencoder) : 훈련하는 동안 코딩층에 있는 뉴런에 대해 최대 k% 활성화만 보존하고 나머지는 0으로 설정한다. 이는 희소 코딩을 만든다.

적대적 생성 네트워크 (generative adversarial network, GAN) : 판별자(discriminator)라고 부르는 네트워크가 생성자(generator)라고 부르는 네트워크가 만든 가짜 데이터와 실제 데이터를 구분하도록 훈련한다. 생성자는 판별자를 속이는 법을 학습하며, 판별자는 생성자의 속임수를 피하는 법을 학습한다. 이는 매우 현실적인 가짜 데이터와 안정적인 코딩을 생성하도록 만들며 매우 강력한 아이디어이다.

 

+ Recent posts