[VISION] 비전 시스템을 위한 딥러닝(8) - GAN, 생성적 적대 신경망

Study/Vision & Deep Learning · 2023. 5. 31. 14:57

GAN은 이안 굿펠로우와 요슈아 벤지오 들이 2014년에 제안하 새로운 신경망 구조이다.

GAN은 실제와 매우 흡사한 이미지, 영상, 음악, 텍스트 등을 생성할 수 있는 능력을 가지고 있다.

이를 통해 새로운 컨텐츠를 창조하고 인간과 동등한 창조물을 만들어 낼 수 있다.

GAN은 생성 모델로서, 특정 도메인의 데이터셋을 학습받고 이를 통해 기존에 존재하지 않았던 내용을 생성하는 기능을 가지고 있다. 

또한, GAN은 인공 일반 지능(Artificial General Intelligence, AGI)으로 가는 첫걸음이기도 하다.

 

8.1 GAN 구조

GAN은 적대적 훈련이라는 개념을 기반으로 하는데, 이 모델은 기본적으로 서로 경쟁하는 다음 2개의 신경망으로 구성된다.

  1. 생성자: 무장위 노이즈를 원래의 데이터셋에서 본 표본과 비슷하도록 변환하는 모델
  2. 판별자: 입력된 관찰이 생성자가 만든 가짜인지 원래의 데이터셋의 일부인 진짜인지 예측하는 모델

GAN은 이 두 신경망이 서로 발전함에 따라 기능이 향상된다. (위조지폐범과 경찰로 비유한다.)

다음과 같은 과정을 통해 동작한다

  1. 무작위 노이즈 입력 -> 이미지 반환
  2. 생성된 이미지와 실제 이미지를 함께 판별자에 입력
  3. 판별자는 입력 이미지를 실존 이미지인지 판별. 0은 가짜, 1은 실제

생성자는 일반적인 합성곱 신경망을 뒤집은 구조이다.

이미지는 학습 데이터에 포함된 이미지와 비슷한 크기가 될 때까지 업스케일링 된다.

 

8.1.1 심층 합성곱 GAN

심층 합성곱 Deep Convolutional GAN은 GAN의 판별자 신경망에 합성곱층을 사용하여 예측 능력을 향상한 구조이다.

이를 통해 전체 모델의 성능을 향상시킬 수 있다.

DCGAN은 2016년에 제안되었으며, 현재 대부분의 GAN에서 합성곱층을 사용하므로 GAN과 DCGAN은 동일한 의미로 사용된다. 이

책에서도 DCGAN은 GAN과 DCGAN을 모두 가리키는 용어로 사용된다.

 

8.1.2 판별자 모델

판별자의 목표는 생성자가 만든 가짜 이미지와 실제 이미지를 구분하는 분류 문제이다.

판별자 모델은 일련의 합성곱층 다음에 시그모이드 함수를 활성화 함수로 사용하는 전결합층이 연결된 구조로 이루어져 있다.

시그모이드 함수는 이진 분류에 적합한 함수로, 출력이 0이면 가짜를 나타내고 1이면 실제를 나타낸다.

판별자 모델은 이미 잘 알려진 분류 모델로, 학습 과정에서 실제 이미지와 생성자가 만든 가짜 이미지를 입력으로 사용하여 학습한다.

 

 

케라스를 사용해서 판별자 신경망을 구현해보자.

먼저 discriminator_model 함수를 구현한다. 입력 이미지의 크기는 28x28이다.

