CycleGAN 논문 구현 및 생각 과정과 정리

현재 하고 있는 task에서 cycleGAN을 활용한 방법이 있어 CycleGAN 부터 제대로 알고 구현하고자 좀 딥하게 읽고 생각해봤습니다.

CycleGAN 논문과 공식 구현 코드입니다.

CycleGAN 이해에 도움이 될만한 자료입니다. 논문의 공동 저자인 박태성님의 한글 발표 자료입니다.

이미 너무 유명한 모델인 만큼 따로 model에 대한 내용, 논문의 내용은 디테일하게 적지 않겠습니다. 모델 설명은 이 링크가 가장 좋았습니다.

기존 깃헙은 pix2pix 등 이리저리 복잡하여 저는 이 구현 코드를 이용하여 구현 연습을 했습니다.

Model Detail

[G] Downsampling & Upsampling

GAN에서는 기본적으로 Generator에서 Downsampling과 Upsampling 과정을 거칩니다.

흔히 Downsampling은 input image의 특징을 추출하고, Upsampling을 통해 이미지의 스타일을 바꿔(translation)주는 용도로 사용한다고 합니다.

이미지에서 각각은 Conv2dConvTranspose2d를 이용하여 이뤄집니다.

[zzsza] Up-sampling with Transposed Convolution 번역를 참고하면 좋습니다.

[G] ResNET (Residual Block)

residual connection을 이용하면 정보 손실이 적고, 고해상도 처리가 가능하기에 사용한다고 한다.

[D] PatchGAN

PatchGAN을 사용했다고 하는데, 이와 관련 이슈입니다. PatchGAN도 하나의 technique인 만큼 따로 깊게 읽어봐도 좋을 것 같습니다.

  • https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix/issues/39

[Train] Loss

Loss는 총 3개를 사용했습니다.

  • GAN Loss (LSGAN) : MSE Loss
  • Identity Loss : L1 Loss
  • Cycle Loss : L1 Loss

L1을 사용하여 모델 자체의 큰 형태에 대해서는 변화가 적게 만들었습니다.

Techniques

다음과 같은 테크닉은 GAN(및 다수 DNN 모델)에서 기본적으로 사용되니 알아둡시다.

Well-Known (for me)

기본적인 것은 다음과 같습니다.

그리고 조금 더 나아가서는 다음과 같은 테크닉이 있습니다.

Advanced

그리고 개인적으로 생소했던 테크닉은 다음과 같습니다.

  • Model > Weight Initialize with Normal Distribution

모델의 가중치를 초기화하는 방법입니다. 코드에서는 torch.nn.init,normal_을 사용하여 mean 0, std 0.02로 초기화 합니다. exploding gradients, vanishing gradients를 방지하기 위해 사용합니다.

이 외에도 Xavier, Kaiming, HE 등의 방법을 사용할 수도 있다고 합니다.

다음 글을 참고하면 좋을 것 같습니다. [deeplearning.ai] Initializing neural networks, Weight Initialization in Neural Networks: A Journey From the Basics to Kaiming

  • Data > Resize with BICUBIC

Interpolation 방법 중 하나인 Bicubic 방법을 사용하여 이미지를 Upsampling합니다. (한국어로는 바이큐빅이라고 읽네요.) 이미지를 읽어들일 때 resize와 함께 사용합니다. 아직 해결하지 못한 의문점으로는 왜 1.12를 곱한 후에 random crop하는지 모르겠습니다.

  • Optimizer > Learning Rate Scheduler

learning rate를 anealing 하는 방법입니다. step에 따라 learning rate를 조절하는 방법으로 이런 류의 논문은 많으니 참고해봅시다.

Class로 작성하여 custom 할 수 있습니다.

  • Discriminator > Replay Buffer

Generator가 만들어 놓은 사진을 다시 Discriminator에게 보여주는 방법이라고 합니다.

링크에서는 다음과 같이 설명하고 있습니다.

GAN 트레이닝을 진행하며 똑같은 샘플별로 성능을 살펴보면 트레이닝을 돌릴때마다 성능이 천차만별이다. 이 불안정성을 해결하기 위해 주기적으로 Generator가 만들어놓은 사진을 다시 discriminator에게 보여줌 이 부분은 Discriminator에게만 적용함

Quetstions

Q. 왜 Discriminator의 Convolution의 kernel size는 4일까?

논문 저자이자 코드 작성자에 의하면 DCGAN을 따랐다고 합니다. (대다수의 GAN은 DCGAN의 구조를 가져온다고 하는데, 저도 DCGAN을 더 살펴볼 필요가 있겠습니다.)

그런데 DCGAN 논문에서는 5를 사용합니다. 그래서 issue를 찾아보니 다음과 같은 이슈가 있었습니다.

  • https://github.com/soumith/dcgan.torch/issues/11

여기서 DCGAN의 저자는 논문에서는 cudnn Transpose이 Theano에서 kernel size가 5라 논문에서는 5라고 썼고, torch에서는 4를 사용했다고 한다. (torch에서는 ConvTranspose2D 사용)

그래서 왜 이런 사이즈를 썼는지는 의문이 해결되지 않았습니다. 보통 이런 논문 구현의 Kernel, stride, padding size는 어떻게 결정되는지 아시는 분들은 댓글로 알려주시면 감사하겠습니다.

짧은 후기

이론과 실험은 다르다는 것.

기존에 이론을 위주로 많이 공부했다면 최근에는 구현 및 실험을 위주로 하고 있습니다. 실험을 했을 때, 왜 실패하고 어떻게 튜닝할 수 있을지 좀 더 연습해야겠습니다.

Pytorch의 수 많은 기능들과 딥러닝의 여러가지 테크닉을 알기 위해서는 끊임없이 공부해야겠습니다.

Leave a Comment