Python/Deep Learning

DCGAN(Deep Convolutional GAN) 구현

임베디드 친구 2026. 2. 22. 13:01
728x90
반응형

DCGAN(Deep Convolutional GAN) 구현

1. DCGAN이란?

DCGAN(Deep Convolutional Generative Adversarial Network)은 기본적인 GAN(Generative Adversarial Network)에 합성곱 신경망(Convolutional Neural Network, CNN)을 결합한 모델입니다. 이는 Ian Goodfellow가 제안한 GAN을 발전시킨 형태로, 이미지를 보다 사실적으로 생성할 수 있도록 설계되었습니다.

기존 GAN에서는 Fully Connected Layer 기반의 네트워크를 사용하였으나, DCGAN은 합성곱 신경망을 사용하여 공간적 구조를 보다 잘 학습하도록 개선되었습니다. 주요 특징은 다음과 같습니다.

  • 합성곱층(Convolutional Layers) 활용: Fully Connected Layer 대신 CNN을 사용하여 데이터의 공간적 특징을 효과적으로 학습
  • 배치 정규화(Batch Normalization) 적용: 학습을 안정화하고 빠르게 진행
  • Leaky ReLU 사용: Generator와 Discriminator의 활성화 함수로 사용하여 기울기 소실 문제를 완화

본 포스팅에서는 DCGAN을 TensorFlow/Keras를 이용하여 구현하는 방법을 자세히 설명하겠습니다.


2. DCGAN의 구성 요소

DCGAN은 기본적으로 두 개의 신경망으로 구성됩니다.

  1. 생성자(Generator): 무작위 노이즈(z)를 입력으로 받아 가짜 이미지를 생성
  2. 판별자(Discriminator): 입력된 이미지가 실제(real)인지 가짜(fake)인지 분류

두 네트워크가 경쟁적으로 학습하면서 생성자는 점점 더 사실적인 이미지를 만들어내도록 훈련됩니다.


3. DCGAN 구현 (TensorFlow/Keras 기반)

3.1 환경 설정 및 라이브러리 불러오기

아래와 같이 필요한 라이브러리를 불러옵니다.

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
import matplotlib.pyplot as plt

3.2 데이터셋 준비 (MNIST 데이터셋 사용)

DCGAN을 학습하기 위해 손글씨 데이터셋(MNIST)을 사용합니다.

# MNIST 데이터 로드
(x_train, _), (_, _) = keras.datasets.mnist.load_data()

# 데이터 정규화 (-1 ~ 1 범위)
x_train = (x_train.astype(np.float32) - 127.5) / 127.5
x_train = np.expand_dims(x_train, axis=-1)  # 채널 차원 추가

BUFFER_SIZE = 60000
BATCH_SIZE = 256

# 데이터 배치 설정
dataset = tf.data.Dataset.from_tensor_slices(x_train).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)

3.3 생성자(Generator) 모델 정의

생성자는 노이즈 벡터를 받아서 가짜 이미지를 생성합니다. 업샘플링(Transpose Convolution)을 통해 점점 큰 크기의 이미지를 생성하도록 설계됩니다.

def build_generator():
    model = keras.Sequential([
        layers.Dense(7*7*256, use_bias=False, input_shape=(100,)),
        layers.BatchNormalization(),
        layers.LeakyReLU(),
        layers.Reshape((7, 7, 256)),

        layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False),
        layers.BatchNormalization(),
        layers.LeakyReLU(),

        layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False),
        layers.BatchNormalization(),
        layers.LeakyReLU(),

        layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh')
    ])
    return model

# 생성자 모델 생성
generator = build_generator()
generator.summary()

3.4 판별자(Discriminator) 모델 정의

판별자는 입력된 이미지가 실제인지 가짜인지 판별하는 CNN 기반 신경망입니다.

def build_discriminator():
    model = keras.Sequential([
        layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same', input_shape=[28, 28, 1]),
        layers.LeakyReLU(),
        layers.Dropout(0.3),

        layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'),
        layers.LeakyReLU(),
        layers.Dropout(0.3),

        layers.Flatten(),
        layers.Dense(1, activation='sigmoid')
    ])
    return model

# 판별자 모델 생성
discriminator = build_discriminator()
discriminator.summary()

3.5 손실 함수 및 최적화 기법 설정

cross_entropy = keras.losses.BinaryCrossentropy(from_logits=True)

def generator_loss(fake_output):
    return cross_entropy(tf.ones_like(fake_output), fake_output)

def discriminator_loss(real_output, fake_output):
    real_loss = cross_entropy(tf.ones_like(real_output), real_output)
    fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)
    return real_loss + fake_loss

# 옵티마이저 설정
generator_optimizer = keras.optimizers.Adam(1e-4)
discriminator_optimizer = keras.optimizers.Adam(1e-4)

3.6 학습 루프 구현

EPOCHS = 50
noise_dim = 100
num_examples_to_generate = 16
seed = tf.random.normal([num_examples_to_generate, noise_dim])

def train_step(images):
    noise = tf.random.normal([BATCH_SIZE, noise_dim])

    with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
        generated_images = generator(noise, training=True)

        real_output = discriminator(images, training=True)
        fake_output = discriminator(generated_images, training=True)

        gen_loss = generator_loss(fake_output)
        disc_loss = discriminator_loss(real_output, fake_output)

    gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)
    gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables)

    generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))
    discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables))

3.7 학습 실행 및 결과 시각화

def train(dataset, epochs):
    for epoch in range(epochs):
        for image_batch in dataset:
            train_step(image_batch)

        # 결과 이미지 출력
        generate_and_save_images(generator, epoch + 1, seed)

DCGAN을 학습시키면 점점 더 사실적인 숫자 이미지를 생성할 수 있습니다. 본 포스팅에서는 DCGAN의 개념과 구현을 TensorFlow/Keras를 이용해 설명하였습니다.

반응형