Deoldify는 2018년 Jason Antic이 발표한 GAN 기반 흑백사진 채색 라이브러리다. 간단히 말해 흑백사진을 딥러닝으로 채색해 컬러사진으로 바꿔준다.
pytorch 기반으로 작성됐으며, Github에서 클론 후 개발 중인 Python 소스코드(.py)에 import 시켜서 사용할 수 있다.
또 Jupiter Notebook 파일 (.ipynb)로도 제공하고 있다. 간단히 사용만 해볼 목적이라면 Colab에서 Jupiter Notebook 파일을 사용해도 된다.
소스코드 및 사용법 : github.com/jantic/DeOldify
jantic/DeOldify
A Deep Learning based project for colorizing and restoring old images (and video!) - jantic/DeOldify
github.com
딥러닝을 접한지 얼마 안됐을때 컬러사진과 흑백사진을 1대1 라벨링 하여 Train Dataset으로 만들고 학습시키면 Validation 역할을 하는 무작위 흑백사진을 컬러사진으로 변환할 수 있지 않을까 하는 생각을 하곤 했다.
비록 세부 원리는 달랐지만 같은 기능을 구현한 Deoldify가 나온 것을 보니 꽤 신기했다.
본 DeOldify 라이브러리는 기본적으로 GAN (Generative Adversarial Network) 모델 기반으로 SAGAN(Self-Attention
Generative Adversarial Network)과 NoGAN (말그대로 GAN이 아닌 학습법 (설명후술))을 차용해 모델을 구성했다. 따라서 GAN이 무엇인지부터 알아보자.
1. GAN (Generative Adversarial Network)
GAN은 직역하면 '생성 적대적 네트워크'라는 뜻이다. 생성 모델이란 '그럴듯한 가짜'를 만들어내는 모델이다. 수만명의 얼굴 이미지를 학습해 그럴듯한 가짜 얼굴을 만들어내는 모델을 들어본 적이 있을 것이다. 그렇게 현실에 존재하지 않는 그럴듯한 가짜를 만들어내는 모델을 생성 모델이라 한다.
그렇다면 '적대적'이란 말은 무엇일까? 이는 GAN이 두 개의 모델을 적대적(Adversarial)하게 경쟁시키며 발전시킴을 의미한다. 그럴듯한 가짜 사진을 생성하는 '생성자 Generator'와 해당 사진이 가짜인지 진짜인지 구분하는 '구분자 Discriminator'를 만들어서, 생성자는 계속 사진을 만들게 시키고 구분자는 가짜 사진을 구분하게 시켜서 피드백을 준다. 그렇다면 생성자는 학습을 반복하며 구분자가 구분 할 수 없을정도로 사진 만드는 법을 배우게 되고, 시간이 흐르면 생성자의 가짜 사진은 완벽에 가깝게 발전한다.
1번째 학습
생성자 : (가짜 사진을 하나 만들고) 이 사진 진짜로 찍은거게, 만든거게?
구분자 : 엄청 티나;; 누가봐도 가짜잖아.
생성자 : 아 ㅇㅋ 이렇게 바꿔봐야지
2번째 학습
생성자 : (가짜 사진을 하나 만들고) 이 사진 진짜로 찍은거게, 만든거게?
구분자 : 아니 티난다니까? 가짜잖아
생성자 : 아 ㅇㅋ 이번엔 이렇게 바꿔봐야지
.
.
151번째 학습
생성자 : (가짜 사진을 하나 만들고) 이 사진 진짜로 찍은거게, 만든거게?
구분자 : 음.. 좀 긴가민가 한데.. 그래도 티가 나네. 가짜!
생성자 : 아 아직도 티가 나는가보네. ㅇㅋ 또 만들어 올게.
.
.
.
9372번째 학습
생성자 : (가짜 사진을 하나 만들고) 이 사진 진짜로 찍은거게, 만든거게?
구분자 : 오 이건 진짜네
생성자 : ㅋ 드디어 속는구만
'네트워크' 라는 말은 말그대로 뉴런 레이어를 쌓아 네트워크를 구성했다는 뜻으로, 우리가 흔히 알고 있는 Deep Learning을 사용했다는 뜻으로 이해하면 된다. 입력값이 뉴런들을 통과하며 가중치가 적용된 새 값을 갖게 되고, 그 다음 뉴런을 옮겨 옮겨 가며 가중치를 계속 적용시켜 결국 출력값을 내놓는다. 딥러닝을 학습시킨다는 것은 최적의 가중치를 찾아가게 됨을 의미한다. 이때 활성화 함수 (activation function)과 손실 함수 (Loss function), 오차 역전파(Backpropagation), 경사하강법(Gradient Descent)등의 여러 수학 함수와 방법들을 사용해 가중치를 업데이트 하게 된다. 자세한 사항은 내용이 너무 길어질 것 같아 기술하지 않겠다. (대신 여러 책에 매우 잘 써있다)
한문장으로 표현하자면 GAN은 생성이라는 문제를 풀기 위해 딥러닝 모델을 적대적으로 학습시키는 알고리즘이다.
2. cGAN과 SAGAN (Convolution GAN & Self-Attentioned GAN)
상기한 GAN은 기본적으로 네트워크가 Fully connected 되어있기 때문에 Parameter가 최대치로 설정되어 있다. 이렇게 된다면 굳이 학습에 반영되지 않아도 될 주변 픽셀들이 같이 학습돼서 학습시간을 지연시킬 여지가 있다. 효율적이지 못한 것이다. 이를 극복하기 위해 CNN(Convolution Neural Network) 원리를 차용한 cGAN 이라는 방식이 대두됐다. 이는 간단히 표현하면 "이미지의 특징만 추출해서 학습시키겠다!"를 목표로 하는 모델이다. 굳이 이미지 전체의 픽셀을 학습하지 않고, Convolution Filter를 만들고 이미지를 통과시켜 특징만 추출 후 학습한다면 효율성이 커질 것이었다. 이는 가짜 이미지를 생성할 때 있어 효율을 대폭 증가시켰다. GAN 말고도 이미지 분류 (image classification) 등에서는 CNN 모델을 주로 쓰게 됐다.
하지만 실무에서 사용해보니 cGAN이 이미지 내 공간 특징 (Geometry feature), 구조 특징 (Structure feature) 구현에 취약하다는 점이 제기됐다. 다음 예시를 보면 이해가 될 것이다.
생성자 : (가짜 고양이 사진을 만들며) 봐바! 아주 귀여운 새끼 고양이 사진이야. 그럴듯 하지?
사람들 : 고양이 털 질감은 꽤 그럴듯 한데, 고양이 발이랑 땅바닥이랑 왜 붙어있지? 이게 고양이 다리인지 발인지 땅바닥에 붙어있는건지 구분이 안 돼;;
이는 충분한 Convolution 필터를 거치지 않았을 경우 추출한 특징과 멀리 떨어진 부분의 픽셀은 잘 이해하고 구현하지 못함을 의미한다. 이를 극복하려면 Convolution 필터를 더 많이 통과시켜야 하는데 이러면 학습시간이 크게 증가한다. 효율성을 위해 cGAN을 사용한건데 역으로 효율이 떨어지게 생겼다. 따라서 이를 보완한 SAGAN (Self-Attentioned GAN)이 제기됐다.
SAGAN은 Convolution 특징 맵을 기반으로 이미지에서 집중해야 할 지역을 따로 표시한 'Attention map'을 또 만들어 이미지를 학습시킨다. 크게 도드라지는 특징만 내놓는 것이 아닌, 집중해야할 구역(Attention Region)을 만들고 그곳 특징을 추가로 추출해 정확도를 올리겠다는 목적이다. 자세한 구현법은 논문을 참조하자 : arxiv.org/abs/1805.08318
Self-Attention Generative Adversarial Networks
In this paper, we propose the Self-Attention Generative Adversarial Network (SAGAN) which allows attention-driven, long-range dependency modeling for image generation tasks. Traditional convolutional GANs generate high-resolution details as a function of o
arxiv.org
결국 이 전략은 완벽히 들어맞아 이미지 생성의 정확도를 한층 더 끌어올리는 결과로 이어졌다.
3. noGAN
noGAN은 Deoldify 개발자 Jason Antic이 직접 제작한 알고리즘이다. 따라서 따로 논문은 없다 (개발자의 github에서 매우매우 강조하더라. 논문 따로 있냐고 문의를 많이 받은 듯).
이 noGAN은 간단히 말해 '학습 횟수를 최소화 한 GAN'이다. Jason Antic은 SAGAN으로 Deoldify를 구현하며 일정 학습 횟수(epoch) 이상으로 올라가면 이미지가 나쁜 상태로 채색되는 현상을 발견했다. 예를 들어 피부가 지나치게 주황색으로, 입술이 지나치게 빨갛게 칠해지는 현상이 있던 것이다. 개발자는 사진 채색 마다 수많은 모델 체크포인트를 만들어 과적합 변곡점(Inflection point)를 찾았고, 그 변곡점의 평균치를 구해 조기 정지 시점으로 설정했다. 과적합이 일어나기 전에 학습을 끊어버리겠다는 목적이다. 훈련 손실 (Train Loss)가 최저로 도달하기 전에 학습을 중단하므로 채색 정확도가 떨어지는 단점이 있었지만, 이상한 색이 칠해지는 것 보다야 색을 좀 번지게 채색하는게 더 좋은 결과물이라 말할 수 있으므로 그렇게 설정했다고 한다.


