これまでは以下のように分類問題や検出問題、セグメンテーション問題、回帰問題について深層学習の実験をしてきましたが、今回は画像データでの異常検知をやってみようと思います。
異常検知をやるときには設定した問題に合わせて特徴量を定義してシンプルな手法を用いる方が、今までの経験上はうまくいくことが多いのです。
ただ、このブログの記事に書く内容は実験・勉強の意味合いも兼ねているので、今回はGANを使った異常検知を試したみたいと思います。
参考:過去記事
▼分類
【PyTorch】MNISTのサンプルを動かしてみた
▼検出
SSD (Single Shot MultiBox Detector) による物体検出
▼セグメンテーション
【Keras+TensorFlow】Deep Learningで顔検出をしてみた
【Keras+TensorFlow】Deep Learningでテロップ位置を検出してみた
▼回帰
【海洋物理】Deep Learningで海面高度/水温から鉛直プロファイルを推定してみた
GANによる異常検知のアルゴリズム
異常検知で使われるアルゴリズムには以下のようなものがあります。
- AnoGAN
- ADGAN
- Efficient GAN
- GANomaly
この中で比較的有名なのはAnoGANかなと思いますが、今回はGANomalyから派生したSkip-GANomalyを使用することにします。以下、特に断りがない限り、実装に関する図は当論文からの引用です。
Skip-GANomalyの概要はこのようになっています。
Skip-GANomalyの仕組み
概要としては、
- 正常データだけを入力として、正常データを正しく生成できるGeneratorを作る
- Real画像とFake画像を見分けられるDiscriminatorを作る
- 異常データを入力するとGeneratorはそのデータをうまく生成できないため、Real画像とFake画像の差分が大きくなる
- 異常データの場合、Discriminator中の特徴量もReal画像のときとFake画像のときで差が大きくなる
- それらの差分からAnomaly Scoreを算出して異常として検知する
という流れになっています。
もう少し詳しいネットワークの構造は下図の通りです。
GeneratorはSkip Connectionを持ったAutoEncoderで、DiscriminatorはReal or Fakeの2分類問題のシンプルなCNNになっています。
引用論文ではデータセットとして、下図のようにCIFAR-10、UBA、FFOBを使用しています。
やってみた結果
今回はまずは動作確認という意味合いで人工的に作成した正常/異常データを用いました。
いきなりでなんですが、人工的に作成したデータとはいえ少しだけ業務に関係したデータですので、具体的なデータの画像の掲載は差し控えます。
イメージとしては、異常データは何かしらのモノに汚れが付いているような画像データになります。
データ量は
- 学習データ:正常画像10000枚
- 評価データ:正常画像100枚/異常画像100枚
です。
早速ですが検知結果は以下のようになりました。
Epoch:1
なぜか正常画像の方がAnomaly Scoreが高い分布になっています。
Epoch:3
それっぽい感じになってきました。
1epoch目でどうしてスコアが逆になっていたのかは正直よく分かりませんが、3epochでもう正常になっているので学習が不十分で変な結果になっていただけでしょう。
Epoch:10
完全に検出できる感じになりました。
現実のデータでここまでうまく閾値が引けることはまずないと思いますが、今回は人工的に作成したデータなので、むしろ綺麗に分割されているのが正しい状態だと思います。
むしろ、人工的なデータですらうまく検知できなかったとしたらモデルがそもそも正しく実装できていないということでしょう。
まとめ
という訳で簡単にではありますが、人工的に作成した画像データでのGANを用いた異常検知のデモでした。
とりあえずは綺麗に検知できているようなので、今後はこれをベースにより実践的なデータでも検証をやってみたいと思います。