DUICUO

QdrantとFiftyOneに基づく近傍埋め込み検索アルゴリズムの実用化

翻訳者 |朱賢宗

校正:孫淑娟

導入

ニューラルネットワークの埋め込みは、入力データの低次元表現を可能にし、幅広いニューラルネットワークアプリケーションに利用できます。埋め込みはデータポイントの意味を捉えることができるため、いくつかの興味深い機能を提供します。これは特に画像や動画などの非構造化データに有効で、ピクセルの類似性だけでなく、より複雑な関係性もエンコードできます。

FiftyOne と Plotly を使用して、BDD100K データセットの埋め込みを視覚化します。

これらの埋め込みに対する検索は、分類タスク、レコメンデーションシステムの構築、さらには異常検知タスクなど、多くのシナリオに適用できます。これらのタスクを実行するために埋め込みに対して最近傍探索を実行する主な利点の一つは、新しい問題ごとにカスタムネットワークを作成する必要がないことです。多くの場合、事前学習済みのモデルを使用できます。さらに、公開されているモデルを使用して生成された埋め込みを、追加の微調整なしで使用することも可能です。

埋め込みには多くの強力なユースケースがありますが、埋め込み検索ワークフローの実行には、程度の差はあれ課題が伴うことがよくあります。特に、大規模なデータセットに対して最近傍検索を実行し、その検索結果に基づいて効果的な操作を行う(例えば、自動ラベル付けされたデータに対するワークフローを実行する)ことは、技術的にもツール的にも課題となります。これらの課題に対処するために、オープンソースソフトウェアプログラムであるQdrantとFiftyOneは、これらのワークフロータスクを簡素化するのに役立ちます。

  • Qdrant は、高密度ニューラル埋め込みに対して近似最近傍探索 (ANN) を実行するように設計されたオープンソースのベクトル データベースであり、大量のデータに拡張することが期待されるあらゆる実稼働対応システムに不可欠です。
  • FiftyOne はオープンソースのデータセット管理およびモデル評価ツールであり、開発者がデータセットを効果的に管理および視覚化し、埋め込みを生成し、モデル結果を改善できるようにします。

本稿では、MNISTデータセットをFiftyOneに読み込み、ANNに基づく分類を実行します。データポイントは、トレーニングデータセット内のK近傍点から最も一般的な参照回答ラベルを選択することで分類されます。言い換えれば、各テストサンプルについて、選択された距離関数を用いてK近傍点を選択し、投票によって最適なラベルを選択します。ベクトル空間におけるすべての探索は、高速化のためにQdrantを用いて実行されます。その後、FiftyOneで分類結果を評価します。

インストール

Qdrantのセマンティック検索を使い始めるには、ツールがクライアントサーバー方式で動作するため、インスタンスを実行する必要があります。最も簡単な方法は、公式のDockerイメージを使用することです。Qdrantの起動には、以下のコマンド1つだけが必要です。

 docker run -p "6333 : 6333 " -p "63 34 : 6334 " -d qdrant / qdrant

このコマンドを実行すると、Qdrant サーバーが実行され、ポート 6333 で HTTP API が公開され、ポート 6334 で gRPC インターフェースが公開されます。

さらに、いくつかのPythonパッケージをインストールする必要があります。FiftyOneを使用して、データ、参照回答ラベル、そして埋め込み類似度モデルによって予測されたデータを可視化します。埋め込みは、torchvisionで提供されているMobileNet v2を使用して作成します。もちろん、何らかの方法でQdrantサーバーと通信する必要があります。Pythonを使用するため、このタスクにはQdrant_clientを使用することをお勧めします。

 pipインストール51
pip でtorchvisionをインストール
pipでqdrant_clientをインストールする

全体的なタスクフロー

1.データセットをロードする

2. 埋め込みを生成する

3. 埋め込みファイルをQdrantに読み込む

4. 最近傍分類

5. フィフティワン評価

データセットの読み込み

スムーズに動作させるには、いくつかの手順が必要です。まず、 MNISTデータセットを読み込み、そこから学習サンプルを抽出します。これは、探索処理で使用するためです。処理を高速化するため、すべてのサンプルを使用するのではなく、2500個だけを使用します。FiftyOneデータセットZooを使用すれば、必要なMNISTサブセットを1行のコードで読み込むことができます。

 foとしてfiftyoneをインポート
fiftyone.zoofozとしてインポートします

#データを読み込む
データセット= foz . load_zoo_dataset ( "mnist"max_samples = 2500 )

# すべてのトレーニングサンプルを取得する
train_view =データセット. match_tags ( tags = [ "train" ])

