# For example,
python3 generate_images.py\
--ds_name="monet2photo"\
--data_dir=".../monet2photo/"\
--x_or_y="x"\
--ckpt_path=".../monet_to_photo.pth"\
--n_cpus=0 # Optional
- 'horse2zebra' dataset의 경우 이미지 중 일부가 화질이 좋지 않거나 이미지의 비율이 왜곡되어 있고 이미지 내에서 말 또는 얼룩말이 차지하는 영역이 매우 작은 등 개인적으로 데이터셋의 품질 자체가 좋지 않다고 생각합니다. 좀 더 대량의, 고품질 데이터셋을 구축하여 다시 학습시켜보면 더욱 우수한 모델을 얻를 수 있을 것입니다.
- 논문만 가지고는 정확히 알기 어려운 부분 또는 논문과 공식 저장소가 서로 다른 부분이 많은데, 공식 저장소를 기준으로 구현했습니다.
-
- discriminators (Dx와 Dy)와 generators (Gx와 Gy)의 objective는 방향성이 서로 충돌하지만 (adversarial training) Dx와 Dy 그리고 Gx와 Gy는 서로 objective의 방향성이 동일하므로, Dx의 Optimizer와 Dy의 Optimizer를 하나로 합치고, Gx의 Optimizer와 Gy의 Optimizer를 하나로 합쳤습니다.
- As-is:
disc_x_optim = Adam(params=disc_x.parameters(), lr=lr) disc_y_optim = Adam(params=disc_y.parameters(), lr=lr) gen_x_optim = Adam(params=gen_x.parameters(), lr=lr) gen_y_optim = Adam(params=gen_y.parameters(), lr=lr)
- To-be:
disc_optim = Adam(params=list(disc_x.parameters()) + list(disc_y.parameters()), lr=lr) gen_optim = Adam(params=list(gen_x.parameters()) + list(gen_y.parameters()), lr=lr)
- 논문에서는 모든 padding에 대해서
padding_mode="reflect"
를 사용한 것처럼 쓰여 있으나 공식 저장소를 보면padding_mode="zeros"
와padding_mode="reflect"
를 혼용하고 있어 이를 따랐습니다.
- 이미지의 집합 X와 Y의 크기가 서로 다르므로 만약 X의 크기가 Y의 크기보다 크다면 1 epoch 동안 X의 이미지가 한 번씩 모델에 입력으로 들어갈 때 Y의 이미지는 한 번 이상씩 모델에 입력으로 들어가게 됩니다. 즉 X의 크기가 데이터의 크기가 됩니다. 이 점을 간과해 데이터의 크기를 Y의 크기와 같게 했고 X와 Y의 각 원소를 정해진대로 1:1 대응이 되도록 코드를 짰었으나 이를 수정했습니다.
- As-is:
x_path = self.x_paths[idx] y_path = self.y_paths[idx]
- To-be:
if self.x_len >= self.y_len: x_path = self.x_paths[idx] y_path = random.choice(self.y_paths) else: y_path = self.y_paths[idx] x_path = random.choice(self.x_paths)
- 논문에 따르면 objective로서 'negative log likelihood' (
GAN_CRIT = nn.BCEWithLogitsLoss()
) 대신에 'least-squares' (GAN_CRIT = nn.MSELoss()
)를 사용합니다. [1] 전자를 사용할 경우 금방 mode collapse가 발생하는 것을 관찰할 수 있었습니다.
- Please refer to my another repository Gatys et al.