fc2ブログ
        

Caffe(Deep Learning)を使って画像の分類をしてみる

前回はGPUを使ってDeep LearningをするためにCaffeの導入をしました。
今回は学習済みネットワークを使って画像の分類(画像内に写っているものの推定)をやってみます。

□モデルやネットワーク、画像の準備
・モデル定義ファイルの準備
cd ~/caffe/examples/imagenet/
wget https://raw.githubusercontent.com/sguada/caffe-public/master/models/get_caffe_reference_imagenet_model.sh
chmod u+x get_caffe_reference_imagenet_model.sh
./get_caffe_reference_imagenet_model.sh

・学習済みネットワークの準備
ILSVRC2012のデータセットで学習済みのネットワークをお借りします
(ライセンス上これを使ったプログラムは商用には使用できません)
cd ~/caffe/data/ilsvrc12/
./get_ilsvrc_aux.sh

これでcaffe/models/bvlc_reference_caffenet/の下に
bvlc_reference_caffenet.caffemodelが
ダウンロードされるはずですが自分の場合されなかったので
http://dl.caffe.berkeleyvision.org/bvlc_reference_caffenet.caffemodel
から直接ダウンロードしました

・テスト画像の準備
cd ~/caffe/
wget http://www.vision.caltech.edu/Image_Datasets/Caltech101/101_ObjectCategories.tar.gz
tar xzvf 101_ObjectCategories.tar.gz

・ソースファイルの修正
~/caffe/python/caffe/io.pyにバグらしきものがあり
そのままだと実行できないらしいので254から255行目の

if ms != self.inputs[in_][1:]:
raise ValueError('Mean shape incompatible with input shape.')



if ms != self.inputs[in_][1:]:
print(self.inputs[in_])
in_shape = self.inputs[in_][1:]
m_min, m_max = mean.min(), mean.max()
normal_mean = (mean - m_min) / (m_max - m_min)
mean = resize_image(normal_mean.transpose((1,2,0)),in_shape[1:]).transpose((2,0,1)) * (m_max - m_min) + m_min
#raise ValueError('Mean shape incompatible with input shape.')

に書き換え

□画像の分類
さて、いよいよ画像の分類をさせてみます
まずcaffeに準備されている~/caffe/python/classify.pyを使います
cd ~/caffe/python/
python classify.py --raw_scale 255 ../101_ObjectCategories/airplanes/image_0001.jpg ../result.npy

エラーなく実行されるようなら大丈夫です
しかし、classify.pyは分類結果が表示されないので
Caffeで手軽に画像分類|Yahoo!デベロッパーネットワーク
http://techblog.yahoo.co.jp/programming/caffe-intro/
を参考に以下のコードを作りました
(python使ったことがないのでちょっと雑です。申し訳ないです。)
2015/07/14:2バイト文字で実行エラーがあったため# -- coding: utf-8 -- を追記

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

import numpy,os,sys,argparse,glob,time,caffe

#モデル定義ファイル
MODEL_FILE="../models/bvlc_reference_caffenet/deploy.prototxt"
#学習済みのネットワーク
PRETRAINED_MODEL_FILE="../models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel"
#分類カテゴリ
CATEGORY_FILE="../data/ilsvrc12/synset_words.txt"
#学習済み全画像の平均値
MEAN_FILE="caffe/imagenet/ilsvrc_2012_mean.npy"

def main(argv):

pycaffe_dir = os.path.dirname(__file__)
parser = argparse.ArgumentParser()

parser.add_argument(
"input_file",
help="Input image."
)
parser.add_argument(
"--images_dim",
default='256,256',
help="Canonical 'height,width' dimensions of input images."
)
parser.add_argument(
"--input_scale",
type=float,
help="Multiply input features by this scale to finish preprocessing."
)
parser.add_argument(
"--raw_scale",
type=float,
default=255.0,
help="Multiply raw input by this scale before preprocessing."
)
parser.add_argument(
"--channel_swap",
default='2,1,0',
help="Order to permute input channels. The default converts " +
"RGB -> BGR since BGR is the Caffe default by way of OpenCV."
)
args = parser.parse_args()

image_dims = [int(s) for s in args.images_dim.split(',')]

mean = numpy.load(MEAN_FILE)

channel_swap = None
if args.channel_swap:
channel_swap = [int(s) for s in args.channel_swap.split(',')]

# USE GPU
caffe.set_mode_gpu()

# Make classifier.
classifier = caffe.Classifier(MODEL_FILE, PRETRAINED_MODEL_FILE,
image_dims=image_dims, mean=mean,
input_scale=args.input_scale, raw_scale=args.raw_scale,
channel_swap=channel_swap)

# Classify image
scores = Classify(args.input_file,classifier)

prediction = zip(scores[0].tolist(), numpy.loadtxt(CATEGORY_FILE, str, delimiter="\t"))
prediction.sort(cmp=lambda x, y: cmp(x[0], y[0]), reverse=True)

#Show result
for rank, (score, name) in enumerate(prediction[:3], start=1):
print('#%d | %s | %4.1f%%' % (rank, name, score * 100))

def Classify(img_file,classifier):

# Load image file.
inputs = [caffe.io.load_image(os.path.expanduser(img_file))]

# Classify.
start = time.time()
predictions = classifier.predict(inputs)
print("Done in %.2f s." % (time.time() - start))
return predictions

if __name__ == '__main__':
main(sys.argv)

これをclassify_new.pyという名前で~/caffe/pythonに保存して実行
python classify_new.py --raw_scale 255 ../101_ObjectCategories/airplanes/image_0001.jpg

□実行結果
Screenshot from 2015-06-21 05:32:24

飛行機、軍用機と分類されました

実行時間はcpuモードでは2秒、今回のgpuモードでは0.4秒でした
gpuを使えば3~4倍近く早くなるようです

今回は学習済みのネットワークを使ったので、~/caffe/data/ilsvrc12/synset_words.txtに記載されるカテゴリのみの分類となります。
このsynset_words.txt、結構大事なカテゴリが抜けてたりするので、何かにそのまま使うというのはちょっと難しいです。
そこで、自分で分類を作りたいと思うのですが、それにはネットワークに学習させる必要があります。
次はそれに触れようとおもいます。


参考にさせて頂いた記事
・Caffeの使い方 | Caffe-RubyWiki
http://wiki.ruka-f.net/index.php?Caffe
・Caffeで手軽に画像分類
http://techblog.yahoo.co.jp/programming/caffe-intro/


にほんブログ村 その他趣味ブログ 趣味の工作へ にほんブログ村 その他趣味ブログ ビデオ撮影・編集へ

コメントの投稿

非公開コメント

承認待ちコメント

このコメントは管理者の承認待ちです
プロフィール

回路師

Author:回路師
趣味がロボットと動画製作です。
便利な機械やあほなマシンの動画を投稿しています.

最新記事
最新コメント
カテゴリ
電子工作キット








月別アーカイブ
書籍






Twitter
リンク
RSSリンクの表示
ソーシャル

検索フォーム