【PyTorch】画像データの異常検知(逆に失敗編) - 加賀百万石ですが何か?

【PyTorch】画像データの異常検知(逆に失敗編)

前回、【PyTorch】画像データの異常検知(デモ編)ということで、人工的に生成した正常/異常画像を用いて動作確認ついでにデモとして結果を掲載しました。

人工的なデータなので綺麗な結果が出るのは当然ですので、今回はより実践に近いデータでやってみたいと思います。

使用データ

今回使用したデータはカーペットの拡大画像です。

以下は、サンプルとして正常(左)と異常(右)の画像を5枚ずつ表示したものです

画像の枚数は実践に近いデータとしたため、GANベースのネットワークを学習させるには正直データ不足なのですが、仕方なく以下のような枚数となりました。

  • 学習:正常画像のみ280枚
  • 評価:正常画像28枚/異常画像89枚

学習と評価結果

使用したアルゴリズムは前回同様にSkip-GANomalyです。詳細(というほど詳しく書いてはいないですが)は前回の記事をご覧ください。

まずはEpoch数と評価画像の正常/異常の分布です。

Epoch=1

1 Epoch目なので精度については特にどうこういうつもりはないというか、そもそも議論できる状態ではないです。

ただ、前回のデモ編のときと同様に最初は正常画像の方がAnomaly Scoreが高くなっている状態にあることが少し気になりますね。

アルゴリズム上の特性なんでしょうかね…?

Epoch = 5

5 Epoch目が経過したところです。

正常画像の分布が1 Epoch目のときよりはAnomaly Scoreが低い側に遷移していますが、まだまだ全然判別はできていない状態です。

Epoch = 10

10 Epochが経過したところです。

正常も異常も区別なく同じような分布になってしまっています。

まったく分類できていなくて正常も異常も同じようにAnomaly Scoreを算出してしまっている状態です。

この後もしばらく学習を続けたのですが結果は全然変わらなかったので、ヒストグラムはここまでとします。

生成された画像

結果は全然判別できないというものでしたが、念のためGeneratorが10 Epoch目で生成している画像を確認してみることにします。

まずは正常画像です。左がReal画像  (Generatorの入力画像) で右がFake画像 (Generatorからの出力画像) です。

これを見ると、わずかな色味の差はあるもののほぼ完全に正常画像を再生成できているようです。

GANを使用するそもそもの目的として「正常画像を正しく生成できるようにする」というものがあるので、これはとりあえず特に問題はなさそうです。

次に異常画像です。左右は正常画像のときと同様です。

明らかに異常画像も正しく再生成できてしまっていますね。

正常画像だけで学習しているので異常画像は上手く生成できないためAnomaly Scoreが高くなるという原理で異常検知を行っているのでこれでは正常/異常の分類ができなくて当然です。

と言うことで問題は「なぜ正常画像しか学習させていないのに、異常画像も正しく再生成できてしまっているか」と言うことです。

確かな原因を探るのは、深層学習の性質上なかなか難しいのですが、考えられる原因のひとつとしてSkip Connectionの存在が挙げられそうです。

論文から図を再度引用しますが、Skip-GANomalyのネットワークはこのようになっています。

このGenerator部分ですが、U-Netと似たような構造で画像を入力した直後からSkip ConnectionでEncoder-Decoderの中間層を飛ばしています。

もともとSkip-GANomalyはGANomalyを改良してSkip Connectionを追加したネットワークであるはずなのですが、今回の題材に関しては逆効果となってしまっている可能性があります。

このSkip Connectionがあるせいで、入力した画像の情報のほぼすべてをEncoder-Decoder部分を通さずに再生成画像として出力しているのではないかと考えられそうです。

もし入力画像が正しくEncoder部分を通過しているならば、画像サイズがかなり圧縮されますので、カーペットの繊維ひとつひとつがここまで綺麗に再生成されるのは逆に不自然なように思えます。

入力画像を再生するAutoEncoderとしてGeneratorを学習させているので、入力した画像が正確に再生成されいていること自体はある意味成功と言えますが、今回の目的から鑑みると明らかによくない状態ですので、今回の検証はタイトルにあるように「逆に失敗」してしまったと言える結論のようです。

まとめ

前回は人工的な正常画像と異常画像を生成してデモ編として検証しました。そして、今回はより実践的なデータを用いて画像の異常検知をやってみましたが、Generatorが異常画像まで上手く再生成できるようになってしまっていたために、正常/異常の判別が上手くいきませんでした。

今回の検証結果から、少なくとも今回の検証条件ではSkip Connectionが悪影響を及ぼしていそうな状況が見て取れたため、ネットワーク構造を見直すなどの根本的なチューニングが必要となりそうです。

今後は特にGenerator部分に焦点を当てて、もう少し検証を進めて行こうかなと思います。

スポンサーリンク