본문 바로가기

프로젝트

무이메이커스_간 (GAN) 을 활용한 인공지능 (AI) 이미지 변환 (Image Translation) 딥러닝 프로젝트

프로젝트 진행 순서

  • 1. 간 (GAN) 을 통한 인공지능 (AI) 이미지 변환 (Image Translation) 개요
  • 2. 이미지 데이터 전처리 (Image Preprocessing)
  • 3. 딥러닝 모델 생성
  • 4. 모델 평가 및 시각화 (Evaluation and Visualization)
  • 5. 실생활 적용

 

안녕하세요 헬스케어 제품 개발회사 허니컴의 무이메이커스페이스 입니다.

저희는 4차산업혁명을 맞이하여 딥러닝을 접목시킨 제품 개발을 위해 다양한 프로젝트를 수행하고,

이를 활용하여 인공지능 (AI) 을 지닌 다양한 헬스케어 제품을 생산하는데 그 목적이 있습니다.

이번 시간에는 딥러닝 모델 중 하나인 간 (GAN) 을 활용하여 만든 인공지능 (AI) 으로

이미지를 다른 이미지로 변환하는 (Image Translation) 프로젝트를 소개하고자 합니다.

목표는 주어진 도메인의 이미지를 다른 도메인의 이미지로 변환하는 것으로,

다양한 간 (GAN) 모델 중 하나의 도메인에서 다른 도메인으로 Mapping 시키는

CycleGAN 을 활용하여 Landscape 데이터를 Gogh 의 그림으로 변환시키는 것입니다.

개발 환경은 윈도우 (Window), 언어는 파이썬 (Python), 라이브러리는 파이토치 (Pytorch) 를 사용합니다.

1. 이미지 변환 (Image Translation) 개요

지난 주 수행했던 DCGAN 딥러닝 모델은 Noise 한 데이터를 Input 으로 받으면 Generator 가 생성하고자 하는

이미지 데이터와 같은 형태의 이미지를 생성하고, 이를 Discriminator 가 판별하는 과정을 통해 간 (GAN) 모델이

직접 데이터를 창조하였습니다.

이미지 변환의 경우 CNN 기반으로 Pair 된 데이터셋을 통해 학습하여 진행되었으나, CNN 의 Loss Function 은

모든 Pixel 에 대한 Error 값을 Loss 로 잡고 평균을 구하므로, Blur 현상이 발생합니다.

CNN 의 L1 Loss 값에 따른 이미지 변환

 

그리하여 이미지를 새로 생성해낸다는 간 (GAN) 의 개념을 가져와 Conditiona GANs 를 제시하게 되고,

이를 Pix2Pix 라고 부르며 다양한 이미지에 대한 변환을 가능하게 만들었습니다.

https://arxiv.org/abs/1611.07004

 

Pix2Pix 를 통한 다양한 이미지 변환

 

그러나 해당 모델은 Pair 한 데이터셋을 구축해야만 학습을 진행할 수 있는 구조로,

완벽히 Pair 한 데이터셋을 구축하는 것은 불가능하므로, 이러한 문제점을 해결하고자 CycleGAN 이 연구되었고,

이를 시작으로 많은 Unpair 한 데이터셋 학습을 통한 이미지 변환 간 (GAN) 모델이 생성되고 있습니다.

https://arxiv.org/abs/1703.10593

 

Pair 한 이미지와 Unpair 한 이미지

 

CycleGAN 은 Cycle Consistent 라는 컨셉으로 하나의 도메인에서 다른 도메인으로 변환하기 위해선

단순히 한 도메인에서 다른 도메인으로의 Mapping 이 아닌 양방향의 도메인 Mapping 을 통한 Loss,

각 2가지를 구해서 더한 것을 전체 Loss 로 정의해서 학습하는 것입니다.

 

Cycle Consistent 컨셉

 

이를 수식적으로 풀어보면 X 도메인에서 Y 도메인으로 변환할 때의 함수를 G,

Y도메인에서 X 도메인으로 변환할 때의 함수를 F 라고 가정합니다.

이후 DCGAN 과 마찬가지로 X 이미지가 Input 으로 들어가고 Y 와의 분포차를 최소로 하는 G_Generator,

G_Generator 의 Output 과 Y 이미지 레이블에 해당되도록 확률을 최대로 하는 G_Discriminator 를 둡니다.

 

GAN 의 컨셉을 가져온 Loss 값

 

여기에 Cycle Consistent 컨셉을 추가하여 다시 X 도메인으로 돌아오는 L1 Loss 를 추가합니다.

Cycle Consistent 의 컨셉을 가져온 Loss 값

 

마찬가지로 Y 가 X 도메인으로 변환하는 과정도 동일하게 설정하여 모든 Loss 값의 합을 구합니다.

 

모든 Loss 값을 더한 최종 Loss 값

 

최종적으로 해당 Loss 값은 Generator 가 최소가 되도록, Discriminator 가 최대가 되도록 학습해야 하므로,

