深層学習論文: CVPR 2023 VAND ワークショップのためのゼロ/フューショット異常分類およびセグメンテーション手法

深度学习论文: CVPR 2023 のためのゼロ/フューショット異常分類およびセグメンテーション手法 VAND ワークショップ チャレンジ トラック 1&2: ゼロショット AD で 1 位およびフューショット AD で 4 位 A Zero-/Few-Shot Anomaly Classification
and CVPR 2023 VAND ワークショップ チャレンジ トラック 1 および 2 のセグメンテーション方法: ゼロショット AD で 1 位、フューショット AD で 4 位
PDF: https://arxiv.org/pdf/2305.17382.pdf
PyTorch 代: https://github. com/shanglianlm0525/CvPytorch
PyTorch代償: https://github.com/shanglianlm0525/PyTorch-Networks

1。概要

工業用外観検査における製品タイプの幅広い多様性に対応するために、当社は多数のカテゴリに迅速に適応でき、通常の参照画像をまったくまたはほとんど必要としない単一モデルを構築し、工業用外観検査により効率的なソリューションを提供します。2023 年の VAND チャレンジに対するゼロ/少数サンプル追跡のソリューションが提案されています。

1) ゼロショット タスクでは、提案されたソリューションは、CLIP モデルに追加の線形レイヤーを追加して、画像特徴を結合埋め込み空間にマッピングします。これにより、テキスト特徴と比較して異常マップを生成できるようになります。
2) 参照画像が利用可能な場合 (ショットが少ない場合)、提案されたソリューションは複数のメモリ バンクを利用して参照画像の特徴を保存し、テスト時にそれらをクエリ画像と比較します。

この課題では、私たちの手法は Zero-Shot で 1 位を達成し、セグメンテーションでも良好なパフォーマンスを示し、2 位の競合他社よりも F1 スコアが 0.0489 向上しました。Few-Shotでは総合4位、F1分類スコアで1位を獲得しました。

核心点:

  • 状態とテンプレートのプロンプトの統合を使用して、テキスト プロンプトを作成します。
  • 異常な領域の位置を特定するために、追加の線形レイヤーが導入され、CLIP 画像エンコーダーから抽出された画像特徴をテキスト特徴が位置する線形空間にマッピングします。
  • マッピングされた画像の特徴とテキストの特徴の間の類似性を比較して、対応する異常マップを取得します。
  • 少数ショットでは、ゼロ ショット ステージの追加の線形レイヤーが保持され、その重みが維持されます。さらに、テスト段階では画像エンコーダを使用して参照画像の特徴を抽出し、テスト画像の特徴と比較するためにそれらをメモリ バンクに保存します。
  • 浅い特徴と深い特徴を最大限に活用するために、画像エンコーダの異なる段階の特徴が同時に利用されます。

2 方法論

全体として、ゼロショット分類には CLIP の全体的なフレームワークを採用し、状態とテンプレート コレクションの組み合わせを使用してテキスト プロンプトを構築します。画像内の異常領域の位置を特定するために、CLIP 画像エンコーダーから抽出された画像特徴をテキスト特徴が存在する線形空間にマッピングする追加の線形レイヤーを導入します。次に、マッピングされた画像特徴とテキスト特徴の類似性比較を実行して、対応する異常マップを取得します。少数サンプルの場合、ゼロサンプルステージの追加の線形レイヤーを保持し、それらの重みを維持します。さらに、画像エンコーダを使用して参照画像の特徴を抽出し、それらをメモリ バンクに保存し、テスト段階でテスト画像の特徴と比較します。浅い特徴と深い特徴を十分に活用するために、ヌル設定と少数ショット設定の両方で異なる段階の特徴を使用することに注意してください。

ここに画像の説明を挿入します

2-1 ゼロショットAD

異常分類は
WinCLIP 異常分類フレームワークに基づいており、複雑なマルチスケール ウィンドウ戦略を使用せずに Baseline の異常分類精度を大幅に向上させるテキスト プロンプト統合戦略を提案します。具体的には、統合戦略には、テンプレート レベルと状態レベルの 2 つの部分が含まれます。
1) 状態レベルのテキスト プロンプトは、「エッジ周囲のチップ」やコーナーを使用せずに、正常または異常なターゲット (欠陥がない、破損しているなど) を説明する一般的なテキストを使用します。 ";
2) テンプレート レベルのテキスト プロンプト。提案されたソリューションでは、CLIP で ImageNet 用の 85 個のテンプレートをスクリーニングし、「奇妙な [obj.] の写真」およびその他の適用できない項目を削除しました。異常検出タスク用のテンプレート。
これら 2 つのテキスト ヒントは、CLIP のテキスト エンコーダを通じて最終的なテキスト特徴として抽出されます: F t ∈ R 2 × C F_{t} \in R^{2 \times C}FR2 × C

