更新履歴
- 2016/04 初投稿。動作確認。
- 2017/04/02 タグを修正。動作確認はしていない。
はじめに
BVLC/caffeのwindowsブランチのソースコードを使って、caffeのインストールからcifar10の学習と分類まで試してみました。環境構築するにあたって、「なぜその作業が必要なのか」わからない点が多くあり、そのような点は適当にスルーしています(つまり、本当に正しく動いているかは保証できないYO)。
参考にしたページ
- 【Caffe】Windows7にCaffeをインストール (いつもの作業備忘録)
- CaffeでDeep Learning (2) (桜遡)
- [deep learning] caffeとCIFAR-10を使って画像判別テスト(詳細) (脳汁portal)
環境
- windows8(64bit)
- Visual Studio Express 2013 for Windows Desktop
- cygwin(シェルスクリプトを実行するため)
やったこと
- githubのコードをダウンロードしてビルド
- サンプルデータ(cifar10)を使って学習
- 学習結果を用いて画像のクラス分類
※やったことは、上記の「参考にしたページ」やソースのREADMEに書かれていることとほぼ同じです。
githubのコードをダウンロードしてビルド
ソースは以下です。
https://github.com/BVLC/caffe/tree/windows
ビルド前準備
ビルド自体は、caffe/windows/Caffe.slnを開いてVisual Studio上でビルドを実行するだけですが、そのままではエラーが出てしまったので、以下のような変更をしました。
CommonSettings.props.exampleの変更
caffe/windowsフォルダにあるCommonSettings.props.exampleを
CommonSettings.propsに改名(語尾の.exmapleを削除)します。
そして、中身の以下のタグを改変しました。
変更前
<CpuOnlyBuild>false</CpuOnlyBuild>
<UseCuDNN>true</UseCuDNN>
<PythonSupport>true</PythonSupport>
<PythonDir>C:\Miniconda2\</PythonDir>
変更後
<CpuOnlyBuild>true</CpuOnlyBuild>
<UseCuDNN>false</UseCuDNN>
<PythonSupport>true</PythonSupport>
<PythonDir>~略~\Anaconda2\</PythonDir>
↑は、GPUを使わない設定です。GPUを使いたい場合は、公式のREADMEを参考に改変してください。
また、公式のREADMEではpython環境としてMinicondaが挙げられていましたが、自分のPCに既にAnacondaが入っていたのでAnacondaを使うことにしました。Anacondaのパスの”~略~”の部分は環境依存なので自分の環境に合わせて修正してください。
ソースの改変
src/caffe/util/db_lmdb.cppの改変
以下のように書き換えないと実行時エラーが出てしまいました。そこで、Problems with MDB in the mnist example #1298 を参考に以下のように改変しました。
変更前
const size_t LMDB_MAP_SIZE = 104857600; // 100 MB
変更後
const size_t LMDB_MAP_SIZE = 1073741824;
変更した値の意味はよく分かりません。ちなみに、mnistのデータセットを試す場合、convert_mnist_data.cppに対して同様の改変をする必要がありました。
プロジェクトのプロパティの変更(GPUの場合)
今回はGPUで動作確認しないので必須ではありませんが、GPUで実行したい場合は、プロジェクトのプロパティを変更する必要がありそうです。デフォルトではwarningをエラーと見なす設定になっているので、その設定を変更する必要があります。これに関しては、以下のページが参考になりました。
【Caffe】Windows7にCaffeをインストール (いつもの作業備忘録)
以上によって、ビルドできるはずです。初めてビルドする時はNuGetが必要なライブラリをダウンロードしてくれるので、その分、時間がかかるかもしれません。
サンプルデータ(cifar10)を使って学習
学習用データの用意
データのダウンロード
caffe/data/cifar10フォルダをカレントディレクトリとして、get_cifar10.shを実行します。すると、data_batch_1.bin~data_batch_5.binとtest_batch.binがダウンロードされます。
caffeで読み込める形式にデータを変換
ダウンロードしたデータをcaffeで読み込める形式に変換する必要があるようです。そのために、caffeフォルダをカレントディレクトリとして、./examples/cifar10/create_cifar10.shを実行します。なお、スクリプトを少し改変しました(ビルドしたバイナリのパスを修正しました)。
# !/usr/bin/env sh
# This script converts the cifar data into leveldb format.
EXAMPLE=examples/cifar10
DATA=data/cifar10
DBTYPE=lmdb
echo "Creating $DBTYPE..."
rm -rf $EXAMPLE/cifar10_train_$DBTYPE $EXAMPLE/cifar10_test_$DBTYPE
./Build/x64/Release/convert_cifar_data.exe $DATA $EXAMPLE $DBTYPE
echo "Computing image mean..."
./Build/x64/Release/compute_image_mean.exe -backend=$DBTYPE \
$EXAMPLE/cifar10_train_$DBTYPE $EXAMPLE/mean.binaryproto
echo "Done."
↑によって、caffe/examples/cifar10にcifar10_test_lmdbとcifar10_train_lmdbというフォルダが生成されるはずです。
学習
以下のページを参考にしました。むしろ、やったこともこのページと同じです。
CaffeでDeep Learning (2) (桜遡)
まず、学習する前にcaffe/examples/cifar10フォルダにある、cifar10_quick_solver.prototxtとcifar10_quick_solver_lr1.prototxtの最後の行を書き換えてCPUで学習するように変更します。
変更前
solver_mode: GPU
変更後
solver_mode: CPU
そして、学習用スクリプト(examples/cifar10/train_quick.sh)を実行します。なお、スクリプトを少し改変しました(ビルドしたバイナリのパスを修正しました)。
# !/usr/bin/env sh
TOOLS=./Build/x64/Release
$TOOLS/caffe train \
--solver=examples/cifar10/cifar10_quick_solver.prototxt
# reduce learning rate by factor of 10 after 8 epochs
$TOOLS/caffe train \
--solver=examples/cifar10/cifar10_quick_solver_lr1.prototxt \
--snapshot=examples/cifar10/cifar10_quick_iter_4000.solverstate.h5
実行時のカレントディレクトリはcaffeフォルダです。
$ ./examples/cifar10/train_quick.sh
学習結果の確認
pythonで画像の分類をしてみます。
まず、python上でpycaffeを呼べるようにするために、caffe/Build/x64/Release/pycaffeにあるcaffeフォルダをcaffeフォルダごと"~略~/Anaconda2/Lib/site-packages"にコピーします(site-packagesフォルダの中にcaffeフォルダがある状態にします)。
あるいは、caffe/Build/x64/Release/pycaffe/caffeまでのパスを通す方法でもよいかもしれませんが、試していないのでよくわかりません。
次にクラス判定用プログラムを作成します。判定プログラムは以下のウェブページを参考にしました。(ほぼパクったに等しいので恐縮ですが、)平均画像を読み込む部分を少し変えました。
[deep learning] caffeとCIFAR-10を使って画像判別テスト(詳細) (脳汁portal)
import sys
import caffe
from caffe.proto import caffe_pb2
import numpy as np
net_path = 'cifar10_quick.prototxt'
model_path = 'cifar10_quick_iter_4000.caffemodel.h5'
mean_path = 'mean.binaryproto'
cifar_map = ["airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck"]
mean_blob = caffe_pb2.BlobProto()
mean_data = open( mean_path , 'rb' ).read()
mean_blob.ParseFromString(mean_data)
mean_arr = np.array( caffe.io.blobproto_to_array(mean_blob) )
classifier = caffe.Classifier(
net_path,
model_path,
mean=mean_arr[0],
image_dims=(32, 32),
raw_scale=255)
image = caffe.io.load_image(sys.argv[1])
predictions = classifier.predict([image],oversample=False)
answer = np.argmax(predictions)
print 'Answer: {0}({1:.0f}%)'.format(cifar_map[answer], predictions[0][answer]*100)
これで準備完了です。
caffe/examples/cifar10フォルダでcifar_test.pyを実行します。
第1引数に判定したい画像ファイル名を指定します。
cifar_test.py neko.jpg
入力画像neko.jpgは↓です。(K-DON! ANIMALSのネコ)
判定結果は、
dog(64%)と出ました…。まぁ、ドヤ顏がたくましいので犬っぽいかもしれません。