LIFULL Creators Blog

「株式会社LIFULL(ライフル)」の社員によるブログです。

HOME'Sデータセット画像をディープラーニング適用した物件画像分類

こんにちは、おうちハッカー@リッテルラボラトリーの石田です。

先日より弊社は、「HOME'S」の物件・画像データセットを研究者に提供開始しました。
情報学研究データリポジトリ(IDR)より申請頂けます。 こちらのデータセットを用いた研究を支援させていただくため、ディープラーニングによる画像分類器の学習と、テキストマイニングをお試しいただけるツールキットを提供いたします。

GitHub

本記事では主に、画像解析ツールで行うことができる、ディープラーニングを用いた部屋画像の分類を紹介します。

f:id:nextdeveloper:20151225152132p:plain

ディープラーニングで物件画像の分類

公開されたデータの中には、約8,300万枚の物件画像データが含まれています。それらの画像には、間取り、外観、玄関、居間、キッチン、トイレなどの画像種別が設定されています。 こちらの画像を教師データとして学習を行い、部屋画像を入力として与えると、どの種類の部屋なのか判定する分類器をディープラーニングのフレームワークのChainerを用いて作成しました。 ツールキットを用いることで、簡単に研究を始めることができると思います。以下にその手順を示します。

動作環境

  • Linux (推奨: Ubuntu 14.04 LTS 64bit または CentOS 7 64bit)
  • Chainer 1.5.1
  • (推奨) GPU利用環境 (CUDA 6.5, 7.0, 7.5)

HOME'Sデータセットの利用申請

HOME'Sデータセットは国立情報学研究所(NII)のご協力を得て研究資源として提供させていただいております。研究の用途に限定させていただいているため、情報学研究データリポジトリ(IDR)より申請をお願いいたします。1~2週間でデータセット提供用ページよりダウンロードしていただけます。

Chainerのインストール

Linux環境でのChainer v1.5のインストールをお願いします。画像枚数が大変多いため、GPUの利用を強くお勧めします。

Chainer自体のインストールは容易ですが、GPU演算のためのCUDAのインストールは、多くの方がよくつまづかれる部分です。公式ドキュメント通りにしていただければよいかと思いますが、よろしければこちらも参考にしてください。

Chainerのインストールが終わったら、MNISTのチュートリアルを実行することをお勧めします。

ツールキットの入手

HOME'Sデータセットから、Chainerに含まれるImageNet用の分類サンプルソースを用いて分類器を学習できるよう、ツールキットを用意しています。下記の通り、GitHubリポジトリからcloneまたはダウンロードしてください。場所はどこでもよいのですが、本文書では、データセットディレクトリ配下にcloneする前提で進めます。

(cloneする場合)

cd /path/to/dataset/directory
git clone https://github.com/Littel-Laboratory/homes-dataset-tools.git

(ダウンロードする場合)
https://github.com/Littel-Laboratory/homes-dataset-tools/archive/master.zip

データセットの展開

本データセットに含まれる物件画像データファイル (photo-rent-NN.tar.bz2) は、tar.bz2形式で圧縮されているので、展開作業が必要です。展開用のツールを用意していますのでご利用ください。

cd /path/to/dataset/directory
./homes-dataset-tools/imageKit/extract_photo.py ./
  • 物件画像の展開にはかなり長い時間がかかります
  • 全画像ファイルを展開する場合は、概ね1TBytes以上のディスク領域が必要となります。
  • 画像のファイル数がかなり多い (約8300万枚) ため、ディスクの容量とともにinode数をかなり消費します。inode数を多めに確保してフォーマットしてください。

上記を実行すると、データセットディレクトリ内のphotoディレクトリ (/path/to/dataset/directory/photo) に物件画像ファイルが展開されます。 物件画像ファイルは物件と対応づけられています。物件IDは16進数32桁の数字です。物件IDを元に画像ディレクトリが生成されます。画像は0001.jpgから順に番号が振られています。

例: 物件IDが0123456789abcdef0123456789abcdef の場合、この物件IDの画像は photo/01/23/456789abcdef0123456789abcdef に格納されています。

画像は、
0001.jpg 0004.jpg 0007.jpg 0010.jpg 0014.jpg 0017.jpg
0002.jpg 0005.jpg 0008.jpg 0011.jpg 0015.jpg 0018.jpg
0003.jpg 0006.jpg 0009.jpg 0013.jpg 0016.jpg
といった形です。

また、本ツールキットでは物件画像のメタデータ (画像種類タグ) を学習に用います。 photo_rent.tsv.bz2を展開してください。

cd /path/to/dataset/directory
bunzip2 photo_rent.tsv.bz2

訓練データの準備

ImageNetのソースを利用して学習させるために、データセットを加工します。

具体的には、

  • 画像のパスとタグ(種類)のリストの作成
  • 画像のリサイズ
  • 平均画像生成

を行います。

画像パスとタグのリスト作成

リストは、以下のようにスペース区切りで画像パスとタグを記述したものです。今回使用するタグは、画像に付けられた画像タイプです。 (例: 1=間取り, 11=居間, 12=キッチン)