def build_discriminator():

    model = Sequential()

    model.add(Conv2D(32, kernel_size=3, strides=2, input_shape= img_shape, padding="same"))
    model.add(LeakyReLU(alpha=0.2)) # 누설 ReLU 활성화 함수를 모델에 추가
    model.add(Dropout(0.25))

    model.add(Conv2D(64, kernel_size=3, strides=2, padding="same")) # 이때 패딩적용 안 함
    model.add(ZeroPadding2D(padding=((0,1),(0,1))))
    
    # 학습 시간 단축 및 정확도 향상을 위해 배치 정규화 층을 추가
    model.add(BatchNormalization(momentum=0.8))
    model.add(LeakyReLU(alpha=0.2))
    model.add(Dropout(0.25))

	# 배치 정규화, 누설 ReLU, 드롭아웃을 적용한 세 번째 합성곱층을 모델에 추가
    model.add(Conv2D(128, kernel_size=3, strides=2, padding="same"))
    model.add(BatchNormalization(momentum=0.8))
    model.add(LeakyReLU(alpha=0.2))
    model.add(Dropout(0.25))
    
	# 마찬가지로 배치 정규화 누설 ReLU, 드롭아웃을 적용한 네 번째 합성곱층을 추가 
    model.add(Conv2D(256, kernel_size=3, strides=1, padding="same"))
    model.add(BatchNormalization(momentum=0.8))
    model.add(LeakyReLU(alpha=0.2))
    model.add(Dropout(0.25))
	
    # 1차원 변환층과 시그모이드 활성화 함수를 사용하는 전결합층을 추가
    model.add(Flatten())
    model.add(Dense(1, activation='sigmoid'))

    model.summary()

	# 입력 이미지 크기를 설정
    img = Input(shape= img_shape)
    
    # 판별자 모델을 이용해서 이미지가 진짜일 확률을 계산한다.
    validity = model(img)

    return Model(img, validity)

이들 층의 하이퍼파라미터는 판별자 모델을 학습시킬 때 조장할 것이다.

출력된 모델의 개요를 보면 출력 특징 맵의 크기는 감소하고 깊이는 증가한다.

익히 보아온 일반적인 CNN 구조와 같다.

 

8.1.3 생성자 모델

생성자 모델은 무작위 데이터를 입력으로 받아 훈련 데이터와 비슷한 가짜 이미지를 생성한다. 목표는 생성된 이미지가 판별자 모델에 의해 진짜로 판단될 수 있을 만큼 실제 데이터와 유사하게 만드는 것이다.

학습이 진행됨에 따라 생성자는 점점 실제 이미지에 근접한 이미지를 생성하도록 발전해야 한다. 판별자 모델은 가짜 이미지를 구분하는 능력을 함께 학습하므로 생성자는 더 진짜 같은 이미지를 생성해야 한다.

생성자 모델의 구조는 합성곱 신경망의 층을 역순으로 배치한 형태를 가지고 있다.

무작위 노이즈 값을 입력으로 받아 이를 너비, 높이, 깊이를 가진 3차원 텐서로 변환한다. 이 텐서는 특징 맵으로 간주되며, 이어지는 합성곱층을 통해 최종적인 이미지를 생성한다.

특징 맵의 크기를 키우는 업샘플링

케라스는 확대 배율(size)을 설정해서 이미지를 업샘플링 하는 업샘플링층을 제공한다.

keras.layers.UpSampling2D(size=(2,2))

해당 코드를 실행하면 설정된 크기에 맞추어 행렬의 각 값이 행과 열 방향으로 두 번씩 반복된 행렬을 얻게 된다.

생성자 모델은 훈련 데이터와 비슷한 크기가 될 때까지 업샘플링을 반복하도록 구성한다.

def build_generator():

    model = Sequential() # 순차 모델 객체를 만든다.

	# 뉴런 수가 128 7 7개인 전결합층을 가장 먼저 추가한다.
    model.add(Dense(128 * 7 * 7, activation="relu", input_dim= latent_dim))
    model.add(Reshape((7, 7, 128)))
    model.add(UpSampling2D(size=(2,2))) # 이미지의 크기를 14x14로 두 배 늘리는 업샘플링

	# 합성곱층 및 배치 정규화층
    model.add(Conv2D(128, kernel_size=3, padding="same"))
    model.add(BatchNormalization(momentum=0.8))
    model.add(Activation("relu"))
    model.add(UpSampling2D(size=(2,2)))

	# 합성곱층 + 배치 정규화층
    # 데이터셋의 이미지와 같은 28x28까지 업샘플링 됐으므로 더 이상 하지 않는다.
    model.add(Conv2D(64, kernel_size=3, padding="same"))
    model.add(BatchNormalization(momentum=0.8))
    model.add(Activation("relu"))

	# 필터가 1개인 합성곱층
    model.add(Conv2D(channels, kernel_size=3, padding="same"))
    model.add(Activation("tanh"))

    model.summary()

	# 길이가 lantent_dim인 노이즈 벡터를 생성한다.
    noise = Input(shape=(latent_dim,))
    img = model(noise) # 가짜 이미지를 생성한다.

    return Model(noise, img)

판별자 모델과 결정적으로 다른 부분은 1차원 벡터를 입력한다는 점이다.

깊이가 1까지 감소하는 이유는 이 모델이 회색조 이미지인 MNIST 데이터셋을 다루기 때문이다.

 

