개발자로 후회없는 삶 살기

[22.09.23] GAN PART.최신 GAN 기술 본문

[AI]/[네이버 BoostCamp | 학습기록]

[22.09.23] GAN PART.최신 GAN 기술

몽이장쥰 2022. 12. 27. 19:14

서론

최신 GAN 기술을 파고 들어보겠습니다.

 

본론

 

- DCGAN

판별자

 

생성자

=> 해설

1. 판별기는 그냥 합성곱 신경망을 쓰면 됩니다.
2. 생성기는 판별기 과정을 거꾸로 하면 됩니다. 이미지를 받아 처리하여 벡터를 만드는 것이(판별기가 하는 일) 아니라 벡터를 받아 크기를 늘려 이미지로 만듭니다. -> 전치 합성곱이라고 합니다. (transpose conv)

-> A) 일반적인 합성곱 : 깊이를 늘리면서 입력 너비와 높이를 줄입니다.(압축 = 특징 추출)
-> B) 전치 합성곱 : 깊이를 줄이는 동안 너비와 높이를 증가시킵니다.(확장 이미지 생성)

 

- GAN 훈련의 어려움

GAN은 훈련하고 평가하기가 어렵기로 유명합니다. 빠르게 발전하는 분야이므로 새로운 정보를 탐색할 수 있는 능력을 갖추는 것이 바람직합니다.

 

=> 평가

얼마나 비슷하게 흉내 냈는지 "정량화"를 해야 합니다. 우리는 생성된 샘플의 품질을 평가하는 통계적인 방법을 원합니다.

 

=> 평가 지표 1. 인셉션 점수, 2. 프레셰 인셉션 거리

 

※ FID 미리 보기 : 생성된 이미지와 대상 이미지 세트를 각각 측정합니다. > 생성된 이미지와 대상 이미지를 네트워크에 입력하여 중간 계층에서 추출한 벡터를 사용하여 가우시안 분포 사이의 거리를 계산합니다. FID는 작아야 좋습니다.

 

-> 평가 내용

1. 생성된 샘플은 실제 사물과 같고 구분이 가능해야 합니다. -> 구분이 가능하다는 것은 인셉션 분류기가 무엇을 보고 있다고 확신할 수 있어야 한다는 것을 의미합니다.

2. 생성된 샘플은 다양하고 모든 클래스를 포함해야 합니다.

 

-> 평가 방법

1. 인셉션 점수 = 높아야 좋습니다.


2. FID

종종 GAN은 클래스 별로 손쉬운 이미지만 학습합니다. FID는 잡음이 강하고 클래스 내부의 샘플 누락을 감지할 수 있습니다. IS는 한 타입의 카테고리만 생성해도 카테고리 생성 조건을 만족하기 때문에 FID가 중요합니다.

 

ex) 고양이 하나만 생성하는 게 아닌 여러 종류 혹은 하나의 고양이더라도 여러 각도의 별개로 볼 수 있는 이미지를 생성해야 합니다.

 

+ 방법 : 인셉션 모델에 이미지를 통과시켜 중간(= 임베딩) 표현을 만들고 > 진짜 이미지와 생성된 이미지의 임베딩된 평균, 분산, 공분산의 거리를 평가합니다.




- 훈련의 어려움

1. 모드 붕괴 : 일부 클래스를 못 만듭니다.
2. 느린 수렴 : 계산이 느립니다.(미래 AI는 데이터가 아니라 계산 성능이 결정적 요소가 될 거라고 말하기도 합니다.)

 

3. 과잉 일반화 : 존재하지 않는 샘플이 만들어집니다. (ex 몸통 하나에 머리가 3개인 소)


4. ProGAN 기법 : 훈련의 안정성과 빠른 수렴
5. 게임 설정 : 두 GAN(선수)이 게임의 목표, 두 선수가 달성하려고 하는 것 + 얼마나 승리할 가능성이 높은지 = 규칙과 승리 지표(손실함수)를 알아야 합니다.

 

