論文まとめ＆実装例：EFFICIENT GAN-BASED ANOMALY DETECTION

# はじめに
ICLR2018の以下の論文
[1] H. Zenati, et. al. "EFFICIENT GAN-BASED ANOMALY DETECTION"
のまとめ

arXivのページ
https://arxiv.org/abs/1802.06222

著者らのgithubコード
https://github.com/houssamzenati/Efficient-GAN-Anomaly-Detection

私のサンプルコード
https://github.com/masataka46/BiGAN
名前はBiGANとなってますが、中身は本Efficient-GANです。

関連論文のまとめ
- anoGAN：https://qiita.com/masataka46/items/09e4e13be097a68174cd
- ADGAN：https://qiita.com/masataka46/items/4f7f770250fecc911bbc



# 概要 
GANを用いた異常検知モデルとしては anoGAN や ADGAN があるが、これらは推論時に与えられた画像に対応するノイズを探索するため、リアルタイムな処理が難しい。

本手法 Efficient-GAN は学習時に画像をノイズへ変換するencoderを学習し、推論時にそれを利用することで既存手法の数百倍の速度を達成した。

# アーキテクチャ 
本手法のアーキテクチャは[2]DonahueらのBiGANを用いている。

以下が[2]のfigure 1。

<img width="969" alt="BiGAN_001.png" src="https://qiita-image-store.s3.amazonaws.com/0/116706/83465145-2c59-de99-717f-31f21d0e1dec.png">

anoGANやADGANと明らかに違う点は、画像をノイズに変換するencoder $E(\bf x\rm)$ が加わっていること。またdiscriminatorには画像とノイズのペアを入れて、それが

1. ノイズと、それから生成された画像
2. 画像と、それをencodeしたノイズ

のいずれかを判断する。

# minimaxな式
Efficient-GANのminimaxな式は以下。

```math
V(D,E,G) = \mathbb{E}_{x \sim p_{X}} [\mathbb{E}_{z \sim p_{E}(\cdot | x)}[\log D(x,z)]] + \mathbb{E}_{z \sim p_{Z}} [\mathbb{E}_{x \sim p_{G}(\cdot | z)}[1 - \log D(x,z)]]
```

D：discriminator
E：encoder
G：generator
$x \sim p_X$ ：realな画像
$z \sim p_{E}(\cdot | x)$ ：realな画像 $x$ をencoderに入力した時の出力されたノイズ
$z \sim p_Z$ ：一様乱数に従うノイズ
$x \sim p_G(\cdot | z)$ ：一様乱数に従うノイズ $z$ をgeneratorに入力した時の出力画像

右辺１項目

```math
\mathbb{E}_{x \sim p_{X}} [\mathbb{E}_{z \sim p_{E}(\cdot | x)}[\log D(x,z)]] 
```

は real な画像をencoderに入れノイズを生成し、そのペアをdiscriminatorに入れた時の対数尤度。

右辺２項目

```math
\mathbb{E}_{z \sim p_{Z}} [\mathbb{E}_{x \sim p_{G}(\cdot | z)}[1 - \log D(x,z)]]
```

はノイズ $z$ をgenerrator に入れて画像を生成し、そのペアを discriminator に入れた時の 1 -対数尤度

# 正常・異常の判定

学習の過程で encoderが出来上がってるので、推論においては anoGAN や ADGAN のような探索が必要ない。

１発の推論でanoGAN と同様に

```math

\begin{eqnarray}
A(x) &=& \alpha L_G(x) + (1 - \alpha ) L_D(x) \\
L_G(x) &=& \| x - G(E(x)) \|_1 \\
L_D(x) &=& \| f_D(x,E(x)) - f_D(G(E(x)),E(x)) \|_1 \\
\end{eqnarray}
```

を用いる。

# 実験と結果 
### MNIST を用いた実験 
1. MNISTの異なる１０numberの１つを異常クラス、他を正常クラスとする
2. 正常データの8割をtraining dataとし、他の2割と異常データをtest dataとする
3. メトリクスは AUPRC(area under the precision-recall curve)
4. 比較対象のモデルはVAEとanoGAN
5. 本モデルとanoGANに関しては、異常scoreの算出に上記のdiscriminatorの中間層からの出力を用いる場合（DF）、discriminatorからの最終出力を用いる場合（$\sigma$）の２つを検討する


結果は以下。

<img width="576" alt="anoGAN_002.png" src="https://qiita-image-store.s3.amazonaws.com/0/116706/48e8617f-ab2e-48f5-7b76-fc7678cefac6.png">

おおよそanoGAN、VAEを上回っている。特にdiscriminatorからの中間層出力を用いた(FM)方が性能がいい。

### KDDCUP99 を用いた実験

1. KDDCUP99 10 percent datasetの値が上位20%を異常、他を正常とする
2. 正常データの50%をtraining data、残りと異常データをtest dataとする
3. メトリクスは precision, recall, F1-score
4. 比較対象はOC-SVM、DSEBM、DAGMM、anoGAN
5. 本モデルとanoGANに関しては、異常scoreの算出に上記のdiscriminatorの中間層からの出力を用いる場合（DF）、discriminatorからの最終出力を用いる場合（$\sigma$）の２つを検討する

結果は以下。

<img width="881" alt="efficient-GAN_010.png" src="https://qiita-image-store.s3.amazonaws.com/0/116706/4124950d-ce0a-3aec-31ba-dba1184b1d73.png">

F1で見た時に、一番性能がいい。しかもanoGANの速度を700倍から900倍上回ったらしい。

# 実装例
tensorflow使った実装例は以下。
https://github.com/masataka46/BiGAN

ネットワーク・モデルはノーマルなGANにencoderが加わっただけなので、普段からGANをガンガン作ってる人には難しくないと思います。

###出力例

MNISTの５（正常データ）で学習して７を異常データとした時の例。

左から推論時の正常画像（５）、それをencodeして再度generateしたもの、異常画像（７）、それをencodeして再度generateしたもの。

![resultImage_18092602_990.png](https://qiita-image-store.s3.amazonaws.com/0/116706/2f0c4c8c-af09-d30e-4d04-703faabbcaff.png)



# reference
[2] J. Donahue, et. al."ADVERSARIAL FEATURE LEARNING"