8.1.4 GAN의 학습

GAN의 학습은 판별자 모델과 생성자 모델의 학습 과정으로 구성된다.

판별자 모델은 실제 이미지와 생성자가 생성한 가짜 이미지를 올바르게 분류하도록 학습되며, 생성자 모델은 판별자를 속일 수 있는 능력을 향상하기 위해 학습된다.

학습은 두 가지 과정으로 이루어진다.

  1. 판별자 모델의 학습:
    이는 일반적인 지도 학습 모델의 학습과 유사하다. 생성자가 생성한 가짜 이미지와 훈련 데이터의 진짜 이미지를 레이블과 함께 입력하여 이미지의 진위 여부를 확률값으로 예측한다.
  2. 생성자 모델의 학습:
    생성자 모델은 판별자 모델과 함께 학습되어야 한다. 생성자가 생성한 가짜 이미지가 얼마나 진짜 같은지를 판별자 모델이 평가해야 한다. 따라서 판별자와 생성자를 통합한 신경망을 구성하여 생성자 모델의 학습을 진행한다.

이 두 가지 학습 과정은 병렬로 진행된다. 판별자 모델은 단독으로 학습되고, 생성자 모델은 통합 신경망을 통해 학습된다.

생성자 모델의 학습 방식이 이렇게 되는 이유는 나중에 자세히 설명하겠다.

현재는 판별자와 생성자 2개의 모델을 만들되, 판별자는 단독 학습이 가능하고 생성자는 판별자가 있어야만 학습이 가능하다고 이해하면 된다.

이 병렬 학습 과정은 순방향 계산과 역전파를 통해 가중치를 수정하는 기본적인 신경망의 학습과정을 따른다.

판별자 모델은 역전파를 통해 가중치를 수정하고, 통합 신경망은 생성자 모델의 가중치를 수정하기 위해 역전파를 사용한다.

 

1) 판별자 모델 학습

일반적인 신경망의 학습 과정과 다를 바 없다.

앞서 만든 모델을 컴파일하고, binary_crossentropy를 손실함수로 사용하고, 최적화 알고리즘은 원하는 것을 사용한다.

# Build and compile the discriminator
discriminator = build_discriminator()
discriminator.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])

무작위 데이터를 사용해서 학습을 진행하는 케라스의 train_on_batch 메서드를 사용하여 배치 1개를 입력해 가중치를 한 번 수정하는 코드를 살펴보다.

# Sample noise and generate a batch of new images
noise = np.random.normal(0, 1, (batch_size, 100)) # 노이즈 데이터
gen_imgs = generator.predict(noise) # 새로운 이미지를 한 배치 생성하기

# Train the discriminator (real classified as ones and generated as zeros)
# 판별자 모델의 학습 (가짜 = 0, 진짜 = 1)
d_loss_real = discriminator.train_on_batch(imgs, valid)
d_loss_fake = discriminator.train_on_batch(gen_imgs, fake)

 

2) 생성자 모델의 학습(통합 신경망)

해당 모델의 학습 과정은 까다롭다.

생성자 모델의 학습에는 판별자 모델이 꼭 필요하다. (판별자는 독립!)

생성자 모델의 학습을 진행할 때는 판별자 모델의 가중치를 고정해야 한다.

생성자 모델과 판별자 모델의 손실 함수가 서로 다르기 때문에 수정 방향도 서로 다르기 때문이다.

통합 신경망을 당음과 같이 구현한다.

# Build the generator
generator = build_generator()

# The generator takes noise as input and generates imgs
z = Input(shape=(latent_dim,))
img = generator(z)

# For the combined model we will only train the generator
# 판별자 모델의 가중치르 고정한다.
discriminator.trainable = False

# The discriminator takes generated images as input and determines validity
valid = discriminator(img)

# The combined model  (stacked generator and discriminator)
# Trains the generator to fool the discriminator
combined = Model(z, valid)

통합 신경망을 구성했으니 기존 방법대로 학습을 진행할 수 있다.

combined.compile(loss='binary_crossentropy', optimizer=optimizer)

# 판별자 모델이 가짜 이미지를 진짜 이미지라고 생각하게 만들 수 있도록 생성자 모델을 학습시킨다.
g_loss = combined.train_on_batch(noise, valid)

에포크가 진행됨에 따라 생성된 이미지가 점점 판별자 모델을 속일 수 있을 만큼 학습 데이터와 비슷해진다.

 