00/00/03d67c168129876425c22a106dae/0003.jpg 1
00/00/180a3c6848b723749e1dc9cd4b12/0030.jpg 3
00/00/11fe05aa3585e929b34d887b2dbe/0007.jpg 10
00/00/081549d99cf1e3f5be593e560799/0004.jpg 11
00/00/081549d99cf1e3f5be593e560799/0005.jpg 12
00/00/081549d99cf1e3f5be593e560799/0006.jpg 15
00/00/11fe05aa3585e929b34d887b2dbe/0009.jpg 16
00/00/11fe05aa3585e929b34d887b2dbe/0010.jpg 17
00/00/11fe05aa3585e929b34d887b2dbe/0011.jpg 18
00/00/03d67c168129876425c22a106dae/0014.jpg 19

学習には、以下の2つの独立したリストファイルが必要となります。

  • train.txt: 訓練用データ
  • test.txt: テスト用データ

これを作成するには、ツールキットのmake_train_lists.pyを実行します

cd /path/to/dataset/directory/homes-dataset-tools/imageKit
./make_train_lists.py ../../photo_rent.tsv

すると、各タグの写真のパスがtrain.txt, test.txtにそれぞれ10,000枚、1,000枚づつ含まれたリストが生成されます。また同時にリサイズすべき画像リストresize.txtが生成されます。

make_train_lists.py のオプションで枚数を変更したり、写真をピックアップする際のオフセットやインターバルを変えて、異なる訓練セットを生成することもできます。この枚数で大きく学習時間が変わってきますので、もう少し早く結果を見たい方は、--trainphotos, --testphotosオプションで枚数を減らしてください。詳しくは、

./make_train_lists.py --help

でヘルプを参照してください。

画像のリサイズ

ImageNetのインプット画像サイズは256*256であるので、先ほどリストに追加された画像のリサイズを行います。

./resize_photo.py resize.txt ../../resized_photo/

平均画像生成

最後に、訓練データから平均画像を生成します。

./compute_mean.py train.txt --root ../../resized_photo/

こちらを実行すると、 mean.npy というファイルが生成されます。

これでImageNetでの学習に必要なデータ一式の準備は終了です。

ImageNetで学習

学習

ツールキットの train_imagenet.py で学習を始めます。

Chainer附属のImageNetと少しだけコードを変えてあります。変更点としては、保存する形式をCPUでも読み込めるようにしているだけです。

./train_imagenet.py train.txt test.txt -g 0 --batchsize 32 --val_batchsize 100 --epoch 300 --root ../../resized_photo/ | tee log

こちらを実行すると学習が始まります。*1

{"iteration":100,"loss":2.735,"type":"train","error": 0.846875}
{"iteration":200,"loss":2.167,"type":"train","error": 0.7709375}
{"iteration":300,"loss":1.963,"type":"train","error": 0.719062499}
{"iteration":400,"loss":1.898,"type":"train","error": 0.6765625}
{"iteration":500,"loss":1.880,"type":"train","error": 0.664374999}
{"iteration":600,"loss":1.814,"type":"train","error": 0.6396875}
{"iteration":700,"loss":1.770,"type":"train","error": 0.61687500}
{"iteration":800,"loss":1.781,"type":"train","error": 0.620937499}
{"iteration":900,"loss":1.754,"type":"train","error": 0.60375}
{"iteration":1000,"loss":1.740,"type":"train","error": 0.60187499}
・
・

枚数が多いので、AWSのGPUインスタンスを利用した場合でも、初期設定の13万枚の学習データで300epochの学習で丸2日かかります。 結果を早く試したい場合は、epochを減らすか、学習データ枚数を減らしてください。

300epoch学習させると、エラーレートはこのように下がっていきました。 なおグラフ作成には、Hi-kingさんが公開している補助スクリプトを利用させていただきました。

chainerで画像分類するための補助スクリプト · GitHub

訓練データでのエラーレート f:id:nextdeveloper:20151209111511p:plain

テストデータでのエラーレート f:id:nextdeveloper:20151209111916p:plain

訓練ではずっと下がり続けていますが、テストデータでは、50000イテレーション以降で16%前後で変わらない結果となりました。

学習済みモデルでテスト

学習が終わった後は、modelというファイルが生成されています。use_model.pyを用いて作成したモデルにてクラス分類を行います。

./use_model.py /path/to/bukken/photo  

ちゃんと居間として認識されています。

f:id:nextdeveloper:20151208145647j:plain:left:h170

タグ スコア
居間 99.972%
設備 0.028%
風呂 0.000%
トイレ 0.000%

100%キッチンの結果に。

f:id:nextdeveloper:20151208150805j:plain:left:h170

タグ スコア
キッチン 100.000%
地図 0.000%
設備 0.000%
バルコニー 0.000%

こちらは玄関の靴を入れる収納スペースなのですが、どちらとも言えない画像なので両方のスコアが高くなっています。

f:id:nextdeveloper:20151208145229j:plain:left:h170

タグ スコア
収納 41.396%
玄関 37.067%
設備 21.536%
キッチン 0.000%

考察

学習させたモデルの精度が85%程度であることの原因は、画像に対して適切なタグつけが行われていない、また重複するタグを持つ画像の扱いにあると考えられます。先の玄関の靴箱の写真の例では、訓練データ内の同様の写真の正解データは、玄関であったり収納であったり設備であったりします。この訓練データを使ったことにより、複数のスコアが高く出てしまうようです。 ですので、数字としての精度を高める場合には、例えば「玄関収納」など、写真のタグの分類をより細かく行い、複数のタグにまたがる状況を減らす方法が考えられます。

最後に

このように、簡単に分類器を作成できます。ツールキット自体は申請せずとも使うことができますが、ディープラーニング関連研究をお考えの方は、ぜひ申請してお試しください。

*1:見やすくするためにログを多少加工しています。