백문이 불여일견. 직접 Deoldify로 채색한 사진을 소개한다. 부모님과 조부모, 증조부모님들의 사진을 직접 채색해봤다.
1. 1932년 6월, 할아버지의 소학교 수학여행


2. 1930년대 친척 어르신 장례식


3. 1957년 8월, 할아버지의 사무실 풍경


4. 1963년 8월, 할머니가 활동하시던 부녀자 모임 "꽃계"


5. 1971년 2월, 친가 결혼식 사진


6. 1976년 2월, 친가 가족사진


7. 1962년, 외할머니와 어머니, 큰 삼촌


8. 1972년, 어머니와 중학교 친구 분


9. 1973년, 소양강 댐 나들이 가신 친가 어르신


10. 1977년, 아버지의 군시절 사진


사실 이 모델에 관심이 갔던 이유는 부모님, 조부모님들의 옛날 흑백사진을 좀더 생생하게 만들어드리고 싶은 마음 때문이었다. 부모님이 보시고 매우 좋아하셔서 뿌듯했다. 흑백사진으로 남아있던 추억을 최신 기술로 채색해 다시 생생하게 살려내는 과정 자체가 너무 재밌었다.
인공지능의 발전은 새로운 미래를 개척하는 동시에 지나간 과거도 생생히 되살리는 역할을 함을 이번 기회에 크게 느꼈다. Deoldify의 원리를 살펴보고 구현법을 맛보는 동시에 부모님의 추억까지 되살릴 수 있어 뜻 깊은 기술 리뷰였다.