8.1.5 GAN 미니맥스 함수

GAN의 학습은 제로섬 게임과 관련된 미니맥스 함수에 기반하고 있다. 이 함수는 최적화 문제보다는 제로섬 게임의 개념을 따르며, 두 참가자 간의 경쟁적인 상황을 나타낸다.

GAN은 신경망이 다음과 같이 정의되는 함수 V(D, G)의 최적화를 시도하는 미니맥스 게임이다.

 

판별자 모델은 실제 이미지와 생성자 모델이 생성한 가짜 이미지를 올바르게 분류하는 것을 목표로 학습한다. 반면 생성자 모델은 판별자 모델을 최대한 속일 수 있도록 학습한다.

이러한 학습 과정은 두 모델이 자신의 역할에 점점 능숙해지도록 한다.

GAN의 미니맥스 함수에서 판별자 모델의 목표는 진짜 데이터에 대한 예측을 최대화하고 가짜 데이터에 대한 예측을 최소화하는 것이다.

생성자 모델의 목표는 판별자 모델이 가짜 데이터를 최대한으로 잘못 판정하도록 만드는 것이다.

판별자 모델은 진짜 데이터와 가짜 데이터를 입력으로 받아 분류를 수행하며, 생성자 모델이 만든 가짜 이미지와 실제 데이터 이미지를 판별한다.

GAN의 학습은 두 가지 분기로 나누어져 있으며, 각각 판별자 모델과 생성자 모델의 학습에 한다. 이 두 분기는 미니맥스 게임의 개념을 따르며, 각각 다른 오차 함수를 사용하여 학습이 진행된다.

학습 초기에는 생성자 모델이 만든 가짜 이미지가 실제 이미지와 많이 다르기 때문에 판별자 모델은 가짜 이미지를 높은 확신도로 판별할 수 있다.

하지만 학습이 진행됨에 따라 판별자 모델은 진짜와 가짜 이미지를 정확하게 판별하도록 학습되고, 생성자 모델은 판별자 모델을 속이도록 학습한다. 생성자 모델이 판별자 모델을 속이게 되는 시점에 학습을 중단한다.

 

8.2 GAN 모델의 평가 방법

GAN 모델의 평가 방법은 생성자 모델의 학습에 사용되는 손실 함수가 없어서 모델의 성능을 손실을 기준으로 평가하기 어렵다.

대신, 생성된 이미지의 품질을 사람이 직접 평가하는 방식을 주로 사용하거나, 사람 평가자가 개입하지 않는 방법도 사용한다.

GAN 연구 논문에서 서술한 저자가 자신의 모델을 평가한 방법을 참고할 수 있으며, 저자는 사람 평가자를 고용하여 생성된 이미지와 실제 이미지를 구분하도록 했다.

그러나 사람 평가자의 주관적인 평가나 피드백에 의해 측정값이 일정하지 않거나 변동이 발생하는 단점이 있다.

이 때문에 현재는 생성된 이미지의 품질과 다양성을 정량적으로 측정하는 방법이 연구되고 있다.

예를 들어, 인셉션 점수와 프레셉티언 거리(FID)는 널리 사용되는 평가 지표이다. 

그러나 GAN 모델의 평가에는 아직 일반적으로 인정된 방법이 없어서 연구자나 실무자는 모델의 성능을 선택하고 학습 중단 시점을 결정하는 등 어려움을 겪을 수 있다.

 

8.2.1 인셉션 점수

인셉션 점수는 생성된 이미지의 품질과 다양성을 평가하는 기법으로, 사전 학습된 인셉션 모델에 생성된 이미지를 입력하여 분류 결과를 확인한다.

여러 이미지를 생성하여 분류 모델로 분류하고 예측 확률을 계산하여 평가한다. 생성된 이미지의 예측 점수가 높을수록 품질이 높으며, 다양성도 고려된다. 

  • 예측 점수가 높을 것: 분류 결과가 생성한 이미지와 어긋나지 않는다면 그 확신도를 해당 이미지의 예측 점수로 삼는다.
  • 다양성이 높을 것: 생성된 이미지가 특정 클래스에 치우쳐서는 안 된다.

 

8.2.2 프레셰 인셉션 거리

프레셰 인셉션 거리(FID)는 GAN 모델의 평가 기법으로, 인셉션 점수를 개선한 방식이다.