CycleGAN 딥러닝 모델의 최종 학습 과정은 다음 수식을 따릅니다.

 

CycleGAN 모델의 학습 수식

 

* 참고적으로 CycleGAN 은 이미지의 Style (배경, 색깔 등) 을 바꾸는 것에 특화된 딥러닝 모델이라면,

보다 형태 변화 (사람의 얼굴 변형, 동물 변경 등) 에 특화된 모델로 DiscoGAN 이 존재합니다.

해당 딥러닝 모델은 위와 똑같은 Loss 구조를 가졌으나, 마지막 Cycle Consistent Loss 로 

L2 Loss 를 사용한다는 차이점이 있습니다. *

즉, 간 (GAN) 딥러닝 모델들은 목적에 맞게 Generator, Discriminator 에 사용되는 딥러닝 모델을 설계하고,

이후 Loss 값의 조정에 따라 학습을 시켜나가는 구조로 이뤄집니다.

CycleGAN 의 딥러닝 모델들로는 Generator 에 CNN 딥러닝 모델인 Resnet 이 사용되었고,

Discriminator 에는 Pix2Pix 에 사용된 PatchGAN 을 사용합니다.

2. 이미지 데이터 전처리 (Image Preprocessing)

간 (GAN) 의 학습은 다른 딥러닝 모델들 보다도 데이터셋이 많은 영향을 차지하기 때문에,

이번 프로젝트는 실제 논문에서 적용한 Landscape 데이터셋과 Van Gogh 데이터셋을 이용해

풍경 이미지를 반 고흐의 그림과 같은 Style 로 변환시켰습니다.

Landscape 데이터셋은 이미지 공유 웹 사이트인 Flickr 에서 파이썬 (Python) 을 통해 크롤링 (Crawling) 하였고,

반 고흐의 데이터셋은 다양한 이미지를 모아둔 DB 인 WikiArt 에서 구축하였습니다.

구축된 데이터는 다음과 같은 경로를 통해 이미지를 저장합니다.

 

datasets/
    trainA/  # Input 으로 들어갈 이미지 폴더 (X 도메인, Landscape)
        img_trainA_0.jpg
        img_trainA_1.jpg
        ...
    trainB   # Training 으로 들어갈 이미지 폴더 (Y 도메인, Van Gogh)
        img_trainB_0.jpg
        img_trainB_1.jpg
        ...
    testA
        img_testA_0.jpg
        img_testA_1.jpg
        ...
    testB
        img_testB_0.jpg
        img_testB_1.jpg
        ...

 

다음으로 Directory 에 저장된 이미지를 불러와 파이토치 (Pytorch) 의 Transform 을 통해 전처리를 진행합니다.

파이토치 (Pytorch) 의 딥러닝에 넣기 위한 형태로 변환시켜줍니다.

(2가지 데이터셋을 합쳐야 하므로 별도의 Dataset 을 구축하는 Class 를 코딩해야 합니다.)

 

import torchvision.transforms as transforms
from torch.utils.data import DataLoader
from torch.utils.data import Dataset

import os
import glob
from PIL import Image
import random

import argparse

class ImageDataset(Dataset):
    def __init__(self, root, transform_):
        self.transform = transforms.Compose(transform_)
        self.files_A = sorted(glob.glob(os.path.join(root)))
        self.files_B = sorted(glob.glob(os.path.join(root)))

    def __getitem__(self, index):
        item_A = self.transform(Image.open(self.files_A[index % len(self.files_A)]))
        item_B = self.transform(Image.open(self.files_B[index % len(self.files_B)]))
        return {'A': item_A, 'B': item_B}

    def __len__(self):
        return max(len(self.files_A), len(self.files_B))


def main():

    dataroot = 'datasets 폴더의 경로'
    transform=transforms.Compose([transforms.Resize(256),
                                  transforms.CenterCrop(256),
                                  transforms.ToTensor(),
                                  transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
                               ]))
    dataset = ImageFolder(root=dataroot, tranform_=transform)

    parser = argparse.ArgumentParser(description='Face')
    parser.add_argument('--batch_size',type=int,default=1)
    parser.add_argument('--epoch',type=int,default=30)
    parser.add_argument('--learning_rate',type=float,default=0.0002)
    # Hyperparameter Option

    parser.add_argument('--channels',type=int,default=3)     
    parser.add_argument('--feature_g',type=int,default=64) 
    parser.add_argument('--feature_d',type=int,default=64) 
    # Convolution Layer Parameter Option (Data Format)

    args = parser.parse_args()

    dataloader = Dataloader(dataset, batch_size = args.batch_size, 
                            shuffle=True, num_workers=0)

 

3. 딥러닝 모델 생성

다음으로 CycleGAN 의 Generator 와 Discriminator 에 사용된 딥러닝 모델입니다.

위에서 말한 것과 같이 Generator 에는 Resnet 이, Discriminator 에는 PatchGAN 이 사용되었습니다.

