CycleGANのIdentity損失をあえてゼロにする実験

:::note
この記事は元々**2024年9月29日**に個人ブログで公開された内容をQiitaに移行したものです。
:::

最近CycleGANを実装してみたのですが、ちょっと気になって、Identity損失の有無で結果がどう変わるか調べてみました。

## Identity損失の必要性

Identity損失（または同一性損失）は、以下の数式で表されるCycleGANの損失関数の一つです。

例えばA, Bそれぞれのグループに属する画像があり、これを使ってCycleGANのモデルを学習させるとします。Identity損失は、「A→B変換器」にあえてBの画像を入力したとき、その出力画像が元の入力画像と異なる場合に加算される損失です。

CycleGANの提唱論文によると、Identity損失は画像の色やスタイルを保つために有効です。ただ全てのタスクで必要であるとは記述されておらず、特定のタスクにおいてはこの損失が有効なのだと思われます。例えば論文中では「写真<->モネの絵画」変換のようなタスクでは、Identity損失があることで元の色合いがキープされる結果が示されています。[^1]

[^1]: Zhu, J. Y., Park, T., Isola, P., & Efros, A. A. (2020). Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks. arXiv preprint arXiv:1703.10593v7

## Identity損失の影響を確認する

複数のデータセットに対して、異なるIdentity損失の係数（λ= 0, 0.5）でCycleGANの学習プロセスをそれぞれ実行し、結果がどう変化するか実験を行いました。λ= 0はIdentity損失が無いことと同義です。

なお今回使うデータセットは、CycleGANの王道、馬シマウマ変換の「horse2zebra」[^2]と、夏冬変換でお馴染み「summer2winter」[^3]です。

[^2]: horse2zebra dataset: https://people.eecs.berkeley.edu/~taesung_park/CycleGAN/datasets/

[^3]: summer2winter dataset: https://www.kaggle.com/datasets/balraj98/summer2winter-yosemite

エポック数はそれぞれ100です。


結果は以下のようになりました。

|                    | λ= 0（Identity損失なし）                                                                                                 | λ= 0.5（Identity損失あり）                                                                                                 |
|--------------------|--------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------|
| **horse2zebra**    | ![ln02381460_120_0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3981597/d49da136-7b43-4ec4-a875-49838ab55b0b.jpeg)<br>![ln02381460_900_0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3981597/5af605fd-c3a5-472b-9c64-3dbdd7739c77.jpeg)                                                                       | ![ln02381460_120_0.5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3981597/c3d51130-b328-44d9-809e-fe01f7bd22ae.jpeg)<br>![ln02381460_900_0.5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3981597/277c29c7-82d3-4d09-a3ac-edc98cdd9e54.jpeg)                                                                         |
| **summer2winter**  | ![l2011-05-28-151321_0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3981597/81c6ad9d-99d9-4f6b-b144-f1284e4918f0.jpeg)<br>![l2011-07-03-110120_0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3981597/04c1ac74-f870-441e-a261-4bf224735c64.jpeg)                                                                       | ![l2011-05-28-151321_0.5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3981597/b9663724-97a1-47f1-b5eb-6faff4365cf8.jpeg)<br>![l2011-07-03-110120_0.5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3981597/5fb429dd-91cc-4b0a-a035-1e2419673fa1.jpeg)|

- **horse2zebra：** Identity損失がない場合は馬以外の部分の色が大きく変化した一方で、Identity損失がある場合は馬以外の部分の色が変換後も保持された。どちらにしろ馬→シマウマの変換そのものは上手くいった。
- **summer2winter：** Identity損失がない場合は写真全体の色合いが大きく変化した一方で、Identity損失がある場合はその変化が比較的小さかった。

このように、Identity損失の有無には一長一短があるようですね。  
「horse2zebra」のように、**「画像の一部のみを変えることを目的としたタスク」では、変換対象以外の色合いを保持するためにIdentity損失を入れた方が良さそうです。**
一方「summer2winter」のように、**「画像全体を変えることを目的としたタスク」では、Identity損失を入れないほうがより大規模な変更を促すことができそうです。**

## 学習時間の比較

Identity損失の有無が変換の性能に影響することは分かりましたが、学習時間にはどう影響するでしょうか。

明確に言えるのは、Identity損失を考慮しない場合は、損失の計算量を削減できることです。

CycleGANの損失は以下のように４つの損失の和で表されますが、第4項の「Identity損失」を計算するためには、「Aの画像をA→B変換器に入力する計算」と「Bの画像をB→A変換器に入力する計算」が必要になります。もしこれをカットできるのであれば、学習ステップごとの損失の計算を小さくすることができ、学習時間が短縮されるはずです。

```math
\begin{aligned}
L(G, F, D_X, D_Y) =
L_{\text{GAN}}(G, D_Y, X, Y)\\
+ L_{\text{GAN}}(F, D_X, Y, X)\\
+ \lambda_{\text{cyc}} L_{\text{cyc}}(G, F)\\
+ \lambda_{\text{id}} L_{\text{id}}(G, F)
\end{aligned}
```

実際に学習時間を測ってみましたので、結果を以下に記載します。

|                    | Identity損失なし                      | Identity損失あり                      |
|--------------------|---------------------------------------|---------------------------------------|
| **horse2zebra**    | 100エポックで17.29時間（1エポックあたり約10分） | 100エポックで23.95時間（1エポックあたり約14分） |
| **summer2winter**  | 100エポックで15.63時間（1エポックあたり約9分）  | 100エポックで22.29時間（1エポックあたり約13分） |

このように、それぞれのデータセットにおいて、  
**<span style="color:red;font-weight:bold">損失の計算にIdentity損失を入れないことで、計３時間をおよそ30%削減できることがわかりました。</span>**

ちなみに実行環境は、Google Cloud PratformのCompute Engineのインスタンス内で、GPUタイプはT4、GPU数は１です。

## まとめ

Identity損失の有無にはそれぞれメリット・デメリットがあり、状況によって使い分けるのがよさそうです。

**Identity損失が有る場合のメリット**

- **「画像の一部のみを変えることを目的としたタスク」には、変換対象以外の色合いを保持するために必須となる。**

**Identity損失が無い場合のメリット**

- **「画像全体を変えることを目的としたタスク」では、より大規模な変更を促すことができる。**
- **学習時間を短縮できる。**