6. MMGAN / NSGAN : 현재는 잘 사용하지 않지만 정보 이론 개념을 이해하는데 필요합니다.

7. 훈련 종료 시점 : 일반적으로 몇 번의 반복마다 생성된 샘플을 보고 멈출 때를 결정합니다. > 원칙적으로 내시 균형에 도달할 때 훈련이 끝난다고 하지만 실전에서 이를 입증하기 힘듭니다. (= 고차원은 평형 상태를 증명하기 어렵기 때문입니다.) + 두 손실 함수를 보는 것만으로는 언제 훈련을 끝내야 하는지 실제로 알기 어렵습니다. 그래서 비교적 빨리 결과를 내는 GAN을 씁니다. 그게 NSGAN입니다.

 

8. WGAN : 와서 스테인 거리를 사용하여 훈련 종료시간을 알 수 있어서 좋습니다.

-> 정리 : 이들 중 하나는 논문의 시작에 언급되므로 적어도 새로운 논문이 어떤 방법으로 사용되는지 이해할 수 있습니다. > 수학적으로 많이 보장하지는 못하지만 훨씬 잘 동작하는 비포화 버전인지, 이론적 배경도 갖추고 뛰어난 성능을 제공하는 새로운 와서 스테인 버전인지 알 수 있습니다.

- ProGAN

위 기법 1에서 말한 간단한 모델에서 복잡한 모델로 훈련하는 동안 점차 늘리는 방법을 설명합니다. -> 이를 통해 모델 훈련을 안정적으로 하고 높은 품질과 해상도를 가진 다양한 출력을 만듭니다.

 

+ ProGAN : Progressive GAN(풀 HD 화질로 실제 사진 같은 이미지를 생성하는 최신 기법)

 

+ 혁신 1 : 고해상도 층으로 점직적 증대와 단계적 도입

 

=> 점진적 증대

1. 처음에는 손실 함수를 멀리서 봐서 지역을 판단하고 특정 지역에 가까워질 때 점점 그 지역만 확대합니다.

 

2. 특정한 지역에 가까워질 때 그 지역만 확대해서 볼 수 있다면 어떨까요? 복잡도가 늘어나서(+) 디테일한 이미지를 보고 산악가가 경사를 따라 내려가면서 산행을 쉽게 하게 되고 = 평지로 더 빨리 내려가기 위한 "경로를 택할" 수 있습니다.

 

 

-> 정리 : 등산가가 "특정 지형에 가까워질수록 점진적으로 부드럽게 천천히 복잡한 모습이 확대"되어 나오는 게 좋습니다.

 

-> 기술적 정리 : 저해상도 합성곱(줌아웃) 층에서 출발하여 훈련하면서 여러 개의 고해상도 층으로(줌인) 이동합니다. = 처음부터 고해상도(줌인) 층을 사용하면 손실 함수의 공간을 탐색하기 힘듭니다. ∴ 간단한 것부터 시작해서 더 복잡하게 만들어갑니다.

 

+ 줌인 = 4x4 크기로 훈련하고 나중에는 1024x1024 크기를 훈련합니다.

 

-> 구체화 : 처음에는 덜 복잡한 모델을 사용하여 탐색하기 쉬운 손실 함수를 얻습니다. > 그다음 최적의 목표에 가까웠다고 확신이 섰을 때 복잡도를 증가시킵니다. = a, c에서 b, d로 이동합니다.

 

=> 단계적 도입

저자들은 저해상도에서 고해상도로 적응할 시간을 주었습니다. > 저해상도에 있다가 새로운 층에 확신이 생기면 고해상도로 단계적으로 도입했습니다.

 

+ 혁신 2 : 미니 batch 표준편차 (= 모드 붕괴를 막습니다.)

