※2017/3/15追記 Windows版のリポジトリでビルド済みのバイナリが配布されています。自分でビルドしないでもそちらのバイナリを使用することをお勧めします。
ビルド済みのバイナリのインストール方法とサンプルの実行方法はこちらの日記を参照ください。
WindowsでCaffeをビルドすることができたので方法を示しておきます。
Windows版のCaffeは公式のページからGithubのレポジトリへのリンクがあるので、そのREADMEに従えばビルドできます。
ただし、GPUで実行しようとするとビルドの設定変更が必要な個所がありました。
はじめその設定がわからず以下のようなエラーが出てあきらめていましたが、某所からやり方法を教えてもらって解決しました。
check failed: error == cudasuccess (8 vs. 0) invalid device function
なお、以下の説明はコマンドもしくは、C++から利用することを想定しており、Pythonから利用する場合は、追加で対応が必要になります。詳細はREADMEを読んでください。
手順を順番を追って説明します。
ビルド/実行環境
- Windows 10 Home
- Visual Studio 2013 Community
- CUDA 7.5
- cuDNN v4 or v5
レポジトリのダウンロード
Git for Windowsをインストール済みの前提で説明します。
コマンドラインで任意のディレクトリに移動して、Windows版のブランチをダウンロードします。
git clone -b windows https://github.com/BVLC/caffe.git
CommonSettings.propsの編集
READMEに書かれているとおり、.\windows\CommonSettings.props.exampleをコピーして、.\windows\CommonSettings.propsを作成します。
CommonSettings.propsの
<CudaArchitecture>compute_35,sm_35;compute_52,sm_52</CudaArchitecture>
の部分を、実行する環境のGPUに合わせて編集します。
NvidaのページにGPUの「Compute Capability」が記載されているので、例えば、Geforce GTX 760の場合は「3.0」なので、
<CudaArchitecture>compute_30,sm_30;compute_35,sm_35;compute_52,sm_52</CudaArchitecture>
のように、「compute_30,sm_30;」を追記します。
CUDAとcuDNNのインストール
CUDA7.5をNvidiaのサイトからダウンロードしてインストールします。
cuDNN v4もしくはv5をNvidiaのサイトからダウンロードしてインストールします。
ダウンロードするには登録が必要です。個人でも特に問題なく登録できます。
インストールは、zipファイルを解凍して、cudaディレクトリの中身を、「C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5」にコピーします。
v5の場合は、後述の通りCaffeのソース修正が必要になります。
Visual Studio 2013プロジェクトの設定
windows\Caffe.slnをVisual Stuido 2013で開きます。
アクティブな構成を変更します。(例:Release/x64)
ソリューションにプロジェクトがいくつもありますが、それぞれのプロジェクトを右クリックしてプロパティを選び、構成のプロパティ→C/C++→詳細設計を選び、指定の警告を無効にするに「4819」と入力してOKを押します。
これは、CUDAのソースにASCII以外の文字が含まれいるため出力される警告を無視するために設定します。警告があるとコンパイルエラー扱いに設定されているので必須です。
cuDNN v5対応
cuDNN v5をインストールした場合は、Windows版のCaffeはcuDNN v5に対応していないので、ソース修正が必要になります。v4をインストールした場合は不要です。
Windows版のCaffeをダウンロードしたディレクトリとは別のディレクトリに、最新のCaffeをダウンロードします。
git clone https://github.com/BVLC/caffe.git
cuDNN関連のソースがビルドエラーになるので、ビルドエラーになったソースを最新版のソースに置き換えていけばよいです。cudnn.hppは、全体を置き換えるとWindows対応のコードも置き換えてしまうので、「#if !defined (_MSC_VER)」の個所は置き換えないようにしてください。
対象のソースは以下のものです。
- include\caffe\layers\cudnn_relu_layer.hpp
- include\caffe\layers\cudnn_sigmoid_layer.hpp
- include\caffe\layers\cudnn_tanh_layer.hpp
- include\caffe\util\cudnn.hpp
- src\caffe\layers\cudnn_conv_layer.cu
- src\caffe\layers\cudnn_relu_layer.cu
- src\caffe\layers\cudnn_relu_layer.cpp
- src\caffe\layers\cudnn_sigmoid_layer.cu
- src\caffe\layers\cudnn_sigmoid_layer.cpp
- src\caffe\layers\cudnn_tanh_layer.cu
- src\caffe\layers\cudnn_tanh_layer.cpp
CaffeのWindowsブランチをForkしてcuDNN v5向けに変更を加えたリポジトリを公開します。
github.com
ビルド
Caffeはいろいろなライブラリに依存していますが、NuGetから自動でダウンロードするようになっているので、そのままビルドできます。
メニューからビルド→ソリューションのビルドを選択して、ビルドを行います。
ビルドが完了するまで数分かかります。
ビルドが無事完了すると、Build\x64\Releaseに、exeとdllが作成されます。
MNISTサンプルで動作確認
MNISTサンプルで動作確認を行います。
実行方法は、基本的にexamples\mnist\readme.mdに従います。
MNISTサンプルは、examples\mnistにありますが、linux用のサンプルになっているので、Windowsで実行するにはいくつか修正が必要です。
まずスクリプトがbashのシェルスクリプトになっているので、MSYSをインストールします。
MNISTデータダウンロード
./data/mnist/get_mnist.sh
を実行し、MNISTのデータをダウンロードします。
※wgetとgunzipが使われています。不足しているコマンドがあれば、MinGWのパッケージマネージャでインストールしてください。
データ準備
examples\mnist\create_mnist.shを編集します。
- 「BUILD=build/examples/mnist」→「BUILD=Build/x64/Release」に修正
- 「convert_mnist_data.bin」→「convert_mnist_data.exe」に修正(2か所)
編集後、
./examples/mnist/create_mnist.sh
を実行します。
訓練実行
examples\mnist\train_lenet.shを編集します。
- 「./build/tools/caffe」→「./Build/x64/Release/caffe」に修正
編集後、
./examples/mnist/train_lenet.sh
を実行します。
成功すれば以下のように出力されます。
デフォルトでGPUで実行されます。
bash.exe"-3.1$ ./examples/mnist/train_lenet.sh I0619 22:48:09.056084 6428 caffe.cpp:186] Using GPUs 0 I0619 22:48:09.426971 6428 caffe.cpp:191] GPU 0: GeForce GTX 760 I0619 22:48:09.847589 6428 common.cpp:36] System entropy source not available, using fallback algorithm to generate seed instead. I0619 22:48:09.848960 6428 solver.cpp:48] Initializing solver from parameters: test_iter: 100 test_interval: 500 base_lr: 0.01 display: 100 max_iter: 10000 lr_policy: "inv" gamma: 0.0001 power: 0.75 momentum: 0.9 weight_decay: 0.0005 snapshot: 5000 snapshot_prefix: "examples/mnist/lenet" solver_mode: GPU device_id: 0 net: "examples/mnist/lenet_train_test.prototxt" I0619 22:48:09.850059 6428 solver.cpp:91] Creating training net from net file: examples/mnist/lenet_train_test.prototxt I0619 22:48:09.851061 6428 net.cpp:313] The NetState phase (0) differed from the phase (1) specified by a rule in layer mnist I0619 22:48:09.851563 6428 net.cpp:313] The NetState phase (0) differed from the phase (1) specified by a rule in layer accuracy I0619 22:48:09.852064 6428 net.cpp:49] Initializing net from parameters: (省略) I0619 22:48:52.758535 6428 sgd_solver.cpp:106] Iteration 9400, lr = 0.00608343 I0619 22:48:53.152582 6428 solver.cpp:337] Iteration 9500, Testing net (#0) I0619 22:48:53.351280 6428 solver.cpp:404] Test net output #0: accuracy = 0.988 I0619 22:48:53.351280 6428 solver.cpp:404] Test net output #1: loss = 0.0367942 (* 1 = 0.0367942 loss) I0619 22:48:53.353787 6428 solver.cpp:228] Iteration 9500, loss = 0.00429011 I0619 22:48:53.353787 6428 solver.cpp:244] Train net output #0: loss = 0.00429007 (* 1 = 0.00429007 loss) I0619 22:48:53.353787 6428 sgd_solver.cpp:106] Iteration 9500, lr = 0.00606002 I0619 22:48:53.757670 6428 solver.cpp:228] Iteration 9600, loss = 0.00273628 I0619 22:48:53.758157 6428 solver.cpp:244] Train net output #0: loss = 0.00273624 (* 1 = 0.00273624 loss) I0619 22:48:53.758863 6428 sgd_solver.cpp:106] Iteration 9600, lr = 0.00603682 I0619 22:48:54.157690 6428 solver.cpp:228] Iteration 9700, loss = 0.00342221 I0619 22:48:54.158474 6428 solver.cpp:244] Train net output #0: loss = 0.00342217 (* 1 = 0.00342217 loss) I0619 22:48:54.159108 6428 sgd_solver.cpp:106] Iteration 9700, lr = 0.00601382 I0619 22:48:54.559365 6428 solver.cpp:228] Iteration 9800, loss = 0.0139829 I0619 22:48:54.559365 6428 solver.cpp:244] Train net output #0: loss = 0.0139829 (* 1 = 0.0139829 loss) I0619 22:48:54.559867 6428 sgd_solver.cpp:106] Iteration 9800, lr = 0.00599102 I0619 22:48:54.960430 6428 solver.cpp:228] Iteration 9900, loss = 0.00561192 I0619 22:48:54.960681 6428 solver.cpp:244] Train net output #0: loss = 0.00561188 (* 1 = 0.00561188 loss) I0619 22:48:54.961184 6428 sgd_solver.cpp:106] Iteration 9900, lr = 0.00596843 I0619 22:48:55.361533 6428 solver.cpp:454] Snapshotting to binary proto file examples/mnist/lenet_iter_10000.caffemodel I0619 22:48:57.518798 6428 sgd_solver.cpp:273] Snapshotting solver state to binary proto file examples/mnist/lenet_iter_10000.solverstate I0619 22:48:57.525818 6428 solver.cpp:317] Iteration 10000, loss = 0.00311166 I0619 22:48:57.525818 6428 solver.cpp:337] Iteration 10000, Testing net (#0) I0619 22:48:57.729859 6428 solver.cpp:404] Test net output #0: accuracy = 0.9905 I0619 22:48:57.729859 6428 solver.cpp:404] Test net output #1: loss = 0.0292506 (* 1 = 0.0292506 loss) I0619 22:48:57.730361 6428 solver.cpp:322] Optimization Done.