画像向けAI異常検知で間違い探しを解いてみた

はじめまして、今年の1月にInsight Edgeへ参画したData Scientistの山科です。 まだ加入して数ヶ月ですが、画像を用いた異常検知や予兆保全、オペレーションの最適化、生成AI用いたDX案件など、幅広い技術・分野に携わらせてもらっており、日々、調査にデータ分析の試行錯誤と四苦八苦しながら業務に取り組んでいます。

今回は、画像を用いた異常検知に関する案件でPatchCoreという手法を用いたのですが、使い勝手が良く様々なことに使えそうだなと感じましたので、間違い探しを題材にパラメータのケーススタディをした結果を評価し、どういったことに使えるかを考察していきたいと思います。

目次

画像に対する異常検知手法

画像認識技術を用いた異常検知の重要性については、藤村さんの記事 でも紹介されている通りで、製造業や農業など幅広い分野で省力化・効率化のため用いられています。
画像に対する異常検知技術としては、近年、ディープラーニングベースのものが主流となっており、そのなかでもハイブリットモデルと呼ばれる、事前学習済みのニューラルネットワークモデルと異常検知として長く用いられているkNNを組み合わせた手法がSOTAを達成しています。ハイブリットモデルとしても、SPADE、PaDiM、PatchCore、といった手法が提案されていますが、今回は PatchCore を選択しました。

PatchCoreでは、学習済みモデル用いて正常画像から抽出した特徴量をMemory Bankに保存しておき、判定したい画像の特徴量との距離から正常/異常を判定します。この時、学習済みモデルを特徴量抽出器として用いているためニューラルネットワークの再学習が不要な点、学習済みモデルの最終層ではなく中間層から特徴量を取得するようにしたことで画像の位置情報も保持することで、局所的な異常(ピクセル単位での異常)を見つけやすくしている点が特徴となっています。

今回は、ind_knn_ad で実装されているPatchCoreを用いて検証して行きます。

AIで間違い探しを解く!

間違い探しはよく似た絵から異なる箇所を探すパズルですが、異常検知も検証したい画像が正常な画像と比べてどこが似ているか、異なっているかを探すタスクですので異常検知と同様に考えられます。間違い探しの題材としましては、春といえばさくら、ということで下図の間違い探しに取り組んで行きたいと思います。画像サイズはそれぞれ、950✕1450となっており、間違い箇所は5箇所です。(私は2コしか見つけれませんでした。。。)

Fig.1 間違い探し(左:正しい画像、右:間違い画像)

まず、デフォルトの設定値で間違い箇所を検知した結果を下図に示します。左から学習画像(正しい画像)、検証画像(間違い画像)、検証画像+異常度を示しています。異常度の結果を見ると全体的に赤くなっており、異常度が高い、つまりほとんどの箇所で間違っていると出力してしまっています。また、Fig.1と比べると正方形に修正(リサイズ)されており、右側や左側に関しては異常検知できていないことがわかります。

Fig.2 デフォルト設定値での結果

リサイズされていることに関して、プログラムを見てみると画像の前処理として高さを256に(アスペクト比を維持して)リサイズしたあとに、CenterCropで224✕224のサイズで抽出していることがわかりました。これにより、周りの画像が切り取られてしまいますので(中心に検知対象が写っており、周りは背景になっているような画像を想定しているのだと思います。実際に製造現場ではそういった画像を扱うことが多いです。)、この前処理部分の修正として、CenterCropの処理をコメントアウトしていきます。

# 学習データの読み込み部
size=224
class MVTecTrainDataset(ImageFolder):
    def __init__(self, cls : str, size : int):
        super().__init__(
            root=DATASETS_PATH / cls / "train",◊
            transform=transforms.Compose([
                transforms.Resize(256, interpolation=transforms.InterpolationMode.BICUBIC),
                transforms.CenterCrop(size),
                transforms.ToTensor(),
                transforms.Normalize(IMAGENET_MEAN, IMAGENET_STD),
            ])
        )
        self.cls = cls
        self.size = size

CenterCropの処理をコメントアウトした結果を以下に示します。画像全体に対して異常検知できるようになりましたが、相変わらず赤い箇所が多いままとなっています。

Fig.3 CenterCropの処理をコメントアウトした結果

これは、特徴数のサンプリングの割合(Memory Bankに保存するピクセルの割合)がデフォルトでは1%となっており、正常と学習しているピクセルのパターンが少ないため正しく判定できなかったと考えられます。このためサンプリングの割合を10%、50%、70%と変えて評価したいと思います。各ケースで異常度を算出した結果を下図に示します。これよりサンプリングの割合を増やすことで、部分的に異常度が高く(図中では赤く)なることが確認できます。サンプリングの割合を増やすことで画像中のピクセルを満遍なく学習でき、誤検知を減らすことができていると考えられます。
50%や70%のときの結果を見ると、①真ん中右より、②右側の桜の木の後ろ側、の2箇所で異常度が高くなっていることが確認できます。実際に、①さくらの木が無くなっている、②鹿が増えている、ので間違いを見つけることができました。

