[파이썬] 이미지 생성을 위한 GAN 활용

GAN(Generative Adversarial Networks)은 주로 이미지 생성에 사용되는 딥러닝 모델입니다. GAN은 생성자(generator)와 판별자(discriminator)라는 두 개의 신경망으로 이루어져 있으며, 생성자는 실제같은 이미지를 생성하려고 하고 판별자는 실제 이미지와 생성자로부터 생성된 이미지를 구별하려고 합니다. 이 두 신경망은 서로 경쟁하면서 학습하여 점점 더 진짜같은 이미지를 생성할 수 있도록 개선됩니다.

이번 포스트에서는 Python을 사용하여 GAN을 활용하여 이미지를 생성하는 방법을 알아보겠습니다.

패키지 설치

GAN 모델을 만들기 위해서는 몇 가지 패키지를 설치해야 합니다. 다음 명령어를 사용하여 필요한 패키지를 설치합니다:

pip install tensorflow
pip install keras
matplotlib

필요한 데이터셋 가져오기

GAN을 학습시키기 위해서는 생성할 이미지에 대한 학습 데이터셋이 필요합니다. 여기서는 CIFAR-10 데이터셋을 사용하겠습니다. CIFAR-10은 10개의 다른 클래스로 구성된 6만 개의 32x32 컬러 이미지로 이루어져 있습니다.

from keras.datasets import cifar10

(X_train, _), (_, _) = cifar10.load_data()

# 데이터 정규화
X_train = (X_train.astype('float32') - 127.5) / 127.5

생성자 모델 만들기

GAN의 생성자 모델은 랜덤 노이즈로부터 실제같은 이미지를 생성하려고 합니다. 일반적으로 생성자 모델은 전체 모델 중 하위 부분을 구성합니다. 다음은 생성자 모델을 만드는 예시 코드입니다:

from keras.models import Sequential
from keras.layers import Dense, Reshape, Conv2D, UpSampling2D

def build_generator():
    model = Sequential()
    model.add(Dense(128 * 8 * 8, input_dim=100))
    model.add(Reshape((8, 8, 128)))
    model.add(Conv2D(128, kernel_size=3, padding='same'))
    model.add(UpSampling2D())
    model.add(Conv2D(64, kernel_size=3, padding='same'))
    model.add(UpSampling2D())
    model.add(Conv2D(3, kernel_size=3, padding='same', activation='tanh'))
    return model

generator = build_generator()

판별자 모델 만들기

판별자 모델은 생성자로부터 생성된 이미지와 실제 이미지를 구별하는 역할을 합니다. 판별자 모델도 생성자 모델과 마찬가지로 전체 모델 중 하위 부분을 구성합니다:

from keras.layers import Flatten, Dropout

def build_discriminator():
    model = Sequential()
    model.add(Conv2D(64, kernel_size=3, padding='same', input_shape=(32, 32, 3)))
    model.add(Flatten())
    model.add(Dropout(0.4))
    model.add(Dense(1, activation='sigmoid'))
    return model

discriminator = build_discriminator()

GAN 모델 만들기

GAN 모델은 생성자와 판별자를 연결하여 학습하기 위한 최종 모델입니다. 이 모델은 생성자와 판별자를 동시에 학습시키는 역할을 합니다:

from keras.models import Model
from keras.optimizers import Adam

# 판별자의 학습 비활성화
discriminator.trainable = False

gan_input = Input(shape=(100,))
generated_image = generator(gan_input)
gan_output = discriminator(generated_image)

gan = Model(gan_input, gan_output)
gan.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.0002, beta_1=0.5))

GAN 모델 학습하기

GAN 모델을 학습시키기 위해서는 생성자와 판별자를 번갈아 가면서 학습시켜야 합니다. 학습 과정은 다음과 같이 이루어집니다:

batch_size = 64

for epoch in range(epochs):
    # 실제 이미지 batch 만들기
    batch_real = X_train[np.random.randint(0, X_train.shape[0], size=batch_size)]
    # 랜덤 노이즈 batch 만들기
    noise = np.random.normal(0, 1, size=(batch_size, 100))
    # 가짜 이미지 batch 생성하기
    batch_fake = generator.predict(noise)

    # 판별자 학습
    discriminator.trainable = True
    d_loss_real = discriminator.train_on_batch(batch_real, np.ones((batch_size, 1)))
    d_loss_fake = discriminator.train_on_batch(batch_fake, np.zeros((batch_size, 1)))
    d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)

    # 생성자 학습
    discriminator.trainable = False
    g_loss = gan.train_on_batch(noise, np.ones((batch_size, 1)))

    # 학습 과정 출력
    print("Epoch: {}/{} | Discriminator Loss: {} | Generator Loss: {}".format(epoch, epochs, d_loss, g_loss))

이미지 생성하기

학습이 완료된 GAN 모델을 사용하여 새로운 이미지를 생성할 수 있습니다. 다음과 같이 랜덤 노이즈로부터 이미지를 생성하는 함수를 만듭니다:

import matplotlib.pyplot as plt

def generate_images():
    noise = np.random.normal(0, 1, size=(10, 100))
    generated_images = generator.predict(noise)

    fig, axes = plt.subplots(2, 5)
    count = 0
    for i in range(2):
        for j in range(5):
            axes[i, j].imshow(generated_images[count, :, :, :])
            axes[i, j].axis('off')
            count += 1

    plt.show()

generate_images()

이제 GAN 모델을 사용하여 이미지를 생성하는 방법에 대해 알게 되었습니다. GAN은 다양한 이미지 생성 작업에 사용될 수 있으며, 더 복잡한 모델과 데이터셋을 사용하여 놀라운 결과를 얻을 수 있습니다. 실험을 통해 GAN 모델을 직접 만들어보고 다양한 이미지 생성 작업에 도전해보세요!