(모델들은 미리 구현된 https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix 를 참조하였습니다.)

이후 핵심이 되는 Loss 값 4개를 각각 구하여 합하는 것으로 학습을 진행합니다.

 

import torch

input_X = torch.Tensor(args.batch_size,args.channels,args.feature_g,args.feature_g)
input_Y = torch.Tensor(args.batch_size,args.channels,args.feature_d,args.feature_d)
target_X = torch.Tensor(args.batch_size).fill_(1.0)
target_Y = torch.Tensor(args.batch_size).fill_(0.0)

optimizer_G = torch.optim.Adam(itertools.chain(Generator_X2Y.parameters(),Generator_Y2X.parameters()),lr=args.lr)
optimizer_D_X = torch.optim.Adam(DiscriminatorX.parameters(),lr=args.lr)
optimizer_D_Y = torch.optim.Adam(DiscriminatorY.parameters(),lr=args.lr)

GAN_Loss = torch.nn.MSELoss()
Cycle_Loss = torch.nn.L1Loss()

for epoch in range(num_epochs):
    for i,batch in enumerate(dataloader):
        real_X = input_X(batch['A'])
        real_Y = input_Y(batch['B'])
        ######## Generator X->Y , Y->X ##############
        optim_G.zero_grad()
        fake_Y = Generator_X2Y(real_X)
        pred_X = DiscriminatorY(fake_Y)
        Loss_X2Y = Gan_Loss(pred_X, target_X)
        fake_X = Generator_Y2X(real_Y)
        pred_Y = DiscriminatorX(fake_X)
        Loss_Y2X = Gan_Loss(pred_Y, target_Y)
        ######## GAN Loss ###########################
        CycleX = Generator_Y2X(fake_Y)
        Loss_Cycle_X = Cycle_Loss(CycleX, real_X)
        CycleY = Generator_X2Y(fake_X)
        Loss_Cycle_Y = Cycle_Loss(CycleY, real_Y)
        ######## Cycle Loss ##########################
        Loss = Loss_X2Y + Loss_Y2X + Loss_Cycle_X + Loss_Cycle_Y
        Loss.backward()
        optimizer_G.step()
        ######## Total Loss ##########################

* 모델 및 학습과 관련되어 참조된 코딩은 추가적으로 개별 작성하여 수정할 예정입니다.

4. 모델 평가 및 시각화 (Evaluation and Visualization)

실제 사진 (왼쪽), 반 고흐의 그림 (중앙), 딥러닝이 변환해낸 사진 (오른쪽)

 

실제 사진 (왼쪽), 반 고흐의 그림 (중앙), 딥러닝이 변환해낸 사진 (오른쪽)

 

실제 사진 (왼쪽), 반 고흐의 그림 (중앙), 딥러닝이 변환해낸 사진 (오른쪽)

 

 

5. 실생활 적용

간 (GAN) 기반의 딥러닝 모델들은 다양한 데이터들에 대한 생성 및 변화를 가능하게 만들었습니다.

이는 기존의 데이터를 변조하는 작업과는 달리, 기존의 데이터를 기반으로 새로운 데이터를 생성하는 것으로,

현실과 비현실을 구분하기 힘들 정도의 정교함을 보여주는 수준으로 발전되고 있습니다.

이러한 새로운 이미지의 생성은 낮은 화소의 이미지를 고화질의 새로운 이미지로 생성시키기도 하고,

 

저화질의 이미지를 고화질의 이미지로 재생성하는 간 (GAN)

 

특정 인물의 얼굴을 변형시켜 감정이나 다양한 표정을 만들어낼 수 있으며,

 

오바마의 표정을 다양하게 변환시키는 간 (GAN)

 

또한 본 프로젝트와 같이 다양한 사진들을 본인이 원하는 형태의 이미지로 변환하기도 합니다.

 

스케치 만으로 완성된 그림을 생성하는 간 (GAN)

 

또한 이미지가 아닌 텍스트 및 음성 분야로도 확장되어 텍스트가 주어지면 해당 텍스트에 맞는 이미지를 생성하기도 하며, 원하는 상대의 음성을 만들어내는 등의 작업도 가능하게 되었습니다.

 

텍스트를 통해 이미지를 생성하는 간 (GAN)

 

4차산업혁명을 통한 빅데이터와 인공지능 (AI) 붐은 다양한 딥러닝의 발전을 가져왔으나,

아직까지 사람들에게 이는 친숙하지 못한 방법론이며

어떠한 데이터냐에 따라 그 변화가 다양하므로 정답이 존재하지 않습니다.

허니컴 메이커스페이스는 데이터에 따라 다양한 방향으로 인공지능 (AI) 딥러닝 모델을 적용해보며

'정답' 에 근접한 모델을 생성하고,

이를 사람들이 이해하기 쉽도록 시각화와 같은 방법을 통해 설명해나가고자 합니다.

........

시제품 제작 문의