タイトルにある通りです.
初めはCaffeでやろうとするも,
Ubuntu16.04のprotobuf周りのせいで雲行きが怪しくなったので,
今回はChainerにCaffeモデルを読み込ませてテストしてみようって感じです.
① Chainerをインストールする
今回はネットワークを云々したい訳ではないので,
CPUでの利用を考えています.
したがって,Chainerのインストールはコマンド一発です!
|
sudo pip3 install chainer |
GPUで使いたい場合は,
こちらや
こちらを参考にしてください.
② Caffeモデルの準備
次に,Chainerに読み込ませるCaffeモデルの準備をします.
今回はGoogleNetの
bvlc_googlenetを利用しています.
1000個のカテゴリーに分類することができます.
こちらにある,caffemodel_urlのリンクからダウンロードしてください.
解凍したら,synset_words.txtを加工してラベルファイルを生成します.
ラベルファイル生成は,以下のコマンドを実行.
|
wget http://dl.caffe.berkeleyvision.org/caffe_ilsvrc12.tar.gz tar -xf caffe_ilsvrc12.tar.gz sed -e 's/^[^ ]* //g' synset_words.txt > labels.txt |
これで,labels.txtにラベルが保存されます.
“crane”という行が2つあってまぎらわしいので,
135行目を”crane(bird)”に,
518行目を”crane(machine)”に変更しておくと良いとのことです.
③ テスト画像をChainerへの入力形式に変更
以下のプログラムでテスト画像をChainerの入力形式に変換します.
Chainerの入力形式は[画像インデックス,BGR, Y座標, X座標]なので,
テスト画像をその形式に変換しています.
画像サイズは定義したサイズに変換しますが,
画像中のオブジェクトが歪まないように変形しています.
画像インデックスはテスト画像の枚数分指定しています.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
# テスト画像の準備 import numpy as np from scipy import misc # 入力画像サイズの定義 target_shape = (224, 224) # 画像を読み込み、RGB形式に変換する image = misc.imread('sample.png') # 画像のリサイズとクリップ target_h, target_w = target_shape h, w, _ = image.shape if w > h: shape = (target_h, target_w * w // h) else: shape = (target_h * h // w, target_w) y_margin = (shape[0] - target_h) // 2 x_margin = (shape[1] - target_w) // 2 image = misc.imresize(image, shape) image = image[y_margin:y_margin + target_h, x_margin:x_margin + target_w] pixels = image.astype(np.float32) # pixelsは3次元でそれぞれの軸は[Y座標, X座標, RGB]を表す # 入力データは4次元で[画像インデックス, BGR, Y座標, X座標]なので、配列の変換を行う # RGBからBGRに変換する pixels = pixels[:,:,::-1] # 軸を入れ替える pixels = pixels.transpose(2,0,1) # 平均画像を引く mean_image = np.ndarray((3, 224, 224), dtype=np.float32) mean_image[0] = 103.939 mean_image[1] = 116.779 mean_image[2] = 123.68 pixels -= mean_image # 4次元にする pixels = pixels.reshape((1,) + pixels.shape) # 画像インデックスはテストの画像数分用意する |
④ Caffeモデルを読み込む
以下のプログラムで,Caffeモデルを読み込みます.
caffemodelのパスは各自の環境に合わせて定義してください.
|
# chainerにgooglenetのモデルをインポートする import chainer import chainer.functions as F from chainer.functions import caffe # caffemodelを読み込む func = caffe.CaffeFunction('./bvlc_googlenet.caffemodel') # レイヤー'loss3/classifier'の出力を得て、softmaxを適用する x = chainer.Variable(pixels, volatile=True) y, = func(inputs={'data': x}, outputs=['loss3/classifier'], disable=['loss1/ave_pool', 'loss2/ave_pool'], train=False) prediction = F.softmax(y) |
⑤ 予測させる
最後に以下で予測させます.
|
# テストしてみる #ラベルを読み込む categories = np.loadtxt('./labels.txt', str, delimiter="\n") # スコアとラベルを紐づけスコアの高い順にソートする result = zip(prediction.data.reshape((prediction.data.size,)), categories) result = sorted(result, reverse=True) # 上位10個の結果を表示する for i, (score, label) in enumerate(result[:10]): print('{:>3d} {:>6.2f}% {}'.format(i + 1, score * 100, label)) |
試しに以下のキジムナーの画像をテストしてみた結果です.
|
1 22.69% b'clog, geta, patten, sabot' 2 16.32% b'cowboy boot' 3 6.24% b'pot, flowerpot' 4 4.69% b'wig' 5 3.22% b'plastic bag' 6 3.02% b'mousetrap' 7 2.44% b'ocarina, sweet potato' 8 1.65% b'toilet seat' 9 1.64% b'mask' 10 1.47% b'stinkhorn, carrion fungus' |