일련의 실제 이미지와 생성된 이미지를 분류 모델에 입력하여 출력을 수집하고, 이들 값의 다변량 가우시안 분포를 구한 뒤 두 분포 사이의 프레셰 거리를 계산한다.

FID는 많은 수의 이미지(5만 장 이상 권장)를 필요로 하며, FID 점수가 낮을수록 생성된 이미지와 실제 이미지의 분포가 비슷하다고 판단된다

 

8.2.3 평가 방법 선택 요령

인셉션 점수와 FID는 생성된 이미지를 입력하여 점수를 측정하는 방식으로, 학습 도중에 모델의 상태를 저장하고 측정에 사용할 이미지를 생성해 두어 모델 선택에 활용해야 한다.

GAN 모델의 평가 방법에 대해 학계나 업계에서 합의한 표준은 없으며, 다양한 평가 기법이 존재한다.

GAN 모델 개발 초기에는 생성된 이미지를 사람이 직접 평가하여 모델을 선택하는 것이 좋으며, GAN 모델 개발은 복잡한 작업이기 때문에 시간이 많이 소요된다.

인셉션 점수와 FID 외에도 도메인별 평가 기법을 적용할 수 있다.

예를 들어, 2018년에 콘스탄틴 슈멜코프는 이미지 분류 기반의 두 가지 평가 지표인 GAN-train과 GAN-test를 제안했다.

이들은 각각 재현율(다양성)과 정확도(이미지의 품질)를 평가하는 지표다.

 

8.3 GAN 응용 분야

8.3.1 문장으로부터 이미지 생성하기

StackGAN은 문장으로부터 이미지를 생성하는 GAN 응용 분야이다.

기존의 GAN은 이미지를 생성하는 데에 사용되었지만, StackGAN은 텍스트 입력을 받아 해당하는 이미지를 생성한다.

이를 위해 StackGAN은 두 개의 GAN을 사용한다.

첫 번째 GAN은 문장에서 저해상도 이미지를 생성하고, 두 번째 GAN은 이 저해상도 이미지를 고해상도로 변환하여 실제와 유사한 이미지를 생성한다.

StackGAN은 텍스트로부터 사실적이고 다양한 이미지 생성을 가능하게 해 준다.

 

8.3.2 이미지-이미지 번역

Pix2Pix는 이미지 간 변환을 수행하는 GAN 응용 분야이다.

주어진 입력 이미지와 목표 출력 이미지를 쌍으로 학습시켜, 입력 이미지를 원하는 출력 이미지로 변환하는 모델을 생성한다.

예를 들어, 흑백 사진을 컬러로 변환하거나 낮과 밤 사진을 변환하는 등의 작업이 가능하다.

Pix2Pix는 Conditional GAN의 개념을 사용하여 입력 이미지와 목표 출력 이미지 사이의 관계를 학습하고, 생성자와 판별자를 함께 훈련하여 높은 품질의 이미지 변환을 수행한다.

Pix2Pix 모델의 새로운 개선점은 과업과 데이터에 맞춰 손실 함수를 학습할 수 있어 다양한 상황에 적용할 수 있다는 것이다.

Pix2Pix는 출력 이미지가 입력 이미지에 의해 결정되는 일종의 조건부 GAN인데, 판별자 모델이 원 이미지와 이를 바탕으로 생성된 이미지를 모두 입력받아 생성된 이미지가 원 이미지를 적절하게 변환한 것인지 판별한다.

 

8.3.3 초해상도 이미징 GAN

SRGAN은 고해상도 이미지를 생성하는 GAN 응용 분야이다.

저해상도 입력 이미지를 고해상도 이미지로 변환하는 작업을 수행한다.

일반적으로, 이미지의 해상도를 높이는 것은 정보의 손실과 화질 저하를 초래할 수 있지만, SRGAN은 GAN을 사용하여 더욱 세부적이고 실제와 유사한 고해상도 이미지를 생성한다.

SRGAN은 저해상도 이미지와 고해상도 이미지의 쌍을 사용하여 생성자와 판별자를 훈련시키고, 저해상도 입력 이미지를 높은 해상도로 변환하는 능력을 갖춘 모델을 구축한다.

SRGAN은 예술 작품, 의료 영상, 영화 및 비디오 게임 등 다양한 분야에서 사용될 수 있다.

다음 게시물을 통해 GAN 모델을 직접 구현해 보는 프로젝트를 진행해 보겠다.

반응형