GAN/이론

6. ProGAN - 주요한 혁신들(1)

jwjwvison 2021. 6. 27. 21:41

 ProGAN은 풀 HD화질로 실제 사진같은 이미지를 생성하는 최신 기법이다. 여기에 포함된 네 가지 혁신은 다음과 같다.

 

 <잠재 공간 보간>

 2장에서 출력을 위한 초깃값을 만드는 저해상도 공간을 잠재공간이라고 불렀다. 4장의 DCGAN과 ProGAN도 초기 훈련된 잠재 공간은 의미 있는 속성을 가진다. 예를 들어 얼굴 이미지에 안경을 씌우는 벡터를 찾을 수 있다면 동일한 벡터로 새로운 이미지에도 안경을 씌울수 있다는 뜻이다. 

 이를 보간(interpolation)이라고 한다. 다음 그림에 이 과정이 나타나있다.

 

<고해상도 층으로 점진적 증대와 단계적 도입>

 특정한 지역에 가까워질 때 그 지역만 확대해서 볼 수 있다면 어떨까? 복잡도를 늘릴 수 있을 것이다. 거칠고 픽셀이 두드러진 이미지가 아니라 디테일이 상세한 이미지를 본다. 예를 들어 계곡으로 더 빨리 내려가기 위해 바짝 마른 개울을 건너는 경로를 택할 수 있다. 이것이 점진적 증대(progressive growing)이다. 그 지역의 해상도를 점진적으로 늘리는 것이다.

 

 기술적으로, 신경망은 저해상도 합성곱 층에서 출발하여 훈련하면서 여러 개의 고해상도 층으로 이동한다. 처음부터 고해상도 층을 사용하면 손실 함수의 공간을 탐색하기 어렵다. 따라서 간단한 것부터 시작해서 더 복잡하게 만든다. 다음 그림처럼 몇 스텝 동안 4x4 크기를 훈련하고 그다음 몇 번의 에포크를 거쳐 1024x1024 크기를 훈련한다.

 

 이런 시나리오의 문제점은 한 번에 하나의 층을 추가할 때(예를 들어, 4x4 에서 8x8로) 여전히 훈련에 큰 영향을 끼친다는 것이다. 대신 ProGAN 저자들은 다음 그림처럼 이런 층을 단계적으로 도입하여 시스템이 고해상도에 적응할 시간을 주었다.

 

 하지만 이 해상도를 바로 도입하지 않고 0과 1사이의 알파(a) 파라미터를 사용해 고해상도에 새 층을 단계적으로 도입한다. 알파는 이전 층을 업스케일한 층과 전치 합성곱으로 커진 층을 얼마나 사용할지 결정한다. D에서는 0.5배로 감소시켜 판별자에서 훈련된 층에 부드럽게 주입되게 한다. 이것이 위 그림에 있는 (b)이다. 새로운 층에 확신이 생기면 (c)처럼 32x32를 남기고 적절하게 32x32 크기를 훈련한 후에 다시 해상도를 늘린다.

 

<구현 예시>

 

import tensorflow as tf
import tensorflow.keras as K
def upscale_layer(layer,upscale_factor):
  '''
  upscale_factor(int) 만큼 층(텐서)을 업스케일한다.
  텐서 크기는 [group,height,width,channels]이다.
  '''
  height,width=layer.get_shape()[1:3]
  size=(upscale_factor * height,upscale_factor*width)
  upscaled_layer=tf.image.resize_nearest_neighbor(layer,size)
  return upscaled_layer
def smoothly_merge_last_layer(list_of_layers,alpha):
  '''
  임곗값 알파를 기반으로 층을 부드럽게 합친다.
  이 함수는 모든 층이 이미 RGB로 바뀌었다고 가정한다.
  생성자를 위한 함수이다
  list_of_layers: 해상도(크기) 순서대로 정렬된 텐서 리스트
  alpha: (0,1) 사이의 실수
  '''

  last_fully_trained_layer=list_of_layers[-2]  #업스케일링을 위해 끝에서 두 번째 층을 선택
  last_layer_upscaled=upscaled_layer(last_fully_trained_layer,2)  #마지막으로 훈련된 층을 업스케일링한다

  larger_native_layer=list_of_layers[-1]  # 새로 추가된 층은 아직 완전히 훈련되지 않았다

  assert larger_native_layer.get_shape() == last_layer_upscaled.get_shape()  # 합치기 전에 층 크기가 같은지 확인한다

  new_layer=(1-alpha) * last_layer_upscaled + larger_native_layer * alpha # 곱셈은 브로드캐스팅되어 수행된다

  return new_layer

 캐라스와 연구진이 훈련하는 동안 모델의 복잡도를 증가시키는 방법을 처음 고안한 것은 아니지만, 이는 매우 유망한 방법이고 큰 반향을 일으킨 혁신이였다.

'GAN > 이론' 카테고리의 다른 글

8. 텐서플로 허브를 사용한 실습  (0) 2021.06.27
7. ProGAN - 주요한 혁신들(2)  (0) 2021.06.27
8. 훈련 노하우  (0) 2021.06.26
7. 훈련의 어려움  (0) 2021.06.24
6. 훈련 평가  (0) 2021.06.24