敵対的ネットワークGAN（Generative Adversarial Networks）

<font color="grey">
本書は筆者たちが勉強した際のメモを、後に学習する方の一助となるようにまとめたものです。誤りや不足、加筆修正すべきところがありましたらぜひご指摘ください。継続してブラッシュアップしていきます。
© 2021 [NPO法人AI開発推進協会](https://sites.google.com/deepaelurus.com/aboutus/home)
</font>

本書は画像生成の各種モデルのベースとなっているGANについて説明します。(CNNの基礎を理解している前提で記載しています。まだ理解していない方は別冊のCNNの基礎を先に読んでください）

【参考文献、サイト】
・[論文](https://arxiv.org/abs/1406.2661)
・[生成モデル](https://github.com/Yagami360/My_NoteBook/blob/master/%E6%83%85%E5%A0%B1%E5%B7%A5%E5%AD%A6/%E6%83%85%E5%A0%B1%E5%B7%A5%E5%AD%A6_%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92_%E7%94%9F%E6%88%90%E3%83%A2%E3%83%87%E3%83%AB.md#GAN)


# １．概要
GAN は、Generator（以降、生成器）と Discriminator（以降、識別器）という２つの機構から構成される生成モデルです。モデルアーキテクチャは図１のようになります。


![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412761/7422adaa-2ed6-eba3-d71c-af5199cd3565.png)
図 1　GANのアーキテクチャ図
　

生成器は乱数から偽物画像を生成し、識別器は生成された偽物画像と本物画像を入力し本物か偽物かを識別させ、識別器が判別できなくなるまでお互いを交互に学習させることで、最終的には生成器が本物に近い画像を生成できるようにするものです。  

下図２は、モデルアーキテクチャを見やすくするためにモデルをサマリしたものです。  

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413258/33ccdb58-a711-e96d-3ab4-fca7fa430d4d.png)
図 2　GANのアーキテクチャ簡略図

　
まず、生成器は潜在変数Zを入力値として受け取り画像を生成して出力します。通常Zは１００次元ベクトル（各要素は０～１までの値を取る変数）の変数であり、一様分布や正規分布からランダムサンプリングします（＝画像を生成するための種になる）。  
識別器は画像データを入力値として受け取り、そのデータが本物のデータなのか、生成器から生成された偽物のデータかを出力値「0.0（偽物）～1.0（本物））として返します。  

次に各機器の学習について説明します。

# ２．識別器（Discrimator）の学習
識別器は画像（本物または偽物）を入力データとして、予測結果（本物か偽物）を出力するので教師データはその画像が「本物（１）または偽物（１）」かになります。すなわち以下のラベルを用いて学習します。
　　<font color="red">・本物画像入力　->  教師ラベル＝１</font> 
　　<font color="red">・偽物画像入力　->  教師ラベル＝０</font>

# ３．生成器（Generator）の学習
生成器の学習ではあくまで生成器のみ学習させるので、<font color="red">識別器の重みを固定させて学習させる</font>ことにポイントがあります（Kerasフレームワークの場合はtrainable=Falseを動的に指定することで実装が可能）。  

もう一つ重要なポイントは、生成された画像は当然偽物なので本来ならば教師ラベルは０（偽物）ですが、<font color="red">識別器に対して本物だとだますように学習させるので「教師ラベル＝１（本物）」として学習させます</font>。  

従って生成器の学習イメージは下記のサマリになります。  

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413258/b57ba84b-5679-c6b4-7d42-fb855c609059.png)
図 3　GAN生成器の学習イメージ



# ４．損失関数
損失関数は以下で定義されています。
（式１）
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412761/8e717e76-88b8-a8fd-01b5-833e78552309.png)

<dt>【識別器】</dt>
生成器を固定したうえで損失関数を最大化します。第１項は本物データ入力に対するものですが、この項を最大化するのはlogの内部を最大化、すなわち識別子の結果として本物（１）を出力させるように学習させます。  
第2項は、生成器により出力された偽物画像に対するものですが、同様にこの項のlogの内部を最大化するには生成器の出力を最小化、すなわち識別器の結果として偽物（０）を出力させるように学習させます。  
　

<dt>【生成器】</dt>
識別器は固定で生成器のみに依存するので第2項のみ考えればいいことになります。識別器について最小化するのでlogの中身が~~１~~0になるように学習する（D(G(z))を1に近づけるように学習する）ことになります。



# ５．GANの学習での課題について
GANの学習については、以下のような課題があります。
<dd>
(1) 損失関数の収束性
(2) モード崩壊
(3) 勾配損失問題
(4) 生成画像の品質判断
</dd>
以下に個々の課題について説明します。  


##  (1) 損失関数の収束性
GANは、識別器と生成器の2人プレイヤーゼロサムゲームになっていますが、このゲームの最適解は、ナッシュ均衡点になります。また、<span style="color: red; ">2人プレイヤーゼロサムゲームのナッシュ均衡点は、鞍点になります</span>。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412761/2fb98767-9477-1a9d-7927-9fb59d06886e.png)
図 4　GANの収束の難しさ

　
式１の形状が、上図のような凸関数であれば、SGDによってナッシュ均衡点（＝鞍点）に収束されることが保証されますが、非凸関数の場合は保されません。また、GANではニューラルネットワークにより損失関数を表現するので、関数の形状は非凸関数になります。  
このような非凸関数に対して、SGDで最適化（＝鞍点の探査）を行っていくとナッシュ均衡点（＝鞍点）に行かず、振動する可能性があります。  

## (2) モード崩壊
学習が不十分な識別器に対して生成器を最適化した場合や、生成器への入力ノイズZの潜在変数としての次元が足りていない場合などにおいて、生成器による生成画像がある特定の画像に集中してしまい、学習用データが本来持っている多様な種類の画像を生成できなくなってしまいます。これをモード崩壊といいます。


## (3) 勾配損失問題
学習が十分でない識別器に対して、生成器を最適化するとモード崩壊が発生します。これを防ぐために、ある生成器Gの状態に対しての識別器を完全に学習すると、今度は勾配損失問題が発生してしまいます。
GANでは、モード崩壊と勾配損失問題が互いに反して発生しまうというジレンマを抱えています。

## (4) 生成画像の品質判断
生成画像の品質の評価は、損失関数の結果からでは判断が難しい課題があります。

# ６．おわりに
以上がGANの基礎になります。GANには様々な拡張モデルがあります。今後、高画質な画像生成を行うStyleGAN・StyleGAN2について、CPU上で動かす実証をしつつ執筆予定です。