異常検知でググった際によく出てきたEfficientNetを試してみました。
コードはQiita等の記事をかなり参考にさせて頂きました。
(どういった計算をしているか等、理解できていないところがまだまだ多いです。)
コード以外のメモについては簡単ですがこちら
推論の流れ
- データセット作成
- データはよく出てくるMVTECの中から木の表面とネジの2種で検証
- ダウンロード時はgood,scratch,hole等にフォルダ分かれているが、good,badフォルダのみに修正
- 前処理やデータ拡張は今回はなし。リサイズのみ。(実際業務でやる際は前処理の検討は重要)
- クロスバリデーション用にStratifiedKFoldでデータを分割
- 教師用データはgood(良品)のみ
- データはよく出てくるMVTECの中から木の表面とネジの2種で検証
- モデル作成
- 画像認識ライブラリのtimmを利用
- model_nameは結構種類あったと思いますが、tf_efficientnet_b4_nsを使用(b6も試したけど結果は忘れました)
- 推論
- クロスバリデーション3分割で3回実施
- EfficientNetの指定した層の配列を特徴量として、教師データのマハラノビス距離を算出
- テストデータの良品、異常品のマハラノビス距離も算出し、f1が最大となるマハラノビス距離の閾値を求める
- 上の閾値で混同行列を作成し、推論の正誤を確認する
コード
コードはこちら
参照
ほとんど以下記事のコードから抜粋です。
大変参考になりました。ありがとうございます。
【異常検知】MVTec-ADを学習無しで正常/異常分類する
【異常検知】学習ゼロの衝撃!を可視化する
結果
1. 木の表面
クロスバリデーション毎のマハラノビス距離
教師データのマハラノビス距離は0、テストデータの良品の距離は0.1程度、不良品は0.5以上と分類できていそうな感じ
分類結果の混同行列
-
f1が最大となるマハラノビス距離の閾値により分類
-
マハラノビス距離のヒストグラム
異常部位の可視化
特徴が大きいところの色が明るくなるように可視化している。
木目模様っぽいところも明るくなってしまっているが、全体的に結構可視化できている
(これは全部【異常検知】学習ゼロの衝撃!を可視化するのおかげです。)
- level=7の場合
特徴量として使う層を変えると
-
level=2の場合
-
level=4の場合
2. ネジ
おまけ程度にやってみました。
クロスバリデーション毎のマハラノビス距離
木の表面に比べて、テストデータの良品と不良品の差が小さい。
EffNet調べているときに、素材の表面みたいなのは得意だが、3次元の物体になると精度落ちるという記事を見たがやはりそうなのか。
普通に考えて画像によってネジの向き変わっていたり、EffNetでなくても、ネジの方が何倍も難しそう。
分類結果の混同行列
木の表面と比べると精度大きく落ちている。
特に異常の予測はランダムに近い。
異常部位の可視化
なぜ背景が黄色い、、、すみませんめんどうなのでこのまま。
上手く特徴抽出できていないのがよくわかる。
所感
- 木の表面の精度は高かったが、現実でこういうのやろうとすると、ハードルが相当たくさんあって、こんなに簡単に上手くいかないよね(データの質、撮影環境、どう実運用するのか、費用対効果 等々)
- とはいえぱっと使う場合に相性が良いものであれば、ある程度の精度はお手軽に出せるのかも
おまけ(HLACによる異常検知)
おまけ程度にやってみました。
HLACによる異常検知