본문 바로가기
Deep Learning

[실패기] VAE로 손글씨 폰트 생성하기!

by 정현규 2021. 4. 22.

본 글은 오토 인코더의 모든 것에서 영감을 받아 진행한 개인 프로젝트입니다.

 

위 영상에서 VAE를 MNIST로 학습 후 기존 데이터셋에 없던 새로운 스타일의 숫자들을 생성해내는 것을 보고"한글 폰트 생성의 어려움을 VAE로 해결할 수 있지 않을까?"라는 아이디어를 얻었습니다.

 

 제가 생각한 설계는 위의 그림과 같습니다. 기존의 VAE에서 이미 알고 있는 Label 정보를 Latent Vector와 이어 붙여 디코딩하는 Conditional VAE를 사용했습니다. 한글이 어떤 글자인지에 대한 Label을 원-핫 벡터로 변환하여 입력해주었습니다.

 

 요즘은 폰트 중에도 손글씨와 비슷한 것이 많기 때문에 실제 손글씨는 아니지만, 한글 폰트로부터 직접 추출하였습니다. 폰트 약 300개를 수집하여 '가나다라마바사아자차카타파하'에 해당하는 14글자 총 300 x 14 = 5200개를 128*128 크기의 흑백 이미지로 생성하여 사용하였습니다. 우선 쉬운 문제부터 풀어보아 그 가능성을 확인해보는 것이 요지였죠.

 

 50에폭정도 학습을 시키며 에폭당 테스트 세트에 있는 16개의 가짜 이미지를 생성해보았습니다. 즉 "마"를 넣었을 때 "마"가 나오는 구조입니다.

 

학습에 따른 글자 생성 결과!
초성과 중성모음에도 테스트 해보았습니다.

 그렇다면 이론적으로, 한글 폰트 생성을 위해 하나의 글자 이미지만 입력하여도 Label만 변경해준다면, Decoder에서 기존의 데이터 셋에 없는 다른 글자들을 만들어 낼 수 있습니다(한글 폰트 제작의 어려움 해결의 핵심문제). 훈련된 모델을 통해 테스트 데이터의 하나의 이미지인 '가'로부터 생성해낸 가짜 이미지는 다음과 같습니다.

 

 생각한 대로, '가'의 이미지에 대한 Encoder의 출력 결과 z를 가지고, Label정보인 c만 바꾸었을 때, 비슷한 스타일의 글자를 만들어내는 것을 확인할 수 있었습니다. 하지만 비교적 복잡한 글자들은 제대로 그려내지 못했습니다. 더군다나 중성과 종성까지 더해진 데이터셋으로 학습한다면 결과는 더 비참할 것이라고 생각이 되었습니다. 흐릿한 문제를 해결하기 위해 데이터셋을 더 다듬어보고, 폰트를 더 추가해보고, 모델을 더 복잡하게 설계해보는 등 나름대로 여러 튜닝 과정을 거쳤지만 눈에 띄는 성능의 향상은 없었습니다.

 

 다른 방법들을 찾아보던와중에 VAE가 아닌 GAN을 사용하는 여러 사례들을 찾았습니다.

 

 위의 두 다른 사례에서 "이 정도면 실제 폰트로 사용될만하겠구나"라는 생각을 하였습니다. VAE는 그 결과가 종종 흐릿하게 나온다는 것은 알고 있었지만 GAN과의 차이가 굉장히 많이 난다는 사실을 몸소 체험했습니다. VAE와 GAN의 구체적인 차이는 처음에 소개드린 "오토 인코더의 모든 것" 3편에 잘 나와있습니다.

 VAE는 GAN보다 학습이 쉽지만 결과물의 이미지 퀄리티가 흐릿하다는 단점이 있습니다. 반면 GAN은 생성자와 판별자가 경쟁하는 구조로 인해 학습이 어렵지만 이미지 퀄리티가 샤프합니다. 이에 대한 Yoshua Bengio 교수님의 설명도 도움이 되었습니다.

 

 VAE는 z를 정규분포로 가정하지만 GAN은 그렇지 않기에 더 복잡한 분포를 알아낼 수 있다라고도 생각이 듭니다. 시간이 나면 VAE의 z를 다른 분포로도 사용할 수 있는 AAE로 실험해보아야겠습니다.