Fig.4 サンプリング割合を変えた場合の結果

さくらの木や鹿は比較的大きいので、他3箇所はもう少し小さい変化の可能性があります。ですので、次は前処理で行っているリサイズの割合をデフォルトの25%(正確には256/950=26.95%)から、50%、75%、100%に変更して評価します。サンプリング割合は50%としました。 リサイズの割合を変えた結果を以下に示します。これより、75%以上でより局所的に異常度が増加していますが、いずれのケースでも③間違いケースではなくなっているさくらの木の下側の通路沿い、④石階段の中断右側、で異常度が増加していることが確認できます。実際に、③では通路沿いに石が増えている、④階段に石が増えている、ので新たに間違いを②つ見つけることができました。あと1つですね。

[ ]
Fig.5 画像解像度を変えた変えた場合の結果

次に、特徴量抽出器であるバックボーンのアルゴリズムを変えてることで間違いを見つけられるか確認していこうと思います。デフォルトでのバックボーンはEfficientNet-b0となっていますので、以下のアルゴリズムを検証しました(各アルゴリズムの詳細は割愛させていただきます)。分析条件は、サンプリング割合:50%、前処理:CenterCrop無し、リサイズ75%としています。

  • EfficientNet-b7(tf_efficientnet_b7)
  • Efficientnet-v2-s(tf_efficientnetv2_s)
  • Mobilenet-v3-large(tf_mobilenetv3_large_100)
  • wide_resnet50_2

いずれのケースでもEfficientNet-b0と同様に、これまでに見つけた4箇所で異常度が増加していることがわかります。Efficientnet-v2-sでは局所的に異常度が増加している箇所が何箇所が増えています。

Fig.6 特徴量抽出器を変更した結果

これらの特徴量抽出器アルゴリズムの結果を眺めるて見ると、いずれも左側の桜の木の中段右横でわずかに異常度が増加していることがわかります。この部分を拡大して見てみると、確かに、花びらが1枚なくなっています!!!
これにて、なんとか5コ全ての間違いを見つけることができました。

Fig.7 左側桜の木を拡大

ロバスト性評価

間違い探しの場合は、厳密に位置合わせができていますが、製造現場などの実際のユースシーンでは撮影時の角度や明るさといった撮像環境が学習時と検証時とで異なるケースのほうが多いかと思います。ここでは、ランダムに平行移動した画像を学習画像とした場合に、間違いを検知できるか確認したいと思います。

学習させた画像例は以下の通り。

Fig.8 ロバスト性検証用学習画像

評価条件としては、サンプリング割合:50%、特徴量抽出器:EfficientNet-b7(Fig.6~9の中では、誤検知が少ないため)、前処理:CenterCrop無し、リサイズ75%)としました。間違い以外の箇所でも異常度が増加していますが、5箇所の間違い箇所でも異常度が増加しており、位置ズレに対してもロバストに検知できることがわかりました!

Fig.9 位置ズレ検証結果

技術の価値と今後の可能性

今回、間違い探しを例題に、画像の異常検知技術であるPatchCoreを試し、各パラメータを調整した際の影響を評価しました。結果として5箇所全ての間違いを見つけることができましたが、パラメータの調整やパラメータを変えたモデルのアンサンブル適用などが必要でした。
試してみて、PatchCoreの特徴として、次のことがわかりました。

  • 特徴量抽出器に学習済みモデルを活用できるので、異常検知には少量の画像でも精度が出せ、モデルの学習にも時間を要しない
  • ピクセル単位での異常検知が可能
  • 位置ズレに関してもロバストに検知可能で、実問題にも適用しやすい

このことから、適用先として以下のようなタスクの対しても適用できると考えられます。

  • どういった状態で流れてくるかわからない製造ラインでの異常検知
  • 形・色等が様々な農業での品質管理など
  • 製品組み立て後の配線などの確認
  • カメラ画像を用いた、特定箇所での位置判定

一方で、画像を用いる際の異常検知の課題として、以下が残っていますので、引続き技術動向を調査して行きたいと思います。

  • 画像に映らない箇所に対しては、検知のしようが無いので、複数のカメラでもれなく撮影する必要がある
  • 位置に関するロバスト性は確認できたが、明るさといった違いにも過敏に反応することもあったので、ご検知を減らすためには室内で撮像環境を一定とする必要がある