概要
以下で作成したPinecornに登録したベクトルに対してブラウザから検索リクエストを実行した。
サーバレスで使用したく、javascriptから手軽に検索できることを期待したが、クロスドメイン制約を回避することができず、結局Webサーバ(Apache)を使用して実行した。
環境
CentOS Stream 9(docker)
Apache 2.4
やったこと
テスト画面作成
ボタンを押したら、画像からベクトルを生成してqueryを投げるようjavascriptを作成した。
検索に使用した画像は、ベクトル登録時にも使用したファイル。ベクトル生成も、同じように実施した。つもり。
検索の条件は、nodeから実行したときと同じく類似した検索の上位5件を取得する。
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.0.0/dist/tf.min.js"></script>
<script>
async function check(){
const model = await tf.loadGraphModel("https://tfhub.dev/google/tfjs-model/imagenet/mobilenet_v2_100_96/feature_vector/2/default/1",{ fromTFHub: true });
const img = document.getElementById('myImage');
const tensor = tf.browser.fromPixels(img).resizeBilinear([96, 96]).expandDims(0).toFloat().div(tf.scalar(127)).sub(tf.scalar(1));
const features = await model.predict(tensor);
const float32array = features.dataSync();
const featureVector = Array.from(float32array.slice(0));
fetch('http://localhost/query', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Api-Key': '<apiキー>'
},
body: JSON.stringify({
vector: featureVector,
topK: 5,
includeMetadata: false,
includeValues: false,
namespace: 'imageindex'
})
}).then(response => response.json()
).then(data =>{
console.log(data);
}).catch(error => {
console.log(error);
});
}
</script>
</head>
<body>
<button type="button" onclick="check()">check</button>
<img id="myImage" src="1011516521.jpg"></img>
</body>
</html>
Apacheの設定
Pinecornには、Mongodb AtlasのBearer 認証のような、CORSエラーの対策はなさそうだった。なので、ローカル環境のWebサーバ(Apache)に、作成したHTMLファイルを配置(デフォルトの/var/www/html/index.html)し、プロキシの設定を行った。パスが/queryの場合、PinecornのURLにリクエストを送信するようにした。
転送先は、httpsのサイトのため、mod_sslをインストールしてhttp.confに以下を追記した。
<VirtualHost *:80>
ServerName any
SSLProxyEngine on
ProxyPass /query https://imageindex-c5a7176.svc.us-east-1-aws.pinecone.io/query
ProxyPassReverse /query https://imageindex-c5a7176.svc.us-east-1-aws.pinecone.io/query
</VirtualHost>
実行結果
検索結果は、前にnodeから検索したときの画像(ベクトル)と同じものが返ってきた。
が、順序が若干異なっており、また同じ画像でもscoreが1にはなってないのは気になるが、追及する力はない。