ボクセルデータをつかって類似形状検索をやってみる

ある画像からその画像の特徴を使って、似ている画像をデータベースから検索してくる類似画像検索は、コンピューター・ビジョンの世界では一般的になってきておりAPIなども登場しています。

例えばWebページの検索エンジンであれば出現するキーワードの重要度や、ページ間のリンク強度などをもとに欲しい情報が上位にランクされるようになっていますが、類似画像検索として扱いたいのは、そういったキーワードやタグによらず画像そのものの特徴を比較して似ているものを探したいケースです。

本記事は画像の場合と同様に、3Dデータのボクセルデータに対して類似形状データの検索(Retrieval)を試してみます。
※ボクセルデータは、2次元ピクセルデータの3次元への拡張版で、(x, y, z)の格子に値を持つデータです。CADやCTデータなどがこの形式で表現されることがあります。

# 全体の流れ
大まかな流れとして、データを特徴量に変換 → 特徴量間の類似度を計測 → 類似度が高いデータを取り出す、という流れになります。

まず特徴量への変換ですが、例えば類似画像を検索する場合、画像処理による作り込み特徴量(SIFTやHoGなど)やニューラルネットワークで特徴を作ることが多いかと思います。今回は3Dオートエンコーダーを使って特徴量へ変換したいと思います。
その後、その特徴量の間の類似尺度としてコサイン類似度を使って、類似したデータを検索します。
その際、似た形状の商品を探したい場合など膨大なデータの中から探すのは手間ですので、検索エンジンと同様に上位に形状が似たものが上がってくるようにしたいです。

また前提として、データ間の類似の定義は予めしておらず(教師データはなし)、オートエンコーダーで作成した特徴量のみを頼りに検索します。

※参考コード(tensorflow実装)は[github](https://github.com/hiram64/3D-Similarity-Search)で公開しています。

# 対象データ
対象データとして、一般公開されているModelNetを使用します。
クラス数が40のものと10のものがある(フルデータの場合は別途コンタクトが必要)のですが、今回は10クラスのModelNet10を使用しています。
10クラスに含まれるカテゴリーは、bathtub、bed、chair、desk、dresser、monitor、night stand、sofa、table、toiletと家具関連になります。
ダウンロードすると、初期状態でtrainとtestにディレクトリーが分かれているのでそのまま使います。
このデータを32×32×32の立方体にリサイズしてネットワークへの入力データとします。

PRINCETON MODELNET
http://modelnet.cs.princeton.edu/

# 特徴量作成
今回は、3Dオートエンコーダーを使用します。
3Dオートエンコーダーは、2D版と同じくエンコーダーとデコーダーで構成されており、エンコーダーが畳み込んだ特徴量をデコーダーがもとのデータに復元するように学習させます。
ネットワーク全体のちょうど中間にあたるエンコーダーの出力をそのデータの特徴量と考え、この特徴が近い形状のデータを探します。

### ネットワークと学習
以下の畳み込み3Dオートエンコーダーを使用します。エンコーダー、デコーダー共に3層の畳み込み層をもつものにしました。入力データとデコーダーの最終層の出力のクロスエントロピーをロス関数として採用しました。

![ae.png](https://qiita-image-store.s3.amazonaws.com/0/285894/864250ee-e5d6-6fe4-5d3f-ee12c8b357c3.png)

10クラスの全学習データを使って、500エポック学習をさせたものを最終的なモデルとしました。
ModelNetは上に挙げた10クラス以上の分類は存在せず、全クラス一括で学習させているので、例えばあるベッドのデータをクエリー対象として、ベッドに近いイスがヒットするということもありえます。

# データ間類似度と検索
学習させたモデルのエンコーダーの出力をデータの特徴量として扱い、この特徴量の類似度が高いものを順に並べたものが類似度が高いデータとなります。
類似度を図る指標として、コサイン類似度($0$~$1$の間をとり値の大きいものほど類似)を使用します。類似度の計算は総当たりで行い、値の大きい上位$k$個をランキング形式で検索します。

# 実験結果

#### オートエンコーダーの復元
まず、学習終了後のオリジナルのデータ(上段)と、デコーダーで復元されたデータ(下段)です。
細部は異なっている部分がありますが、全体の形状はしっかり復元されていることがわかります。

![restore.png](https://qiita-image-store.s3.amazonaws.com/0/285894/d5f394a6-5e01-0126-0a63-c67830e1b06a.png)

#### 検索結果のサンプル
一番左が検索したいデータで、右へ順に類似度トップ4が並んでいます。
類似の評価は難しいですが、目で見た感じ比較的類似しているものが上位に出てきています。

**chair**
<img src="https://qiita-image-store.s3.amazonaws.com/0/285894/e050c084-29b8-bf3d-59ff-4c63ead6fa81.png" height=80% width=80%>

**dresser**
<img src="https://qiita-image-store.s3.amazonaws.com/0/285894/18b5e0b8-a75c-a2ee-4011-ce390cf71791.png" height=80% width=80%>

**toilet**
<img src="https://qiita-image-store.s3.amazonaws.com/0/285894/adff48b8-1baa-06b2-fe62-4aca8106c4ae.png" height=80% width=80%>
(トイレに似たイスが上がってきたりしています、、)

#### 特徴量の分布
最後に参考として、エンコーダーによるテストデータのエンコード結果をt-SNEで2次元に圧縮して表示してみます。
結果として、色別にはある程度わかれているのですが、きれいに分離できているとは言い難いです。まだ特徴量の抽出方法には改善の余地はありそうです。

<img src="https://qiita-image-store.s3.amazonaws.com/0/285894/2485bbe1-8664-eb71-7e03-421e9e4f7e32.png" width=60%>

# まとめ

* 3Dオートエンコーダーで作成した特徴量を使って類似形状データの検索を試してみた。感触的には近いデータが検索上位に引っかかった
* MODELNETのデータの性質上、類似画像検索にありがちな対象物体以外の背景等の特徴にひっぱられるということが起きないので、そういった意味では比較的単純かも
* 今回は検索時間は考慮していないので、検索対象が膨大になった場合には、探索方法を工夫する必要がある
* 特徴量の作り方は、他手法も視野に入れて工夫の余地あり