적대적 생성 신경망 (Generative adversarial networks)
먼저 오토인코더에서와 마찬가지로, 간단한 예시로 GAN의 등장배경을 알아보자.

위 이야기의 정품 벽돌과 위조 벽돌의 발전 과정은 GAN(Generative Adversial Networks)의 훈련 과정과 똑같다.
GAN은 생성자와 판별자라는 두 적대자간의 싸움이다.

그림을 통해 이해하면,
생성자(정품or위조)는 랜덤한 잡음을 원래 데이터셋에서 샘플링한 것처럼 보이는 샘플로 변환한다.
판별자는 그 샘플이 원래 데이터셋에서 나왔는지, 아니면 위조품인지를 예측한다.
그렇다면 정보가 없는 맨 처음은? -> 생성자: 잡음 이미지를 그대로 출력 / 판별자: 랜덤으로 판별 -> 다음부터는 위와 같음.
4.1 심층 합성곱 GAN (DC GAN)
심층 합성곱을 이용하면 사실적인 이미지를 만들어 내고, 이미지 품질을 향상시킬 수 있다.!
예제를 통해 DC GAN을 구현해보자.
데이터 : 캐글의 레고 데이터셋

원본 데이터는 0~255로 이루어져 있는데, GAN을 훈련할 때는 [-1 ~ 1]로 스케일을 재조정한다.
(생성자의 출력층에서 하이퍼볼릭 탄젠트 함수를 사용하기 위해서!)

tf.cast => 텐서의 데이터타입을 변경 (np.astype과 비슷)
4.2 판별자
판별자는 생성자가
코드는 아래와 같다.


유의: 3번=마지막 합성곱 출력을 펼친다. 이 지점에서 텐서 크기는 1x1x1이다. 따라서 마지막 Dense층이 필요하지 않음.
판별자의 모델 Summary()는 다음과 같다.

4.3 생성자
이제 생성자를 만들어보자.
생성자에서 Input은 다변량 표준 정규 분포에서 뽑은 벡터라고 한다.
'' output은 원본 훈련 데이터에 있는 이미지와 동일한 크기의 이미지다.
다변량 표준 정규 분포라는 키워드를 보면 변이형 오토인코더가 떠오를텐데, 실제로 GAN의 생성자는 VAE(변이 오토인코더)의 디코더와 정확히 같은 목적을 수행한다고 한다.
생성자의 INPUT & VAE의 디코더 = 잠재 공간의 벡터를 이미지로 변환
생성형 모델에서는 잠재 공간에서 원래 도메인으로 다시 매핑하는 개념은 아주 많이 쓰이는데, 이는 잠재공간에서 벡터를 조정하는 것으로 이미지의 고차원적인 특성을 바꿀 수 있기 때문이다.
코드와 모델 summary를 알아보자.


검정색 동그라미를 보자.
1 = 생성자의 Input 층 -> 길이가 100인 벡터로 정의
2 = Reshape층을 통해 1x1x100 크기의 텐서로 변환 -> 전치 합성곱층 사용할 수 있게
3 = 4개의 Transpose CNN층에 통과, 그 사이에 배치정규화 및 리키렐루 층을 놓음.
4 = 마지막 전치 합성곱 층은 하이퍼볼릭 탄젠트 함수를 활성화 함수로 두고 출력을 원본 이미지와 같은 [-1,1] 범위로!
5 = 생성자 모델을 정의 -> 길이가 100인 벡터를 받고 [64,64,1] 크기의 텐서를 출력


출력층을 제외하고 4개의 전치합성곱층에서 첫 번째 층을 제외한 나머지 3개 층은 strides가 2로 되어있다.
-> 텐서가 네트워크를 통과하면서 방향의 크기가 증가함. (채널 수는 줄어든다-> 마지막에는 1로.! <-? )


