はじめに
Autoencoder での異常検知について話す機会があったので、せっかくなので記事にもしておきます。
※注意
雰囲気を示すために例として celebA データセットを使った結果を出していますが、正常データ内に広いバリエーションがある場合だと今回紹介する手段では難しいです。記事内の結果はチェリーピックしたやつだと思ってください。
異常の検知
ここでの異常検知としては外観検査のようなものを想定します。リンゴの画像を正常データ、それ以外のミカン、トマトの画像を異常データとする場合、リンゴの画像をミカンやトマトの画像と区別するような問題を考えます。
異常データが入手可能な場合
こんな感じでリンゴ、ミカン、トマトのデータがそれぞれ沢山手に入る場合、それらを学習用データとして使えば (原理的には) 各クラス間の決定境界を決めることができるので、リンゴとそれ以外のものを判別できます。
異常データが入手できない場合
リンゴのデータは入手できるもののミカンやトマトのデータは手に入らないといった場合があります。例えば工業製品の欠陥検査などでは、正常データは多数手に入るものの異常データはほとんど手に入らない (そんなにぽんぽん欠陥品が出るようでは困る) というケースは多いです。
その場合でも、何らかの方法で正常データの分布を掴むことができればそこから外れたものを異常データとみなすことで正常/異常の判別に使えそうです。
正常データの分布との距離の取り方について、2次元データが実質的に1次元の直線上に分布しているようなケースを考えると下図のようになります。下図左は正常データの分布が1次元の直線上に分布していることを、下図右は判別対象である新しいインスタンスについて正常データ分布から得られた直線との距離を取ることを示しています。
具体的には、正常データについて主成分分析を行って正常データこの距離が近ければ正常、遠ければ異常とすることで異常の判別ができそうです。
高次元のデータではどうすれば?
データの次元が小さければ主成分分析でもしておけばよさそうですが、画像などの高次元なデータの場合はニューラルネットワークに頼りたいです。今回は Autoencoder を使った場合について紹介しますが、GAN や VAE を使う方法もあります。例えば Efficient GAN-Based Anomaly Detection などは GAN を使った異常検知の好例だと思います。
使用したニューラルネットワーク
適当な Convolutional Autoencoder です。損失関数は Mean Squared Error。
使用したデータ
celebA データセットを glasses 項目を参照して眼鏡あり/なしに分割し、眼鏡なしの画像を学習用データとしました。
結果
左から、入力画像、出力画像、入出力差分画像の順に並べています。眼鏡の部分の再構成が上手くできずに差分が大きくなっていることがわかります。髪の毛など、眼鏡以外の場所でも差分の大きい領域は出てきてしまうようです。