-> 판별자에게 샘플의 충분히 다양한지 알려주는 방법을 만듭니다. > 생성자가 만들고 실제 데이터에서 온 미니 batch에 있는 모든 픽셀의 표준편차를 스칼라 값으로 계산하고 > 이것을 판별자에게 알려줍니다.

 

+ 혁신 3 :

-> 생성자의 픽셀별 특성 정규화 : feature 값이 갑자기 커지는 것이 훈련이 발산하는 초기 신호! > 여기서 픽셀 정규화를 생성자에만 썼습니다.(값이 갑자기 커지는 것은 생성 시에만 일어난다고 합니다.)

 

- SGAN

아이디어 : 훈련 데이터 셋의 일부에만 클래스 label을 가지고 있어서 일부 label 된 데이터 포인트를 일반화합니다. -> 적은 양의 label 된 데이터에서 학습하는 알고리즘의 능력을 높이는 것은 실용적으로 매우 중요합니다.

 

-> 결과 미리 보기 : 훈련 label의 3% (7만 개 중 2천 개)만을 사용하고도 지도 학습의 최고 수준의 정확도에 근접했습니다.

 

모델 예측 : 이제까지 판별자(일반 gan, dcgan 등등)가 두 개의 클래스만(가짜, 진짜) 구별했는데 얘는 다중 분류를 수행합니다. > N+1개의 클래스를 구별하도록 하고 훈련 샘플의 클래스 개수 N, 생성자가 만든 가짜 샘플 1

 

-> ex) mnist 데이터 셋에서 훈련한 sgan 판별자는 11개의 클래스를 예측합니다.

 

- sgan 구조 미리 보기

판별자는 3종류의 데이터 입력을 받습니다. > 생성자에서 온 가짜 데이터, label 되지 않은 진짜 샘플(이거와 생성자의 가짜 데이터가 원래 받던거), label 된 진짜 샘플(새로 받는 것) > 판별자의 목표는 진짜 샘플과 가짜 샘플을 구별하는 것과 + ★ 진짜 샘플일 경우 올바른 클래스를 구분하는 것(왜 이럴까요? 아까는 맞다, 아니다 이진 분류였는데 이제는 다중 분류입니다.)

 

1. 생성자 : 구조도 목표도 동일합니다. 랜덤한 벡터를 받아 훈련 세트와 구분이 안 되는 가짜 샘플을 만듭니다.

2. 판별자

 

+ 원래 판별자

+ sgan 판별자

1. 세 종류의 입력을 받아서 진짜일 경우 해당하는 클래스로 분류(클래스 분류 = 지도 학습)
2. 아닐 경우 가짜로 처리(참, 거짓 분류 = 비지도 학습)
3. 출력 : 1, 2에 의해 n 개의 진짜 클래스 중 하나일 확률 또는 가짜 클래스에 속할 가능성을 나타내는 확률

 

4. 판별자를 기본 DCGAN을 10개의 클래스를 뽑도록 부모 모델을 만듭니다. > 여기서 두 갈래로 나뉩니다. -> sequential 모델이므로 model.add로 이어 붙입니다.

 

 

※ 모델 출력

# 원래 일반 gan 판별자 출력
model.add(Dense(1, activation="sigmoid"))
# sgan 다중 분류 판별자 출력
model.add(Activation('softmax'))

 

# sgan 참, 거짓 판별자 출력
def predict(x):
      # 진짜 클래스에 대한 확률 분포를 진짜 대 가짜의 이진 확률로 변환합니다.
      prediction = 1.0 - (1.0 /
                          (K.sum(K.exp(x), axis=-1, keepdims=True) + 1.0))
      return prediction

-> 무조건 모델 출력은 확률로 내보내야 합니다. (모든 신경망 분류 문제가 그러합니다.) 순차적 모델에서 마지막에 뉴런 개수 1개 하고 activation을 시그모이드로 하면 0~1 사이 확률값 "하나"고 softmax 하면 0~1 사이 확률이 뉴런 개수만큼 다 더해서 1입니다.

 

 