次に、FiftyOne アプリケーションで使用されるデータセットを詳しく見てみましょう。

 #FiftyOne でデータセットを視覚化する
セッション= fo.launch_app (train_view )

埋め込み生成

次のステップは、データセット内のサンプルに埋め込みを生成することです。これは、FiftyOneの外部でカスタムモデルを使用していつでも実行できます。また、FiftyOneはFiftyOneModelZooで様々なモデルを提供しており、これらを直接使用して埋め込みを生成することもできます。

この例では、ImageNet でトレーニングされた MobileNetv2 を使用して、各画像の埋め込みを計算します。

 #各画像の埋め込みを計算する
モデル= foz . load_zoo_model ( "mobilenet-v2-imagenet-torch" )
train_embeddings = train_view.compute_embeddings (モデル)

埋め込まれた結果をQdrantにロードする

Qdrantはベクトルだけでなく、対応する属性も保存できます。各データポイントにはベクトルが関連付けられており、オプションでJSON型の属性項目も保存できます。これを利用して参照用の回答ラベルを渡し、後で予測を行えるようにします。

 ground_truth_labels = train_view.values ​​( "ground_truth.label" )
train_payload = [
{ "ground_truth" : gt } ( ground_truth_labels内のgtの場合
]

埋め込みを作成したら、Qdrantサーバーとの通信を開始できます。QdrantClientのクラスインスタンスは必要なメソッドをすべて備えているため、特に便利です。接続して「mnist」という名前の点のコレクションを作成しましょう。ベクトルのサイズはモデルの出力によって異なります。そのため、後で異なるモデルを試したい場合は、異なるモデルをインポートする必要がありますが、それ以外の設定は変わりません。最後に、コレクションが存在することを確認したら、すべてのベクトルと、それぞれのラベルを含むペイロードを送信できます。

 qdrant_client をqcとしてインポートします
qdrant_client.http.modelsからDistanceインポート

#トレーニング済みの埋め込みデータをQdrantにロードする
デフcreate_and_upload_collection (
埋め込みペイロードコレクション名= "mnist"
):
クライアント= qc . QdrantClient (ホスト= "localhost" )
クライアント.コレクションの再作成(
コレクション名=コレクション名
vector_size =埋め込み.形状[ 1 ],
距離=距離.コサイン,

クライアント.アップロードコレクション(
コレクション名=コレクション名
ベクトル=埋め込み
ペイロード=ペイロード

リターンクライアント

クライアント= create_and_upload_collection ( train_embeddingstrain_payload )

最近傍分類

それでは、データセットを使って推論を実行してみましょう。テストデータセットの埋め込みを作成できますが、基本的な事実は無視してANNを用いて埋め込みを見つけ、2つのデータが一致するかどうかを比較します。埋め込みの作成から段階的に進めていきましょう。

 # 各サンプルの近傍から最も一般的なラベルを選択して、テスト埋め込みにラベルを割り当てます。
test_view =データセット. match_tags ( tags = [ "test" ])
test_embeddings = test_view.compute_embeddings (モデル)

いよいよ「魔法」を働かせる時です。テストデータセット内のサンプルと対応する埋め込みを反復処理し、検索操作を使ってトレーニングセットから最も近い15個の埋め込みを見つけましょう。また、特定のポイント付近で最もよく見られるラベルを見つけるために必要な参照回答ラベルを含むペイロードも選択する必要があります。PythonのCounterクラスのおかげで、定型的なコードの書き換えは不要です。FiftyOneの各テストサンプルでは、​​最もよく見られるラベルが「ann_production」として保存されます。

これらすべては以下の関数に具体化されています。この関数は埋め込みベクトルを入力として受け取り、Qdrant検索関数を用いてテスト埋め込みの最近傍を見つけ、型予測を生成し、FiftyOneデータセットに保存できるFiftyOne分類オブジェクトを返します。

コレクションをインポートする
tqdmからtqdmをインポート

デフgenerate_fiftyone_classification (
埋め込みコレクション名= "mnist"
):
search_results =クライアント.検索(
コレクション名=コレクション名
query_vector =埋め込み
with_payload = True
トップ= 15

#各タイプの出現回数をカウントし、最も一般的なラベルを選択し、最も一般的なラベルの出現回数を結果の合計数で割ることで信頼度レベルを推定します。
カウンター=コレクション.カウンター(
[ point . payload [ "ground_truth" ] のpointsearch_resultsある場合]

予測クラス発生回数=カウンター最も多い( 1 )[ 0 ]
信頼度=発生回数/合計(カウンタ.())
予測= fo .分類(
ラベル=予測クラス信頼度=信頼度

リターン予測

予測= []

#Qdrantを使って最も近いデータポイントを見つける
tqdmへの埋め込み( test_embeddings ):
予測= generate_fiftyone_classification (埋め込み)
予測.append (予測)

test_view.set_values ​​( "ann_prediction" ,予測値)

最も一般的なラベルに属するサンプルのスコアを計算することで、信頼性を推定します。これにより、各ケースのラベルを予測する際の確実性に関する直感が得られ、FiftyOneではこれを利用して、紛らわしいサンプルを簡単に識別できます。

フィフティワン評価

さあ、結果を見てみましょう!まずは分類器のパフォーマンスを視覚化してみましょう。FiftyOneアプリを起動して、参照回答ラベル、予測結果、画像を簡単に確認できます。

セッション= fo.launch_app (test_view )

FiftyOneは、画像および動画データセットにおける回帰、分類、検出、ポリゴン、インスタンス、セマンティックセグメンテーションなど、モデル予測を評価するための様々な組み込みメソッドを提供しています。以下の2行のコードで、分類器の評価レポートを計算して出力できます。

 #ground_truthの値に基づいてANN予測を評価する
結果= test_view.evaluate_classifications (
「ann_prediction」gt_field = 「ground_truth」eval_key = 「eval_simple」


#カテゴリインジケーターを表示する
結果.print_report ( )

FiftyOne を評価した後、結果オブジェクトを使用してインタラクティブな混同行列 (https://voxel51.com/docs/fiftyone/user_guide/plots.html#confusion-matrices) を生成できます。これにより、セルをクリックしてアプリケーションを自動的に更新し、対応するサンプルを表示できます。

プロット=結果. plot_confusion_matrix ()
プロット.表示( )

もう少し深く掘り下げることもできます。FiftyOneの洗練されたクエリ言語を使えば、現実とは一致しないものの、非常に信頼性の高い予測をすべて簡単に見つけることができます。これらはデータセットの中で最も不可解なサンプルであることが多いですが、同時に、最も深い洞察を得られるものでもあります。

 51からViewFieldをFとしてインポート

#FiftyOne アプリを表示しますが、妥当な信頼度で行われた誤った予測のみが含まれます。
偽ビュー= (
テストビュー
.match ( F ( "eval_simple" ) == False )
.filter_labels ( "ann_prediction" , F ( "confidence" ) > 0.7 )

セッション.view = false_view

上の画像は、モデルの中で最も複雑なサンプルを示しています。ご覧のとおり、データセット内の他の画像と比較して非常に不規則な構造をしています。モデルのパフォーマンスを向上させるための次のステップとしては、FiftyOneを使用して、このようなより正確なサンプルを追加することが考えられます。これらのサンプルは、FiftyOneとCVAT、そしてLabelboxなどのツールとの統合によってアノテーションを付けることができます。さらに、より多くのベクトルでトレーニングしたり、例えばトリプレット損失アルゴリズムを用いた類似性学習を通じてモデルを微調整したりすることも可能です。しかし、現時点では、FiftyOneとQuadrantを用いたベクトル類似性分類のこの例は、既に非常にうまく機能しています。

とても簡単です。FiftyOneとQdrantを埋め込みバックエンドとして用いたANN分類モデルを作成したので、従来のk-NNのようにベクトル間の類似性を見つけることがタスクのボトルネックになることはなくなりました。

ぜひご自身でお試しください。

最後に、 GitHubコードリポジトリのノートブックファイルにはこの記事紹介したすべてのソースコードが含まれています。また、このプロセスの実用的なユースケースとして、BDD100K道路シーンデータセットにおける夜間と昼間の属性の事前アノテーションの実行も含まれています。

まとめると、FiftyOneとQdrantという2つのオープンソースライブラリを組み合わせることで、埋め込みデータに対して最近傍探索を効率的に実行し、画像や動画データセットでその結果を操作することができます。このプロセスの優れた点は、その柔軟性と再現性にあります。FiftyOneとQdrantに新しい分野の追加の参照回答ラベルを簡単に読み込み、既存の埋め込みデータを用いてこの事前アノテーションプロセスを繰り返すことができます。これにより、アノテーションコストを大幅に削減し、より高品質なデータセットをより迅速に生成できます。

翻訳者紹介

Zhu Xianzong 氏は、51CTO コミュニティ エディター、51CTO 専門ブロガー兼講師、維坊の大学のコンピューター教師、そしてフリー プログラミング コミュニティのベテランです。

原題: Nearest Neighbor Embeddings Search With Qdrant and FiftyOne 、著者: Eric Hofesmann