오토 인코더와 GAN을 사용한 표현 학습과 생성적 학습
오토인코더 autoencoder 는 레이블없는 데이터를 이용해서 잠재표현latent representation 또는 코딩coding( 일반적인 부호화 ) 로 입력데이터의 밀집 표현을 훈련하는 인공 신경망이다. 일반적으로 밀집표현은 입력 차원보다 낮아 차원 축소 및 시각화에 유용하고, 입력을 표현하는 강력한 특성을 추출기로 사용되어 심층신경망의 사전 훈련에 사용되기도 한다. 이렇게 추출한 낮은 차원의 특성들로 다시 훈련데이터와 비슷한 새로운 데이터를 만드는 생성 모델generative model 에 사용되기도 한다.
이와 비슷하게 GAN generative adversarial networks 는 생성모델과 판별모델을 사용해서 더 정교한 새로운 데이터를 생성해 낸다.
오토인코더, GAN 둘다 밀집 표현을 학습하는 비지도 학습이다.
- 오토인코더 :
입력과 동일한 출력을 만드는 방법을 학습한다. 그런데 오토인코더가 입력을 복사해서 출력하지않고, 효율적으로 밀집 표현을 학습하도록 하기위해서 신경망에 제약들을 추가한다. 잠재표현을 입력 차원보다 훨씬 낮게한다던지, 노이즈를 추가해서 원본 입력을 복원하도록 네트워크를 훈련한다. 즉 오토인코더는 일정 제약 조건하에 항등 함수identity function 을 훈련한다.
- GAN :
두개의 신경망으로 구성된다. 생성자generator 은 훈련 데이터와 비슷해보이는 데이터를 생성하고, 판별자discriminator 은 가짜 데이터와 진짜 데이터를 구별하도록 학습되어, 생성자가 생성한 데이터를 판별자가 판별한다. 이런식으로 신경망이 생성자와 판별자가 경쟁하면서 점점 훈련된다. 이를 적대적 훈련adversarial training 이라고 한다.
17.1 효율적인 데이터 표현
데이터를 쉽게 표현하기 위해서는 데이터를 무작정 외우는 것보다, 데이터의 패턴을 알면 데이터가 얼마나 크든 표현할 수 있다. 숙련된 체스 플레이어는 체스판을 5초만에 외운다. 이것이 가능한 이유는 체스판에 말이 무작위로 놓여져있지않고, 게임에서 놓일만한 현실적이 위치에 놓여져있을때, 패턴을 통해 위우기 때문이다. 즉, 패턴을 찾으면 효울적으로 정보를 저장할 수 있다.
체스 플레이어처럼 오토인코더는 입력을 효율적인 내부 표현으로 바꾸는 인코더encoder ( 인지 네트워크 recognition network ), 내부 표현을 출력으로 바꾸는 디코더decoder ( 생성 네트워크 generator network ) 으로 구성된다.
오토 인코더의 출력을 재구성reconstruction 이라고 부른다.
잠재 표현이 입력 차원보다 저차원인 오토인코더를 과소 완전undercomplete ( 기저basis보다 적은 개수로 표현되는 경우 ) 이라고 한다.
17.2 과소 완전 선형 인코더로 PCA 수행하기
https://github.com/kimhwijin/HandsOnMachineLearing/blob/main/AutoEncoder_GAN_17.ipynb
GitHub - kimhwijin/HandsOnMachineLearing
Contribute to kimhwijin/HandsOnMachineLearing development by creating an account on GitHub.
github.com
3차원 -> 2차원 인코더, 2차원 -> 3차원 디코더 를 연결한 오토인코더를 만든다.
17.3 적층 오토인코더
여러개의 은닉층을 가진 오토인코더를 적층 오토인코더stacked autoencoder ( 심층 오토인코더 deep autoencoder ) 이라고 한다. 적층할 수록 더 복잡한 코딩을 수행할 수 있지만, 너무 깊게하게되면 오토인코더가 각각의 입력데이터를 모두 외워버리게 되어 주의해야 한다.
MNIST를 위한 오토 인코더를 만들어본다.
17.3.1 케라스를 사용하여 적층 오토인코더 구현하기.
https://github.com/kimhwijin/HandsOnMachineLearing/blob/main/AutoEncoder_GAN_17.ipynb
GitHub - kimhwijin/HandsOnMachineLearing
Contribute to kimhwijin/HandsOnMachineLearing development by creating an account on GitHub.
github.com
Fashion_Mnist 데이터 입력 28, 28 -> Flatten -> 100 Dense -> 30 Dense -> 100 Dense -> 28*28 Dense -> Reshape
loss : binary crossentropy -> 각 픽셀을 0 또는 1 ( 흰색 또는 검은색의 확률로 간주한다. ) 이렇게하면 모델이 더빨리 수렴하는 경향이 있다.
metrics : 레이블의 픽셀이 0 or 1 일 거라고 훈련되었기 때문에, 픽셀값들을 0 또는 1로 반올림한 후 사용자 정의 지표를 만든다.
17.3.2 재구성 시각화
https://github.com/kimhwijin/HandsOnMachineLearing/blob/main/AutoEncoder_GAN_17.ipynb
GitHub - kimhwijin/HandsOnMachineLearing
Contribute to kimhwijin/HandsOnMachineLearing development by creating an account on GitHub.
github.com
17.3.3 패션 MNIST 데이터셋 시각화
높은 차원의 데이터 시각화 관점에서 오토인코더는 다른 차원 축소 알고리즘 만큼 좋을 결과를 주지 않을 수 있다. 하지만 오토인코더는 샘플과 특성이 많은 대용량 데이터셋을 다루기 때문에, 어느정도까지 오토인코더로 차원을 축소한 후에, 다른 유용한 차원 축소 알고리즘을 사용해 시각화 하는것도 방법이다.
https://github.com/kimhwijin/HandsOnMachineLearing/blob/main/AutoEncoder_GAN_17.ipynb
GitHub - kimhwijin/HandsOnMachineLearing
Contribute to kimhwijin/HandsOnMachineLearing development by creating an account on GitHub.
github.com
17.3.4 적층 오토 인코더를 사용한 비지도 사전 훈련.
레이블된 훈련 데이터가 많지않은 복잡한 지도 학습 문제의 경우, 비슷한 문제로 학습된 신경망의 하위층을 사용하는 방법과 비슷하게,
대부분 레이블되지 않은 대량의 데이터셋이 있다면, 먼저 전체 데이터로 적층 오토인코더를 훈련시켜 의미있는 은닉층을 훈련한다. 그리고 오토인코더의 하위층을 재사용해서 레이블된 데이터로 실전 문제를 해결하기 위한 신경망을 훈련시킨다.
17.3.5 가중치 묶기
오토인코더에서 인코더와 디코더가 대칭일때, 두 가중치를 묶어서 전체 가중치수를 절반으로 줄이고, 과대 적합의 위험성을 낮출 수 있다.
예를들어 입력 784 -> 100 -> 30 -> 100 -> 784 인 오토인코더가 있을때, 인코더 784->100 과 디코더 100->784 의 가중치를 묶는다. 인코더에는 784x100 의 가중치가있고, 디코더에 100x784의 가중치가 있는데 인코더의 가중치 행렬을 전치시켜 디코더에서도 사용한다.
https://github.com/kimhwijin/HandsOnMachineLearing/blob/main/AutoEncoder_GAN_17.ipynb
GitHub - kimhwijin/HandsOnMachineLearing
Contribute to kimhwijin/HandsOnMachineLearing development by creating an account on GitHub.
github.com
17.3.6 한 번에 오토인코더 한 개씩 훈련하기
적층 오토인코더를 훈련할때, 한꺼번에 전체 층을 훈련하는 것보다, 한층 씩 쌓아 훈련하는 방식으로 전체 오토 인코더를 점진적으로 만들어 갈 수 있다. 많이 사용하지는 않지만 '탐욕적 층별 훈련greedy layerwise training' 는 알아두는 것이 좋다.
https://github.com/kimhwijin/HandsOnMachineLearing/blob/main/AutoEncoder_GAN_17.ipynb
GitHub - kimhwijin/HandsOnMachineLearing
Contribute to kimhwijin/HandsOnMachineLearing development by creating an account on GitHub.
github.com
17.4 합성곱 오토인코더
이미지의 경우 밀집네트워크로 구성된 오토인코더는 좋은 성능을 내지 못해서, 합성곱 오토인코더convolutional autoencoder 을 만든다. 인코더는 입력에서 공간 방향의 차원을 줄이고, 깊이를 늘린다. 디코더는 거꾸로 동작한다. 이를 위해 전치 합성곱을 사용한다.
https://github.com/kimhwijin/HandsOnMachineLearing/blob/main/AutoEncoder_GAN_17.ipynb
GitHub - kimhwijin/HandsOnMachineLearing
Contribute to kimhwijin/HandsOnMachineLearing development by creating an account on GitHub.
github.com
17.5 순환 오토인코더
시계열 혹은 텍스트같은 시퀀스에는 순환 신경망이 밀집 네트워크보다 잘 작동할 수 있다. 순환 오토인코더 를 만들어본다.
https://github.com/kimhwijin/HandsOnMachineLearing/blob/main/AutoEncoder_GAN_17.ipynb
GitHub - kimhwijin/HandsOnMachineLearing
Contribute to kimhwijin/HandsOnMachineLearing development by creating an account on GitHub.
github.com
17.6 잡음 제거 오토인코더
오토인코더를 강제로 유용한 특성을 학습시키는데에 입력에 잡음을 추가하고, 잡음 없는 원본을 복원하도록 훈련하는 것이다. 적층 잡음 제거 오토인코더stacked denoising autoencoder
28*28 -> 100 -> 30 -> 100 -> 28*28 의 Dense로 이루어진 네트워크에서
28*28 -> + Gaussian Noise -> ...
28*28 -> + Dropout 50% -> ...
와 같이 잡음을 추가하거나, 드롭아웃을 사용해 절반으로 이루어진 입력에서 원본으로 복원하도록 훈련한다.
https://github.com/kimhwijin/HandsOnMachineLearing/blob/main/AutoEncoder_GAN_17.ipynb
GitHub - kimhwijin/HandsOnMachineLearing
Contribute to kimhwijin/HandsOnMachineLearing development by creating an account on GitHub.
github.com
17.7 희소 오토인코더
좋은 특성을 추출하도록 만드는 또다른 제약 방식은 희소sparsity 이다. 비용함수에 적절한 항을 추가해서 코딩 층에서 활성화되는 뉴런수를 감소시키는 방법이다. 적은 수의 뉴런을 조합하여 입력을 표현해야 되기때문에 뉴런은 유용한 특성을 학습하게 된다.
한 방법으로, 코딩 층의 출력을 0 ~ 1 로 제한하기위해 sigmoid 함수를 사용하고, 큰 코딩층 ( 큰 차원 ) 을 사용한다. 그리고 출력에 L1 규제를 추가한다. ( 자세한 이유는 잘... , 아래 설명)
ActivityRegularization 층을 사용하면 입력을 그대로 출력하지만, 훈련 손실에 입력의 절대값 합을 더한다! 이건 신경망이 0에 가까운 코딩을 유도하지만, 코딩이 0 에 가까우면 재구성하지 못해 벌칙을 받기때문에, 조그만 값을 출력하게한다. 또한 l2 규제가 아닌, l1 규제를 사용해서 모든 뉴런을 전체적으로 낮추는게 아니라 불필요한 뉴런을 0 으로 만들어 중요한 뉴런을 보존시킨다.
아래의 그래프는 데이터를 인코딩했을때, 출력되는 활성화 벡터들이다. 왼쪽은 모든 활성화 벡터들의 활성화 정도 ( 0 ~ 1 사이 )를 나타낸것이고, 오른쪽 그래프는 데이터당 활성화 벡터들의 활성화 정도의 평균을 나타낸 것이다.
- 규제를 사용하지않은 기본적인 stacked encoder의 뉴런 활성화 상태
sigmoid 함수의 특성으로 0 또는 1 쪽에 분포를 많이하지만 ( 왼쪽 그래프 ) , 대부분의 뉴런들이 값을 가지고 있음을 알 수 있다.
- 코딩 층의 뉴런이 300개이고, l1 규제를 사용한 sparse encoder 의 뉴런 활성화 상태
L1 규제를 사용하니깐 단일 뉴런 대부분이 0 에 분포하고 아주 적은 부분의 뉴런만 값을 가지는 것으로 보인다. 또한 데이터마다 추출된 뉴런 활성화벡터의 평균도 대부분 0 에 존재해서, 대부분의 뉴런이 활성화되지 않는 것으로 보인다.
이렇게 희소 정도를 알아서 정해지도록 하는 방법보다 더나은 결과를 얻기 위해서, 훈련 반복마다 코딩 층의 실제 희소정도를 측정해서 타깃 희소정도와 다르면 벌칙을 부과하도록한다. 모델 코딩 층의 희소정도를 알기위해서 각 뉴런의 평균 활성화를 계산한다. 이때 배치크기를 적당히 해서 너무 편향되지않는 뉴런 평균값을 구한다.
각 배치의 평균 활성화 정도를 알면 비용함수에 희소 손실sparsity loss 를 추가해서 벌칙을 가한다. 이때 mse를 계산할 수 있지만, 훨씬 강한 그레디언트 벌칙을 가진 쿨백-라이블러 발산 Kullback-Leibler divergence 를 사용한다.
위 그림과 같이 KL divergence 는 커질수록 급격한 기울기를 가진다.
Kullback-Leibler Divergence
두 개의 이산 확률 분포 p, q 가 주어졌을때, 두 분산 사이의 KL 발산 D_KL (P || Q ) 은 아래와 같이 계산한다.
뉴런이 활성화될 목표 확률 p와 실제 확률 q ( 훈련 배치에 대한 평균 활성화 ) 사이의 발산 정도는
으로 간단해 진다. ( p 일 확률과 아닐 확률 2개로 나뉘어지기 때문에. )
이렇게 희소 손실을 계산하고 모두 합해서 비용 함수의 결과에 더한다. 희소 손실과 재구성 손실 두가지 손실에 대해 중요도제어를 위해 희소 손실에 가중치 하이퍼파라미터를 곱한다.
희소 손실 가중치 0.05 로 훈련한 뉴런 활성화 정도 그래프 이다.
이전과는 다르게, 각각 뉴런이 조금더 활성화 되었고, 평균 뉴런 활성화도도 0에서 0.1 로 증가하였다. 10% 정도의 뉴런이 활성화 되는 것이다.
17.8 변이형 오토인코더
2014년에 제안된 변이형 오토인코더는 이전의 오토인코더와 두가지 차이점이 있다.
- 확률적 오토인코더 probabilistic autoencoder 으로서 훈련이 끝난 후에도 출력이 부분적으로 우연에 의해 결정된다. ( 반대로 잡음 제거 오토인코더는 훈련 중에만 무작위성이 추가된다. )
- 생성 오토인코더 generative autoencoder 으로 원래는 중요한 특성을 추출하는 이전 오토인코더와는 다르게 훈련 세트에서 샘플링된 것 같은 새로운 샘플을 만들 수 있다.
동일하게 인코더와 디코더로 이루어져있는데, 인코더는 주어진 입력에서 바로 코딩을 만드는 것이 아니라, 평균 코딩mean coding, 표준편차 를 만든다. 실제 코딩은 만들어진 평균과 표준편차을 가지는 가우시안 분포에서 랜덤하게 샘플링된다. 그후 디코더가 정상적으로 디코딩한다.
변이형 오토인코더는 입력이 매우 복잡한 분포를 가지더라도, 간단한 가우시안 분포 ( 실제론 더 일반적임 ) 에서 샘플링된 것처럼 보이는 코딩을 만든다. 훈련동안 비용함수는 코딩을 가우시안 샘플들의 군집처럼 ( 가우시안 분포 ) 으로 보이도록 코딩 공간coding space ( 잠재 공간latent space ) 을 점진적으로 이동시킨다. 그래서 가우시안 분포에서 랜덤하게 코딩을 샘플링후 디코딩해서 손쉽게 새로운 샘플을 만들 수 있다.
비용함수
비용함수는 두가지로 구성된다.
- 오토인코더가 입력을 재생산하도록 만드는 일반적인 재구성 손실이다. ( 앞에서처럼 이진 크로스 엔트로피를 사용가능하다. )
- 단순한 가우시안 분포에서 생성된 것같은 코딩을 가지도록 오토인코더를 강제하는 잠재 손실latent loss 이다. 여기서 목표분포와 실제 분포와의 KL 발산을 사용한다. ( 복잡한 확률분포이기 때문에, 희소 인코더보다 더 복잡한 식을 가진다. )
L : 잠재 손실
n : 코딩 차원
mu_i : i 번째 코딩 원소의 평균
sigma_i : i 번째 코딩 원소의 표준편차
인코더 출력 mu, sigma 로 잠재 손실을 구한다. 그런데 수학적으로 안정적이고 훈련속도를 높이는 방법으로
인코더에서 표준편차 sigma 말고, gamma = log ( sigma ^ 2 ) 인 gamma 를 출력한다.
케라스에서 binary_crossentropy 손실을 사용할경우, 각 픽셀마다의 손실의 평균을 구한다. 따라서 필요한 재구성 손실보다 입력픽셀 수만큼 작기 때문에 위의 잠재손실도 입력 픽셀수만큼 나눠줘서 동일한 스케일을 가지게 한다. 손실이 작아졌기 때문에 더 높은 학습률을 사용해야 한다.
17.8.1 패션 MNIST 이미지 생성하기
https://github.com/kimhwijin/HandsOnMachineLearing/blob/main/AutoEncoder_GAN_17.ipynb
GitHub - kimhwijin/HandsOnMachineLearing
Contribute to kimhwijin/HandsOnMachineLearing development by creating an account on GitHub.
github.com
세부 튜닝 및 오랫동안 훈련하면 더 좋은 이미지를 만들 수 있다.
17.9 생성적 적대 신경망
신경망을 서로 겨루게 하고 경쟁을 통해 신경망을 향상시켜나간다는 아이디어의 GAN은 두개의 신경망으로 이루어진다.
생성자
랜덤한 분포 ( 일반적으로 가우시안 분포 ) 를 입력으로 받아 이미지와 같은 데이터를 출력한다. 생성자는 변이형 오토인코더의 디코더와 같은 역할을 수행한다. 하지만 훈련방식이 매우 다르다.
판별자
생성자가 생성한 가짜이미지 혹은 훈련 세트에서 추출한 진짜 이미지를 입력으로 받아 입력된 이미지가 가짜인지 진짜인지 구분한다.
훈련중 생성자와 판별자의 목표는 반대이다. 판별자는 진짜 이미지 혹은 가짜 이미지를 구분하고, 생성자는 판별자를 속일만큼 진짜 같은 이미지를 생성한다. GAN은 다른 목표를 가진 두 네트워크이기 때문에 일반적으로 훈련이 불가능하다.
훈련 반복
- 먼저 판별자를 훈련한다. 훈련 세트에서 실제 이미지 배치를 샘플링하고 생성자에게 동일한 가짜 이미지를 합쳐 진짜는 1, 가짜는 0 으로 레이블링후 이진 크로스 엔트로피를 사용해 한스텝동안 배치 훈련을 한다. 이때 판별자의 가중치만 역전파시킨다.
- 다음으로 생성자를 훈련시킨다. 생성자로 다른 가짜 이미지 배치를 만들고, 모든 가짜 이미지 레이블을 1 로 세팅하고, 판별자에게 진짜인지 가짜인지 판별하도록 시킨다. 즉 생성자가 만들어낸 이미지를 판별자가 가짜 0 이라고 예측하면 생성자가 벌칙을 받는 형태이다. 이때 판별자의 가중치는 동결시키는 것이 중요하다. 생성자의 가중치만 역전파 시킨다.
생성자는 어떤 진짜 이미지도 입력받지않고, 단지 판별자를 통해 전달되는 그레디언트가 전부이다. 판별자의 성능히 좋아질수록 이 간접 그레디언트에 진짜 이미지의 정보가 많이 담긴다. 이걸로 생성자의 성능이 크게 향상될 수 있다.
17.9.1 GAN 훈련의 어려움
훈련과정에서 생성자와 판별자는 끊임없이 앞서려고 노력한다. 이렇게 진행되다보면 내시 균형 Nash equilibrium 이라 부르는 상태에 다다를 수 있다. 이는 생성자와 판별자 모두 상대방이 전략을 수정하지 않을 것이므로 자신도 전략을 수정하지 않아 생기는 상태이다.
GAN에서는 생성자가 너무 완벽하게 진짜와 같은 이미지를 만들어내서 판별자는 찍기밖에 못하는 경우인 내시균형이 생길 수 있다.
그런데 GAN이 이러한 균형에 도달할거라고 보장되지 않는다.
GAN훈련의 가장 큰 어려움은 모드 붕괴mode collapse 이다. 생성자가 다른 클래스들보다 특정 클래스를 잘만들거나 만들기 쉬울때, 판별자를 더 쉽게 속이기 때문에, 생성자는 그 특정 클래스를 더 많이 만들도록 유도하고, 그렇게 점점 다른 클래스 만드는 법을 잊어버린다.
판별자는 생성자로부터 가짜이미지를 비슷한 특성 클래스의 이미지만 받기 때문에, 점점 다른 클래스를 판별하는 방법을 잊어버린다. 판별자가 생성자가 만드는 특정 클래스를 잘 분별하게되면, 생성자는 다른 클래스로 옮겨가야 한다. 그렇게 몇개의 클래스를 방황하다가 어떤 클래스도 잘 만들어내지 못하게 된다.
또한 생성자와 판별자의 파라미터가 서로에게 영향을 주기때문에, 변동이 크고 불안정해질 수 있다. 그래서 하이퍼 파라미터를 세부 튜닝하는데 많은 노력이 필요하다.
안정적으로 훈련하기 위해서 새로운 비용함수를 제안하거나, 모드 붕괴를 피하기 위한 새로운 기법들이 제안되었다.
다양한 GAN 손실함수를 비교한 git 저장소
https://github.com/hwalsuklee/tensorflow-generative-model-collections
GitHub - hwalsuklee/tensorflow-generative-model-collections: Collection of generative models in Tensorflow
Collection of generative models in Tensorflow. Contribute to hwalsuklee/tensorflow-generative-model-collections development by creating an account on GitHub.
github.com
경험 재생experience replay 기법은 매 반복에서 생성자가 만든 이미지들을 재생버퍼에 저장하고 ( 오래된 이미지는 제거함. ) 판별자를 훈련할때 재생버퍼에 있는 가짜이미지들과 실제이미지를 합쳐서 훈련한다. 그러면 가장 최근 출력에 과대적합될 가능성이 줄어든다.
미니배치 판별mini-batch discrimination 은 배치간의 얼마나 비슷한 이미지가 있는지 측정해서 이 통계를 판별자에게 전달해, 판별자는 다양성이 부족한 가짜 이미지 배치 전체를 거부해서 모드붕괴의 위험을 줄인다.
17.9.2 심층 합성곱 GAN
큰 이미지를 만들기 위해 깊은 합성곱 층으로 GAN을 훈련시키는 것은 매우 불안정하기 때문에 까다로운 구조였지만, 2015년 앨릭 래드퍼드 등이 여러 가지 구조와 하이퍼 파라미터를 실험해서 안정화시켰다. 이를 심층 합성곱 GAN ( deep convolutioinal GAN ) DC GAN 이라고 한다.
변경점
- 판별자의 맥스 풀링층을 스트라이드 합성곱으로 바꾸고, 생성자의 맥스 풀링층을 전치 합성곱으로 바꾼다.
- 생성자와 판별자에 배치 정규화를 사용한다. 생성자의 출력층과 판별자의 입력층을 제외한다.
- tanh 함수를 사용하는 출력층을 제외하고 생성자의 모든 층을 ReLU 활성화 함수를 사용한다.
- 판별자의 모든 층은 LeakyReLU 활성화 함수를 사용한다.
https://github.com/kimhwijin/HandsOnMachineLearing/blob/main/AutoEncoder_GAN_17.ipynb
GitHub - kimhwijin/HandsOnMachineLearing
Contribute to kimhwijin/HandsOnMachineLearing development by creating an account on GitHub.
github.com
Fastion-MNIST 의 DC-GAN을 구성하기위해, 판별자의 BatchNormalization 은 Dropout으로, 생성자의 ReLU를 selu로 변경하고 훈련을 진행하였다. 나는 그런데도 학습이 잘안되서 random seed 를 변경해가면서 훈련해봤는데도 안되서, 판별자의 학습률을 50% 증가시키고 훈련했더니 잘되었다.
17.9.3 ProGAN
2018년 엔비디아 연구원이 훈련 최에 작은 이미지를 생성하고, 점진적으로 생성자와 판별자에 합성곱 층을 추가해서 갈수록 큰 이미지를 만드는 ProGAN을 소개하였다. 적층 오토인코더를 층별로 훈련하는 방법과 비슷하다. 이전 훈련된 층은 훈련가능하도록 두고 생성자 끝과 판별자 시작부분에 층을 추가한다.
생성자의 출력층을 제외한 마지막 합성곱 층 이후에 업샘플링 층을 추가한다. ( nearest interpolation ) 업샘플링한 층을 두개로 나눠서 하나는 그대로 출력 층으로 전달하고, 하나는 새로운 합성곱 층과 출력 합성곱 층을 지나가도록 한다. 이때 기존에 훈련해놓은 합성곱층의 가중치를 잃지 않기위해서, 기존 출력 층과, 새로운 출력층을 점진적으로 ( 가중치 합 ) 더한다. 기존 출력층은 점진적으로 fade-out, 새로운 출력층은 점진적으로 fade-in 한다.
판별자도 생성자와 비슷하게, 합성곱 층과 다운샘플링 층이 추가되고 점진적으로 합쳐진다.
미니배치 표준편차 층
판별자의 마지막 층에 근처에 추가한다. 입력에 있는 모든 위치에 대해 모든 채널과 배치의 모든 샘플에 걸쳐 표준편차를 계산한다.
tf.reduce_std( inputs, axis=[0, -1] )
-> shape : filter size 각 픽셀에 대해서, 모든 배치의 샘플과 필터들의 표준편차를 구한것.
-> tf.reduce_mean 으로 모든 픽셀의 표준편차의 평균을 구함.
-> 이 값으로 채워진 batch_size, height, width, 1 크기의 텐서가 입력에 추가된다.
이를 통해서 생성자가 만든 이미지에 다양성이 부족하면 판별자의 특성 맵 간의 표준편차가 작아지고, 이 층 덕분에 통계를 쉽게얻어 생성자가 적은 이미지를 만드는 경우를 잘 판별할 수 있게된다.
동일한 학습속도
He 초기화 대신 평균이 0 이고 표준편차가 1 인 가우시안 분포를 사용해 모든 가중치를 초기화 한다. 그리고 층이 실행될때 ( 런타임시 ) He 초기화에 있는 동일한 인자로 가중치의 스케일을 낮춘다. sqrt( 2 / n_inputs ) 으로 가중치를 낮춘다. RMSProp , Adam 등 적응형 그레디언트 옵티마이저를 사용할때 GAN의 성능을 크게 향상시킨다. 적응형 옵티마이저는 표준편차를 추정하고 그레디언트 업데이트를 정규화한다. 그래서 다이나믹 레인지가 큰 경우 ( 분산이 큰 경우 ) 는 그레디언트 업데이트를 적게할것이고 ( 표준편차로 그레디언트 업데이트를 나누기 때문에 ), 다이나믹 레인지가 너무 작을 경우에는 그레디언트 업데이트를 매우 크게해서 학습이 너무빠르게된다.
가중치 초기화는 모델이 빌드될 때 한번만 초기화하기 때문에, 모델의 한부분으로 가중치를 조정한다. 그래서 훈련 내내 모든 파라미터의 다이나믹 레인지를 동일하게 만들어 모든 가중치가 동일한 속도로 학습해 속도와 안정성을 높인다.
픽셀별 정규화 층
생성자의 합성곱 층 뒤에 추가한다. 동일한 이미지의 동일 위치에 있는 모든 활성화를 채널에 대해 정규화한다.
동일한 이미지-> 한 샘플, 동일 위치 -> 여러 필터들 중 같은 위치의 픽셀값, 정규화 -> 제곱 평균의 제곱근으로 나눈다.
생성자와 판별자 사이의 과도한 경쟁으로 활성화값이 폭주되는 것을 막아준다. ( 보통 배치 정규화와 비슷한 역할 )
17.9.4 StyleGAN
생성자에 스타일 트랜스퍼 style transfer 기법을 사용해 생성된 이미지가 훈련된 이미지와 같은 다양한 크기의 국부적 구조를 갖도록 유도한다. 즉 생성자의 이미지가 훈련이미지와 비슷하게 생성하도록해 품질을 높여준다.
매핑 네트워크
순차적으로 8개의 MLP가 잠재표현 z ( 코딩 ) 를 벡터 w 로 매핑한다. 이 벡터 w 는 여러 아핀 변환 affine transformation ( 활성화 함수 없는 Dense 층 ) 으로 전달되어 벡터 여러개를 생성한다. 이 벡터는 각각 다른 수준에서 생성된 이미지의 스타일을 제어한다.
합성 네트워크
이미지를 생성하는 네트워크이다. 입력을 받아 앞에서와 같이 합성곱 여러 개와 업샘플링에 통과시킨다. 대신 차이점으로
첫째, 입력과 ( 활성화 함수전에 있는 ) 모든 합성곱 층의 출력에 잡음이 조금씩 섞는다.
둘째, 잡음을 섞고 적응형 인스턴스 정규화 adaptive instance normalization ( AdaIN ) 층이 뒤따르게한다. 이 층에서는 각 특성 맵을 독립적으로 표준화 ( 평균을 빼고 표준편차로 나눔 ) 하고, 위 매핑 네트워크의 스타일 벡터를 사용해 각 특성 맵의 스케일과 이동offset 을 결정한다. ( 스타일 벡터에는 특성맵마다 하나의 스케일과 하나의 편향이 포함된다. )
원래 GAN에서 무작위성 잡음은 잠재 표현 ( 코딩 ) 에서 오고, 생성자는 이를 표현하는 능력의 상당부분을 잡음을 저장하는데 할애한다. 즉 랜덤한 잡음에서 의미를 꺼내는데 많은 능력을 쓴다. 또한 이 잡음이 네트워크를 흘러 생성자 마지막 층에까지 도달해야 새로운 이미지가 기억속 이미지가 아니라, 생성된 이미지가 된다. 이런제약은 훈련 속도를 느리게 만들 제약처럼 보인다.
위 StyleGAN에서 매번 다른 랜덤한 잡음을 각기 다른수준에 ( 여러 층에 ) 추가한다면 ( 별도의 잡음 입력을 추가한다면, ) 이미지의 각 부분에 정확한 양의 무작위성을 추가 할 수 있다.
추가되는 잡음은 각 수준마다 다르고, 한 수준에서 하나의 특성맵을 채우는 가우시안 잡음으로 모든 필터에 브로드캐스팅된다. 그래고 위에서 B로 표현된 박스에서 학습된 특성별 스타일링 인자로 조정된다.
또한 StyleGAN은 일정비율의 이미지를 두개의 다른 코딩으로 생성하는 믹싱 규제mixing regularization ( 스타일 믹싱 style mixing ) 이라고 불리는 기법을 사용한다. 코딩 c1, c2가 매핑 네트워크를 통과해 스타일 벡터 w1, w2 를 만들고, 합성 네트워크에서 첫 번째 단계에서 w1 을 쓰고, 나머지는 w2를 쓴다던가 하는 ( 랜덤하게 선택됨 ) 인접한 수준의 스타일이 상관관계를 가진다고 생각하지 못하도록 한다. 결국 각 스타일 벡터가 생성된 이미지에 있는 제한된 개수의 속성에만 영향을 미치는 styleGAN의 국지성을 촉진시킨다.