[파이썬] 딥러닝을 통한 이미지 생성 및 변환

컴퓨터 비전 분야에서 딥러닝은 이미지를 생성하거나 변환하는데 매우 강력한 도구로 사용됩니다. 딥러닝을 사용하면 특정 이미지의 특징을 추출하거나, 이미지를 생성하여 새로운 이미지를 만들 수 있습니다. 이번 블로그에서는 Python을 사용하여 딥러닝을 통한 이미지 생성 및 변환에 대해 알아보겠습니다.

이미지 생성

생성적 적대 신경망 (GAN)

GAN은 생성자판별자라는 두 개의 신경망을 사용하여 이미지를 생성하는 방법입니다. 생성자는 랜덤한 노이즈 벡터를 입력으로 받아 실제 이미지와 비슷한 가짜 이미지를 생성합니다. 판별자는 생성자가 생성한 가짜 이미지와 실제 이미지를 구별하는 역할을 합니다. 이러한 생성자와 판별자의 경쟁을 통해 점점 더 진짜 같은 가짜 이미지를 생성할 수 있게 됩니다.

import tensorflow as tf
from tensorflow.keras import layers

# 생성자 모델 생성
def make_generator_model():
    model = tf.keras.Sequential()
    model.add(layers.Dense(7*7*256, use_bias=False, input_shape=(100,)))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Reshape((7, 7, 256)))
    assert model.output_shape == (None, 7, 7, 256)  # None은 배치 크기

    model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))
    assert model.output_shape == (None, 7, 7, 128)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))
    assert model.output_shape == (None, 14, 14, 64)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))
    assert model.output_shape == (None, 28, 28, 1)

    return model

generator = make_generator_model()

가장자리 강화 생성적 적대 신경망 (WGAN-GP)

WGAN-GP는 기존의 GAN의 한계를 극복하기 위해 제안된 모델로, 생성자의 출력이 실제 이미지와 거의 구별이 안되는 경우가 있습니다. 그렇기 때문에 실제 이미지의 가장자리를 강화하기 위해 판별자에 Gradient Penalty를 적용합니다. 이를 통해 더욱 실제 이미지와 유사한 이미지를 생성할 수 있게 됩니다.

import tensorflow as tf
from tensorflow.keras import layers

# 생성자 모델 생성
def make_generator_model():
    model = tf.keras.Sequential()
    model.add(layers.Dense(7*7*256, use_bias=False, input_shape=(100,)))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Reshape((7, 7, 256)))
    assert model.output_shape == (None, 7, 7, 256)  # None은 배치 크기

    model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))
    assert model.output_shape == (None, 7, 7, 128)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))
    assert model.output_shape == (None, 14, 14, 64)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))
    assert model.output_shape == (None, 28, 28, 1)

    return model

generator = make_generator_model()

이미지 변환

오토인코더 (Autoencoder)

오토인코더는 입력 데이터를 압축하여 잠재 공간에 표현한 후, 그 잠재 공간에서 원래의 입력 데이터를 복원하는 방식입니다. 이를 통해 이미지 변환 작업, 예를 들어 흑백 이미지를 컬러 이미지로 변환하는 작업 등을 수행할 수 있습니다.

import tensorflow as tf
from tensorflow.keras import layers

# 오토인코더 모델 생성
def make_autoencoder_model():
    input_image = tf.keras.Input(shape=(28,28,1))
    encoded = layers.Conv2D(16, (3, 3), activation='relu', padding='same')(input_image)
    encoded = layers.MaxPooling2D((2, 2), padding='same')(encoded)
    encoded = layers.Conv2D(8, (3, 3), activation='relu', padding='same')(encoded)
    encoded = layers.MaxPooling2D((2, 2), padding='same')(encoded)
    encoded = layers.Conv2D(8, (3, 3), activation='relu', padding='same')(encoded)
    encoded = layers.MaxPooling2D((2, 2), padding='same')(encoded)

    decoded = layers.Conv2D(8, (3, 3), activation='relu', padding='same')(encoded)
    decoded = layers.UpSampling2D((2, 2))(decoded)
    decoded = layers.Conv2D(8, (3, 3), activation='relu', padding='same')(decoded)
    decoded = layers.UpSampling2D((2, 2))(decoded)
    decoded = layers.Conv2D(16, (3, 3), activation='relu')(decoded)
    decoded = layers.UpSampling2D((2, 2))(decoded)
    decoded = layers.Conv2D(1, (3, 3), activation='sigmoid', padding='same')(decoded)

    autoencoder = tf.keras.Model(input_image, decoded)
    return autoencoder

autoencoder = make_autoencoder_model()

변이형 오토인코더 (Variational Autoencoder)

변이형 오토인코더는 오토인코더와 유사하지만, 잠재 공간에 대한 제약 조건을 추가하여 잠재 공간을 더욱 정규화합니다. 이를 통해 노이즈가 있는 이미지를 클리어한 이미지로 변환하는 등의 작업을 수행할 수 있습니다.

import tensorflow as tf
from tensorflow.keras import layers

# 변이형 오토인코더 모델 생성
def make_variational_autoencoder_model():
    input_image = tf.keras.Input(shape=(28,28,1))
    encoded = layers.Conv2D(16, (3, 3), activation='relu', padding='same')(input_image)
    encoded = layers.MaxPooling2D((2, 2), padding='same')(encoded)
    encoded = layers.Conv2D(8, (3, 3), activation='relu', padding='same')(encoded)
    encoded = layers.MaxPooling2D((2, 2), padding='same')(encoded)
    encoded = layers.Flatten()(encoded)
    encoded_mean = layers.Dense(16)(encoded)
    encoded_log_var = layers.Dense(16)(encoded)

    def sampling(args):
        encoded_mean, encoded_log_var = args
        epsilon = tf.keras.backend.random_normal(shape=(16,), mean=0., stddev=1.)
        return encoded_mean + tf.keras.backend.exp(0.5 * encoded_log_var) * epsilon

    encoded_sample = layers.Lambda(sampling)([encoded_mean, encoded_log_var])

    decoder_input = layers.Input(shape=(16,))
    decoded = layers.Dense(7*7*64, activation='relu')(decoder_input)
    decoded = layers.Reshape((7, 7, 64))(decoded)
    decoded = layers.Conv2DTranspose(32, (3, 3), activation='relu', padding='same')(decoded)
    decoded = layers.UpSampling2D((2, 2))(decoded)
    decoded = layers.Conv2DTranspose(32, (3, 3), activation='relu', padding='same')(decoded)
    decoded = layers.UpSampling2D((2, 2))(decoded)
    decoded = layers.Conv2DTranspose(1, (3, 3), activation='sigmoid', padding='same')(decoded)

    encoder = tf.keras.Model(input_image, [encoded_mean, encoded_log_var, encoded_sample])
    decoder = tf.keras.Model(decoder_input, decoded)

    output_image = decoder(encoder(input_image)[2])
    variational_autoencoder = tf.keras.Model(input_image, output_image)

    return variational_autoencoder

variational_autoencoder = make_variational_autoencoder_model()

마치며

위에서는 딥러닝을 통해 이미지 생성 및 변환에 대해 간략히 알아보았습니다. 실제로 딥러닝을 사용하여 다양한 이미지 생성 및 변환 작업을 수행하면서 더욱 흥미로운 결과를 얻을 수 있을 것입니다. 이러한 기술은 컴퓨터 비전 분야뿐만 아니라 디자인, 예술, 영화 등 다양한 분야에서도 활용될 수 있습니다. 딥러닝을 통한 이미지 생성 및 변환에 대해 더 깊게 공부하고 적용해보시길 바랍니다.