Pro Yearly is on sale from $80 to $50! »

論文紹介: バイナリ最近傍探索

A82e268e52c06ad69b83f1a251c682d4?s=47 Keisuke OGAKI
December 06, 2015

論文紹介: バイナリ最近傍探索

Fast Exact Search in Hamming Space with Multi-Index Hashing

Web Scale Photo Hash Clustering on A Single Machine

の二本の論文の紹介です

A82e268e52c06ad69b83f1a251c682d4?s=128

Keisuke OGAKI

December 06, 2015
Tweet

Transcript

  1. バイナリ最近傍探索 Keisuke OGAKI

  2. なぜ最近傍探索 検索! 特に画像のような連続値の場合に、多次元の最近傍探索を行う 検索エンジンとして使うからには、とにかく速度が欲しい

  3. 高速最近傍探 索 FAST EXACT SEARCH IN HAMMING SPACE WITH MULTI-INDEX

    HASHING
  4. Fast Exact Search in Hamming Space with Multi-Index Hashing • 

    ジャーナルTPAMIと国際会議CVPR2012 •  github: https://github.com/norouzi/mih •  arxiv: http://arxiv.org/pdf/1307.2982.pdf
  5. キーアイデア 鳩の巣定理の応用 •  D次元の離散値ベクトルx1, x2について、 x1とx2の距離がkD未満ならば、少なくとも1次元は距離k未満であ る •  特に、距離がD未満ならば、少なくとも1次元は距離0である 1.1

    121.9 13.7 74.74 92.3 … 1 0 0 1 1 1 0 0 … 1 1 2 0 … バイナリエンコード(前回参照) サブベクトルへのマージ 元データ バイナリデータ 探索用 離散値ベクトル
  6. R近傍探索 問題: クエリベクトルQから距離R以内に有る点を列挙しなさい 1.  全データをD次元離散値サブベクトルに分割して、サブベクトル毎に ハッシュマップを作る •  かなり小さいハッシュマップにして、メモリにのせることが重要。探 索を減らすための機能なので衝突はOK 2. 

    クエリベクトルをD次元離散値サブベクトルに分割して、サブベクトル 毎に、距離R/D以内の候補点を出す 3.  全候補点について、元空間で距離Rに収まっているか確かめる
  7. R近傍探索: 実装 def r_nearest(R): for sub_r in range(R/D): for l

    in range(0, N, N/D): sub_query = Q[l:l+N/D] for subvector in sub_queryからsub_r以内の全subvector: for vector in hash[target_subvectors]: if distance(vector, query) <= r: yield vector 2, 3) 探索 hash = [{}] #D個のハッシュ for vector in data: for l in range(0, N, N/D): hash[l/(N/D)][vector[l:l+N/D]].append(vector) 1) 全データをハッシュに
  8. R近傍探索: 実装 for l in range(0, N, N/D): sub_query =

    Q[l:l+N/D] for vector in hash[sub_query]: #必ず1次元はsub_queryと一致する if distance(vector, query) < D: yield vector 例: 距離D未満の点の探索 キーアイデアより、サブベクトルのうち1次元は必ずQと一致する
  9. 最近傍探索 for r in range(0, inf, N/D): candidates = r_nearest(r)

    if len(candidates) >= 0: #R以内の点があれば nearest_vector = candidatesの中でdistance(vector, query)が最も小 さくなるvector return nearest_vector 1.  全データを離散値ベクトルにする 前ページと同一 2. 探索 前ページのr_nearestを利用して、Rを徐々に大きくするのみ
  10. 問題: シビアなサブベクトル設計 バイナリ何bitをまとめて探索用離散値ベクトルにするか(D)の設計が シビア。最近傍探索のコードの中で、発見までの総candidatesを減ら したい。 Dを千咲すると、サブベクトルの次元が減るため、最小距離が等しい、 candidatesの数が減るが、その代わりrの増える量が大きくなる。Dを 大きくすると、rは少しずつ増やすことができるが、次元が増えるため、 同時に見つかるcandidatesも増える 論文では、N/D

    = 元のbit数/log2(サンプル数)という式が実験的に提 案されているが、サンプルの分布の偏りによっても異なってくると思わ れる。 for r in range(0, inf, N/D): candidates = r_nearest(r) …
  11. 高速KMEANS WEB SCALE PHOTO HASH CLUSTERING ON A SINGLE MACHINE

  12. 最近の高速KMEANSの盛り上がり •  2010, WWW: “Web-Scale K-Means Clustering” •  Google • 

    Mini batch法。Sklearnにも実装済み •  2015, CVPR: “Web Scale Photo Hash Clustering on A Single Machine” •  Facebook AIラボ •  バイナリ特徴を使う •  2015, ICCV: “Web-scale image clustering revisited” •  Yahoo! Labs •  コードブックを用いた、より効率のよいハッシング(IQ)
  13. BKMEANS 1.  Eステップ •  全てのサンプルについて最も近いセントロイドを割り当てる •  全章で説明した最近傍探索が利用できる 2.  Mステップ • 

    セントロイドを、割り当てられたデータの平均に更新する •  2値であること、平均は各次元独立に計算できることに留意する と •  割り当てられたサンプルの各次元毎の和の正負で決定できる for centroid in centroids: summed = sum(そのcentroidに割り当てられたサンプル) #ただし、各サンプルの各次元は-1または1の2値を取るものとする for d in range(D): centroid[d] = 1 if summed[d] > 0 else -1
  14. 実験 •  データセットはILSVRC2012の1M(1000クラス)、これを1000クラス にクラスタリングする •  評価は2軸 •  1イテレーションあたりの実行時間 •  5イテレーション後のpurityの平均

    •  purity: クラスタ中で最も多いラベルの割合。 •  元データが1000クラスでk=1000なので、最大でpurityが100% になる 実行時間 K-means 640.9 BK-means 85.4