2023年7月12日水曜日

画像から生成したベクトル埋め込みを使って画像とテキストを検索する

以前の記事でrinna社のjapanese-cloob-vit-b-16を使ってベクトル埋め込みを生成するサービスを作成しました。このサービスによって、画像とテキストのベクトル埋め込みを生成することができます。

せっかくなので、選択した画像を元に、画像とテキストを検索するアプリケーションを作成してみました。以前にエクスポートしたアプリケーションにページとして追加しています。
https://github.com/ujnak/apexapps/blob/master/exports/multimodal-search.zip

以下のように動作します。

動物(ホッキョクグマとタヌキ)の写真を選択し、そのベクトル埋め込みを生成してPineconeで検索しています。オブジェクト・ストレージに保存している画像とオラクル・データベースの表に保存しているテキストからベクトル埋め込みを生成し、その両方をPineconeのインデックスに保存しています。


以下よりアプリケーションの実装について説明します。


検索対象のテキストの準備



検索対象となるテキストを表VEC_TEXTSに保存します。以下のDDLを実行し、表を作成します。

VEC_TEXTSをソースとした対話グリッドを作成し、検索対象となる(つまり、ベクトル埋め込みを生成しPineconeに保存する対象となる)テキストの入力を行います。


ベクトル埋め込みを生成しPineconeのインデックスにUpsertするボタンを作成します。

ボタン名UPSERT_VECTORSラベルUpsert Vectors動作アクションページの送信とします。


ボタンUPSERT_VECTORSを押下したときに実行されるプロセスをUpsert Vectorsとして作成します。

ソースPL/SQLコードに以下を記述します。



Pineconeのインデックスから、テキストより生成したベクトルを削除するボタンを作成します。

ボタン名DELETE_VECTORSラベルDelete Vectors動作アクションページの送信とします。


ボタンDELETE_VECTORSを押下したときに実行されるプロセスをDelete Vectorsとして作成します。

ソースPL/SQLコードに以下を記述します。



以上で検索対象となるテキストの入力、ベクトル埋め込みの生成とインデックスへの更新、インデックスからの削除ができるようになりました。


画像を指定した検索



検索に使用する画像を選択するページ・アイテムはP2_IMAGEです。

識別タイプファイル参照...を指定します。ラベルImage Fileとしています。設定記憶域タイプとしてTable APEX_APPLICATION_TEMP_FILESを選択します。ファイルをパージするタイミングは、End of SessionおよびEnd of Requestのどちらを選択しても動作に違いはありません。


ページ・アイテムP2_TOP_Kにて、検索結果の数を指定します。


ページ・アイテムP2_TYPE選択リストでは、無指定imagetextのどれかを選択します。Pineconeのインデックスの検索条件のmetadataに含めることで、検索対象を画像とテキストの両方(無指定)、画像のみ(image)、テキストのみ(text)に限定します。


ページ・アイテムP2_PICTUREに、検索に使った画像を表示します。

設定基準Image URL stored in Page Item Valueを選択します。ページ・アイテムの値は、ファイルをアップロードしたときに実行されるプロセス内で設定します。


検索はボタンFINDをクリックして実行します。

ボタン名FINDラベルFind動作アクションページの送信です。


ボタンFINDを押下したときに実行されるプロセスをFind Images and Textsとして作成します。

ソースPL/SQLコードに以下を記述します。



検索結果を一覧するリージョンを作成します。

画像を一覧するリージョンとしてResult Imagesを作成します。タイプ対話モード・レポートソースSQL問合わせとして以下を記述します。
select c001, n001 from apex_collections where collection_name = 'IMAGES_AND_TEXTS' and c002 = 'image'


C001に画像が表示されるよう、列の書式HTML式として以下を記述します。

<img src="&G_PREAUTH_URL.#C001#" width="200"></img>


テキストを一覧するリージョンとしてResult Textsを作成します。タイプ対話モード・レポートソースSQL問合わせとして以下を記述します。
select t.id, t.text, c.n001 from vec_texts t join (
    select c001, n001 from apex_collections where collection_name = 'IMAGES_AND_TEXTS' and c002 = 'text'
) c
on t.id = c.c001

アプリケーションの実装の説明は以上になります。

Oracle APEXのアプリケーション作成の参考になれば幸いです。