위 사진은 스트라이드2 + 전치합성곱층과 업샘플링+스트라이드1인 일반 합성곱층을 비교하는 글이다.
Upsample층은 픽셀 사이 공간을 0으로 채우지 않고 기존 픽셀 값을 사용해 업샘플링 한다고 한다.
전치합성곱층은 일반적으로 출력 이미지 경계에 계단/체크무늬 패턴을 만들어서 출력 품질을 떨어뜨린다고 하는데, 뛰어난 GAN 논문에서 여전히 많이 사용한다고 한다. 따라서 Upsampling층이나 Conv2DTranspose 잘 비교해보고 사용해보자.
4.3 DC GAN (Deep Convolutional Generative Adversial Network) 훈련
위의 코드와 설명이 바로 DC GAN이다. (Conv2DTranspose층 사용) -> 심층 합성곱을 사용해 고품질 이미지 생성에 기여할 수 있다. 이제 이 DC GAN 모델의 훈련을 알아보도록 하자.
GAN을 진짜 이해하려면 훈련 과정을 이해해야 한다고 한다. (책에서..)
먼저 훈련 세트에서 진짜 샘플과 생성자의 출력을 합쳐서 훈련 세트를 만든다. (이를 지도 학습 문제로 다루자!)
정답 이미지 (진짜) = 1, 가짜 이미지 = 0, 손실 함수 = 이진 크로스 엔트로피
생성자는 어떻게 훈련시켜야 할까?
생성된 이미지에 점수를 부여하고 높은 점수를 낸 이미지로 최적화하는 방법을 찾아야 한다. (판별자가 이 역할을 수행)
배치 이미지를 생성하고 이를 판별자에 통과시켜 각 이미지에 대한 점수를 얻을 수 있다고 한다.
(판별자가 진짜라고 생각하는 이미지를 생성하도록 생성자를 훈련하고 싶기 때문)
그리고 한 번에 한 네트워크의 가중치만 업데이트 될 수 있도록 두 네트워크를 번갈아가면서 훈련하는 것이 중요하다.
생성자를 훈련할 때 판별자의 가중치가 변경되도록 허용하면 생성된 이미지를 진짜라고 여기도록 조정되기 때문.
-> 판별자가 약해서가 아니라 생성자가 강하기 때문에 생성된 이미지가 1에 가까운 값으로 예측되어야 한다!
아래 그림은 판별자와 생성자의 훈련 과정을 보여준다.

DC GAN compile code


코드의 검정 동그라미를 보자.

4.4 GAN 훈련의 트릭과 팁
GAN은 생성형 AI 분야에서 큰 혁신이지만 훈련이 어렵기로도 유명하다고 한다.
이 절에서는 무엇이 어려운지, 어떻게 해결할 수 있을지 알려준다고 하니 집중력을 잃지 말자!
Case #1 판별자 > 생성자
판별자가 더 뛰어나다면 손실 함수의 신호가 약해져 생성자의 성장(좋은 이미지를 만들어낼 수 있는 능력)이 저해된다.
최악의 상황 -> 판별자가 신같은 존재 -> 학습이 이루어지지 않아버렷!
해결방안
- 판별자의 dropout층의 rate 매개변수값을 증가시켜 네트워크를 통해 흐르는 정보 양 감소시키기
- 판별자의 학습률 감소시키기
- 판별자의 합성곱 필터 수 감소시키기
- 판별자 훈련 시 레이블에 잡음 증가시키기
- 판별자 훈련 시 일부 레이블 이미지 무작위로 뒤집기
Case #1 판별자 < 생성자
고급스러운 말로 모드 붕괴(mode collapse)라고 한다고 한다.
생성자를 이기적인(현명한?) 사람이라고 생각해보자. 어떻게 판별자를 속일 수 있을까? (훈련 방향이 어떨까?)
만약 판별자의 가중치를 업데이트하지 않는다고 해보자. 그렇다면 당연히 생성자는 여러개가 아닌, 판별자를 속일 수 있는 '단 하나'의 샘플만을 찾으려고 할 것이다. 그 샘플만 찾아낸다면 영원히 판별자를 속일 수 있기 떄문이다!
유용하지 않은 손실
딥러닝 모델은 손실 함수의 값이 작아지는 방향으로 학습하기 때문에 손실이 작을수록 이미지 품질이 좋아진다고 착각하기 쉽다. 하지만 생성자는 현재의 판별자에 의해서만 평가되고, 판별자는 계속해서 업데이트 되기 때문에 훈련 과정의 다른 지점에서 평가된 손실을 비교할 수 없다.
-> 생성자의 손실과 이미지 품질 사이의 연관성 부족때문에은 GAN의 중간과정 모니터링이 어렵다.
하이퍼 파라미터
위의 코드를 보았듯이, GAN에서는 튜닝해야 할 하이퍼 파라미터의 개수가 상당히 많을것을 볼 수 있다.
-> 배치 정규화 / 드롭 아웃 / 학습률 / 활성화 층 / 합성곱 필터 / 커널 크기 / 스트라이드 / 배치 크기 / 잠재 공간 크기 등
GAN의 도전과제 해결
위의 여러가지 문제점들은 최근 몇 년간 똑똑이들에 의해서 많이 개선되었다고 하는데, 어떻게 되었는지 더 자세히 알아보자!
4.5 와서 스테인 GAN- 그레디언트 패널티 (WGAN-GP)
아르좁스키라는 스키 2017년 "와서스테인 GAN"이라는 논문을 통해 GAN의 모델 안정성 구축에 크게 기여했다.
핵심은 두 가지다.
1: 생성자가 수렴하는 것과 샘플의 품질을 연관 짓는 의미 있는 손실 측정 방법
2: 최적화 과정의 안정성 향상
참고)와서스테인은 손실 함수이다!


'딥 러닝 > 생성형 AI' 카테고리의 다른 글
05. 확산 모델 (Diffusion model) (0) | 2024.05.31 |
---|---|
03. 변이형 오토인코더 (2) | 2024.03.22 |
02. 딥러닝 (1) | 2024.03.17 |
01. 생성 모델 (2) | 2024.03.11 |