def encode_text_with_prompt_ensemble(model, texts, device):
    prompt_normal = ['{}', 'flawless {}', 'perfect {}', 'unblemished {}', '{} without flaw', '{} without defect', '{} without damage']
    prompt_abnormal = ['damaged {}', 'broken {}', '{} with flaw', '{} with defect', '{} with damage']
    prompt_state = [prompt_normal, prompt_abnormal]
    prompt_templates = ['a bad photo of a {}.', 
                        'a low resolution photo of the {}.', 
                        'a bad photo of the {}.', 
                        'a cropped photo of the {}.', 
                        'a bright photo of a {}.', 
                        'a dark photo of the {}.', 
                        'a photo of my {}.', 
                        'a photo of the cool {}.', 
                        'a close-up photo of a {}.', 
                        'a black and white photo of the {}.', 
                        'a bright photo of the {}.', 
                        'a cropped photo of a {}.', 
                        'a jpeg corrupted photo of a {}.', 
                        'a blurry photo of the {}.', 
                        'a photo of the {}.', 
                        'a good photo of the {}.', 
                        'a photo of one {}.', 
                        'a close-up photo of the {}.', 
                        'a photo of a {}.', 
                        'a low resolution photo of a {}.', 
                        'a photo of a large {}.', 
                        'a blurry photo of a {}.', 
                        'a jpeg corrupted photo of the {}.', 
                        'a good photo of a {}.', 
                        'a photo of the small {}.', 
                        'a photo of the large {}.', 
                        'a black and white photo of a {}.', 
                        'a dark photo of a {}.', 
                        'a photo of a cool {}.', 
                        'a photo of a small {}.', 
                        'there is a {} in the scene.', 
                        'there is the {} in the scene.', 
                        'this is a {} in the scene.', 
                        'this is the {} in the scene.', 
                        'this is one {} in the scene.']

    text_features = []
    for i in range(len(prompt_state)):
        prompted_state = [state.format(texts[0]) for state in prompt_state[i]]
        prompted_sentence = []
        for s in prompted_state: # [prompt_normal, prompt_abnormal]
            for template in prompt_templates:
                prompted_sentence.append(template.format(s))
        prompted_sentence = tokenize(prompted_sentence).to(device)
        class_embeddings = model.encode_text(prompted_sentence)
        class_embeddings /= class_embeddings.norm(dim=-1, keepdim=True)
        class_embedding = class_embeddings.mean(dim=0)
        class_embedding /= class_embedding.norm()
        text_features.append(class_embedding)
    text_features = torch.stack(text_features, dim=1).to(device).t()

    return text_features

画像エンコーダを介した対応する画像特徴は次のとおりです。F c ∈ R 1 × C F_{c} \in R^{1 \times C}FcR1 × C
CLIP テキスト エンコーダーを使用してテキスト特徴を抽出し、それぞれ正常な特徴と異常な特徴を平均する、状態レベルとテンプレート レベルの統合実装。最後に、正常および異常な特徴の平均値が画像特徴と比較され、分類スコアとしてソフトマックス後の異常カテゴリ確率が得られます
。 F_{t}^ {T})s=so f t max ( F _cFtT最後にss
を選択異常検出分類問題の結果としてのsの 2 番目の次元。

text_probs = (100.0 * image_features @ text_features.T).softmax(dim=-1)
results['pr_sp'].append(text_probs[0][1].cpu().item())

異常セグメンテーションは、
異常セグメンテーションに対する画像レベルの異常分類方法に似ており、バックボーンによって抽出されたさまざまなレベルの特徴とテキスト特徴の間の類似性を測定するのが自然な考え方です。ただし、CLIP モデルは分類スキームに基づいて設計されています。つまり、分類に使用される抽象的な画像特徴を除き、他の画像特徴は統一された画像/テキスト空間にマッピングされません。したがって、この問題を解決するためのシンプルだが効果的な解決策を提案します。追加の線形レイヤーを使用して、さまざまなレベルで画像の特徴を画像/テキスト結合埋め込み空間にマップします。つまり、線形レイヤーは patch_token をマップし、それぞれに基づいてそれらを合計します。 patch_token. テキストの特徴は、異常マップを取得するための類似度計算に使用されます。、上の図の青いゼロショット異常マップ プロセスを参照してください。具体的には、異なるレベルの特徴が線形層を介して特徴空間変換に一緒に埋め込まれ、変換された特徴がテキスト特徴と比較されて、異なるレベルでの異常マップが取得されます。最後に、さまざまなレベルの異常グラフが単純に合計されて、最終結果が得られます。

patch_tokens = linearlayer(patch_tokens)
anomaly_maps = []
for layer in range(len(patch_tokens)):
  patch_tokens[layer] /= patch_tokens[layer].norm(dim=-1, keepdim=True)
  anomaly_map = (100.0 * patch_tokens[layer] @ text_features.T)
  B, L, C = anomaly_map.shape
  H = int(np.sqrt(L))
  anomaly_map = F.interpolate(anomaly_map.permute(0, 2, 1).view(B, 2, H, H),
  size=img_size, mode='bilinear', align_corners=True)
  anomaly_map = torch.softmax(anomaly_map, dim=1)[:, 1, :, :]
  anomaly_maps.append(anomaly_map.cpu().numpy())
anomaly_map = np.sum(anomaly_maps, axis=0)

Linear Layer のトレーニング (CLIP 部分のパラメーターはフリーズされています) は、Focal Loss と Dice Loss を使用します。

2-2 数発AD

異常の分類
少数ショット設定の場合、画像の異常予測は 2 つの部分から行われます。最初の部分はゼロショットセットアップと同じです。2 番目の部分は、異常マップの最大値を考慮して、多くの AD 手法で使用されている従来のアプローチに従います。提案されたスキームは、これら 2 つの部分を最終的な異常スコアとして追加します。

異常セグメンテーションの
少数ショット セグメンテーション タスクは、図 1 の黄色の背景に示すように、メモリ バンクを使用します。
端的に言えば、クエリ サンプルとメモリ バンク内のサポート サンプルのコサイン類似度が計算され、その後、変形によって異常マップが取得され、最後にゼロショットによって取得された異常マップが異常マップに追加され、最終的なセグメンテーション予測を取得します。
さらに、少数ショット タスクでは、前述の線形層を微調整する必要はなく、ゼロショット タスクで学習された重みが直接使用されます。

3 実験

ここに画像の説明を挿入します
簡単に言えば、単純な画像ではゼロショットと少数ショットは同様の効果を持ちますが、難しいタスクに直面した場合は少数ショットの方が効果が高くなります。

おすすめ

転載: blog.csdn.net/shanglianlm/article/details/132276540
おすすめ