読者です 読者をやめる 読者になる 読者になる

kivantium活動日記

プログラムを使っていろいろやります

Caffeによる特徴抽出+AROWによる分類を試した

Deep Learningのすごいところとしてよく挙げられるのは「画像から自動で特徴抽出をしてくれる」ことです。従来の手法であればタスクに合わせた画像の特徴をうまく抜き出すような特徴量を作る必要がありましたが、Deep Learningではネットワークが勝手に「特徴」を抽出してくれます。ネットワークが抽出した特徴量を使って別の分類器を学習させて分類することもできます。Deep Learningが自動で作った特徴量を使うことで人間が作ったSIFTなどの特徴量よりも高い精度で分類が可能になることもあるようです。

そこで今回はDeep LearningライブラリのCaffeを使って特徴抽出を行った後、AROWというアルゴリズムを使って分類を行ってみたいと思います。

Caffeによる特徴抽出

Caffe | Feature extraction with Caffe C++ code.Caffeで手軽に画像分類を参考にしました。

準備

Caffeのインストールは済んでいるとします。最初に手元にあったバージョンでは存在しない関数を使っていたので環境によっては更新の必要があるかもしれません。

まずcaffeディレクトリ内で

scripts/download_model_binary.py models/bvlc_reference_caffenet

を実行して事前学習済みのモデルをダウンロードします。

次のコードを実行します。

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import numpy as np
import sys
import os
import caffe

MEAN_FILE = 'python/caffe/imagenet/ilsvrc_2012_mean.npy'
MODEL_FILE = 'models/bvlc_reference_caffenet/deploy.prototxt'
PRETRAINED = 'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel'
LAYER = 'fc7'
INDEX = 4

if not os.path.isfile('models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel'):
    print("pre-trained CaffeNet model not found")
    sys.exit()
if len(sys.argv)<=1:
    print 'argument number is wrong'
    sys.exit()
net = caffe.Classifier(MODEL_FILE, PRETRAINED)
net.set_phase_test()
net.set_mode_cpu()
net.set_mean('data', np.load(MEAN_FILE))
net.set_raw_scale('data', 255)
net.set_channel_swap('data', (2,1,0))

for index in range(1, len(sys.argv)):
    image = caffe.io.load_image(sys.argv[index])
    net.predict([image])
    #モデルの形式を表示する
    #for k, v in net.blobs.items():
    #    print (k, v.data.shape) 
    feat = net.blobs[LAYER].data[INDEX].flatten().tolist()
    print -1, 
    for i in range(len(feat)):
        if feat[i]!=0:
            print str(i)+':'+str(feat[i]),
    print

このコードは引数に与えた画像ファイルに対してLIBSVMフォーマットで4096次元の特徴ベクトルを出力します。コードをfeature_extraction.pyで保存するとして、

python feature_extraction.py image*.jpg > input.txt

のように使います。
caffeのルートディレクトリ内に置くこと前提のコードなので場所が違う場合は適宜変更してください。

AROWによる分類

kbkz.connpass.com
で発表されていた
@olanleedさんによる機械学習ライブラリMochiMochiを使います。
言語はみんな大好きC++です!!(この記事はこのライブラリが使いたくて書いたようなもの)

olanleed.hatenablog.com

Eigenのインストール

MochiMochiは線形代数ライブラリのEigenに依存しているのでインストールします。
Eigen公式サイトからダウンロードして、Eigenフォルダを/usr/includeにコピーすればインストール完了です。

AROWによる分類

AROWというアルゴリズムが良さそうなので使ってみました。
AROWはオンライン線形分類器の一種です。(論文

作者の@olanleedさんのアイコンに敬意を表して、データセットには「一週間フレンズ。」の顔画像を使いました。
f:id:kivantium:20150628225251p:plain:w400
AROWは2値分類器なので画像が藤宮さんかどうかを判定してみようと思います。
arowのexampleを使いました。

makeして

./arow --dim 4096 --train train.txt --test test.txt --r 0.8

のように使います。(train.txt: 訓練データの入ったファイル、test.txt: テストデータの入ったファイル)

この手法を用いることで、用意したデータセットについては正しく分類することができました。


以上、Caffeで抽出した特徴を使ったAROWによる分類の実験でした。