=> 학습 목표

1. 지금까지 gan은 생성 모델이 main이었습니다. 판별자는 생성자의 훈련을 돕고 버리는 용도로 훈련이 끝나면 생성자만 가지고 합성 데이터를 만듭니다.

 

 

2. 하지만 sgan은 판별자가 주요 관심 대상으로 목표는 적은 양의 label만 사용하여 판별자를 완전한 지도 학습 분류기에 가까운 정확도를 내는 준지도 학습 분류기로 만드는 것 > 생성자가 가짜 데이터를 만들어서 판별자 훈련 과정을 돕는 것입니다. > 생성자는 데이터에 있는 관련 패턴을 학습하여 판별자의 분류 정확도를 향상시킵니다. > 훈련이 끝나고 생성자를 버리고 판별자를 분류기로 사용합니다.

 

=> 훈련

-> 일반적인 GAN

1. PART."GAN 시스템"을 보면 x와 x*로 비지도 학습을 하는 그림이 있습니다.
2. 훈련 알고리즘 : 랜덤한 MNIST 이미지의 미니 batch를 진짜 샘플로 받고 랜덤한 잡음 벡터 z로부터 가짜 이미지의 미니 batch를 생성합니다. > 이를 사용해 생성자의 파라미터를 고정한 채로 판별자 네트워크를 훈련 > 가짜 이미지의 미니 batch를 생성하고 이를 사용해 판별자의 파라미터를 고정한 채로 생성자 네트워크를 훈련 > 이를 반복합니다.

 

 

-> sgan

-> 원래 있던 비지도 학습 + 지도 학습이 추가로 생깁니다.

 

1. 지도 학습 : label 된 진짜 샘플의 랜덤 미니 batch를 얻습니다. > 주어진 미니 batch에 대해 다중 분류 손실을 역전파 하여 학습합니다.


2. 비지도 학습 : label이 없는 진짜 샘플 x의 랜덤 미니 batch를 얻습니다. > 주어진 미니 batch에 대해 이진 분류 손실을 역전파 하여 학습합니다. > 생성자의 가짜 샘플을 받아서 이진 분류 손실을 역전파 하여 학습합니다.(이게 원래 GAN의 훈련입니다.)


3. 생성자 훈련 : z를 받아서 x을 생성 > 판별자에 넣어(D(x))이진 분류 손실을 역전파 하여 훈련합니다.

 

 

-> 주의점

1) 2번은 원래 GAN의 훈련입니다.
2) 지도 학습을 하기 위해 랜덤 미니 batch를 뽑는 일이 생겼습니다.

 

=> 모델 평가

훈련하는 동안 지도 학습 정확도는 100을 달성 > 8000번 하는데 샘플이 100개이니 당연히 훈련 데이터 셋을 모두 외울 것입니다 > ★중요한 것은 이 모델이 이전에 본 적 없는 훈련 세트 데이터에 얼마나 잘 일반화되는가★ 입니다.

 

-> 완전 지도 학습 판별기와 같은 학습 데이터 개수(100개)로 학습시키면 30% sgan 판별기가 정확도가 높습니다. = 적은 수의 훈련 샘플에서 sgan으로 훈련한 분류기 성능이 훨씬 뛰어납니다.

 

결론

sgan의 목적은 가능한 적은 수의 label 된 샘플로 판별자를 높은 분류 정확도를 달성하는 분류기로 훈련하는 것 > 이를 통해 분류 작업이 대량의 label 된 데이터 셋에 대한 의존성을 낮춥니다.

 

+ 이전에 본 적 없는 테스트 셋에서 sgan의 분류 정확도가 동일한 개수의 label 된 훈련 샘플로 훈련한 완전 지도 학습 분류기보다 훨씬 높은 성능을 냈습니다.

Comments