TadaoYamaokaの日記

山岡忠夫 Home で公開しているプログラムの開発ネタを中心に書いていきます。

WindowsでChainerをGPUを使って動かす

※最新の情報はこちらの日記を合わせて参照ください。

WindowsでChainerをGPUを使って動かすことができたので、手順をメモっておきます。

使用したソフトのバージョンは以下の通りです。

  • Windows 10 Home 64bit
  • Python 3.5.1(Anaconda 4.0.0 64bit)
  • CUDA 7.5
  • cuDNN v5
  • Chainer 1.8.2

使用したGPUは、Geforce GTX 760 2GBです。

Pythonのインストー

Pythonはライブラリ類をまとめてインストールしてくれるので、Anacondaを使ってインストールしました。
バージョンはPython 3.5の64bit版を使いました。
はじめ2.7で試しましたが、後の手順がうまくいきませんでした。

Visual Studio 2013 Communityのインストー

CUDAをインストールするには、先にVisual Studio 2013 Communityをインストールしておく必要があります。
Visual Studio 2015 Communityは対応していません。
Visual Studio 2015 Communityをすでにインストールしている場合は、一旦アンインストールしてVisual Studio 2013 Communityをインストールした後、Visual Studio 2015 Communityをインストールすれば共存できます。

インストール後、環境変数PATHの一番目に「C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin」を追加します。

Visual Studio 2015 Communityのインストー

Visual Studio 2015 Communityがないとchainerのインストールができないとコメントいただいたので追記しました。
※Visual C++ Build Toolsでも良いとコメントいただいたので追記しました。

ChainerのインストールにPython3.5がビルドされたバージョンのVisual Studioが必要になるため、Visual Studio 2015 Communityをインストールします。インストールオプションでVisual C++にチェックしてください。

Visual Studio 2015の代わりに、「Visual C++ Build Tools」をインストールしても良いようです。

CUDAのインストー

CUDAは7.5をNvidiaのサイトからダウンロードしてインストールします。

cuDNNのインストー

必須ではありませんが、cuDNN v5をNvidiaのサイトからダウンロードしてインストールします。
ダウンロードするには登録が必要です。
個人でも特に問題なく登録できました。

インストールは、zipファイルを解凍して、cudaディレクトリの中身を、「C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5」にコピーします。

Chainerのインストー

pipコマンドでChainerをインストールします。

pip install chainer

Chainerをインストール済みの場合は、GPUを有効にするには一旦アンインストールしてインストールし直す必要があります。
その際キャッシュを利用しないオプションが必要です。

pip uninstall chainer
pip install chainer --no-cache-dir

以上でインストール完了です。

MNISTサンプルの実行

MNISTサンプルをGPUで動かします。
ChainerのGithubリポジトリをダウンロードします。

git clone https://github.com/pfnet/chainer.git

※gitコマンドはGit for Windowsでインストールしてください。

以下の通り実行します。(C:\にダウンロードした場合)

cd C:\chainer\examples\mnist
python train_mnist.py -g 0

成功すれば以下のように出力されます。

C:\chainer\examples\mnist>python train_mnist.py -g 0
GPU: 0
# unit: 1000
# Minibatch-size: 100
# epoch: 20
Network type: simple

load MNIST dataset
Downloading train-images-idx3-ubyte.gz...
Done
Downloading train-labels-idx1-ubyte.gz...
Done
Downloading t10k-images-idx3-ubyte.gz...
Done
Downloading t10k-labels-idx1-ubyte.gz...
Done
Converting training data...
Done
Converting test data...
Done
Save output...
Done
Convert completed
epoch 1
graph generated
train mean loss=0.19046083599949876, accuracy=0.9429333364466826, throughput=16001.954380948753 images/sec
test  mean loss=0.11117558781523257, accuracy=0.9659000062942504
epoch 2
train mean loss=0.07396888414242615, accuracy=0.9766166763504346, throughput=22224.82413467105 images/sec
test  mean loss=0.07778721494600177, accuracy=0.9749000060558319
...(省略)
epoch 20
train mean loss=0.014614566394831552, accuracy=0.995966670314471, throughput=22451.748832707875 images/sec
test  mean loss=0.125516449243434, accuracy=0.9793000078201294
save the model
save the optimizer

imagenetサンプルの実行

train_imagenet.pyの編集

imagenetサンプルはWindowsではそのままでは動作しないため、編集が必要です。
C:\chainer\examples\imagenetのtrain_imagenet.pyの316行目に「if __name__ == '__main__':」を挿入して、以降の行をインデントします。

if __name__ == '__main__':
    # Invoke threads
    feeder = threading.Thread(target=feed_data)
    feeder.daemon = True
    feeder.start()
    logger = threading.Thread(target=log_result)
    logger.daemon = True
    logger.start()

    train_loop()
    feeder.join()
    logger.join()

    # Save final model
    serializers.save_npz(args.out, model)
    serializers.save_npz(args.outstate, optimizer)

画像データ取得

訓練に使用する画像データは含まれていないので、自分で取得する必要があります。
入手が容易だったので、Caltech 101を使用しました。

imagenetサンプルのディレクトリにダウンロードして解凍します。

wget http://www.vision.caltech.edu/Image_Datasets/Caltech101/101_ObjectCategories.tar.gz
tar xzf 101_ObjectCategories.tar.gz

wget、tarコマンドはMSYSをインストールしてください。

Caltech 101のデータは、imagenetサンプルに入力できる形式になっていないので、加工する必要があります。
shi3zさんのページスクリプトが公開されていたので利用させてもらいました。

GitHub - shi3z/chainer_imagenet_toolsから、make_train_data.pyとcrop.pyをダウンロードしてimagenetサンプルのディレクトリにコピーします。

Python2のスクリプトになっているので、make_train_data.pyの6行目を以下の通り編集します。
編集前

return commands.getoutput(cmd)

編集後

return subprocess.getoutput(cmd)


実行には、Open CVが必要になるので、Open CVをインストールします。

conda install -c https://conda.binstar.org/menpo opencv3

スクリプトを実行します。

python make_train_data.py 101_ObjectCategories

imagesディレクトリと、train.txt、test.txt、labels.txtができます。
続いて、画像サイズを変換します。imagesディレクトリを一旦images_rawにリネームして、imagesディレクトリを新規作成し、crop.pyで変換します。

python crop.py images_raw images

次に、train.txt、test.txtに書かれたパスがWindowsのパス形式になっていないので、テキストエディタなどで相対パスに編集します。
編集前

/c/chainer/examples/imagenet/images/image0000000.jpg 0

編集後

images/image0000000.jpg 0

これで訓練する準備が整いました。

訓練を実行

train_imagenet.pyを使用し、モデルの訓練を行います。

python train_imagenet.py -g 0 -j 1 train.txt test.txt

私の環境では、「-j 1」オプションをつけないと、out of memoryが発生しました。

Traceback (most recent call last):
  File "cupy\cuda\memory.pyx", line 352, in cupy.cuda.memory.SingleDeviceMemoryPool.malloc (cupy\cuda\memory.cpp:6707)
  File "cupy\cuda\memory.pyx", line 255, in cupy.cuda.memory._malloc (cupy\cuda\memory.cpp:5469)
  File "cupy\cuda\memory.pyx", line 256, in cupy.cuda.memory._malloc (cupy\cuda\memory.cpp:5384)
  File "cupy\cuda\memory.pyx", line 31, in cupy.cuda.memory.Memory.__init__ (cupy\cuda\memory.cpp:1415)
  File "cupy\cuda\runtime.pyx", line 180, in cupy.cuda.runtime.malloc (cupy\cuda\runtime.cpp:2975)
  File "cupy\cuda\runtime.pyx", line 110, in cupy.cuda.runtime.check_status (cupy\cuda\runtime.cpp:1821)
cupy.cuda.runtime.CUDARuntimeError: cudaErrorMemoryAllocation: out of memory

「-j」(--loaderjob)オプションは並列実行数のオプションのようなので、GPUで実行する場合は1でよいと思います。(5まで増やして実行できましたが、速度は変わりませんでした。)


デフォルトでは10回繰り返して訓練が行われます。動作確認が目的の場合は、「-E 1」とすると1回のみとなるので早く終わります。
実行時間は、私の環境では1epochで、1分16秒でした。
なお、「-g 0 -j 1」オプションを外してCPU(Core i7 6770K)で実行した場合は、26分かかりました。

訓練が完了するとエラー率などが表示されます。

C:\chainer\examples\imagenet>python train_imagenet.py -g 0 -j 1 train.txt test.txt
epoch 1
learning rate 0.01

generated graph
train 213 updates (6816 samples) time: 0:01:16.421986 (89.18899293645758 images/sec)epoch 2
learning rate 0.0097
train 429 updates (13728 samples) time: 0:02:32.111728 (90.24945112194965 images/sec)epoch 3
learning rate 0.009409
train 645 updates (20640 samples) time: 0:03:47.678436 (90.6541717438778 images/sec)epoch 4
learning rate 0.00912673
train 860 updates (27520 samples) time: 0:05:02.995888 (90.82631525278232 images/sec)epoch 5
learning rate 0.008852928099999999
train 1000 updates (32000 samples) time: 0:05:51.930302 (90.92709507675764 images/sec)
{"iteration": 1000, "loss": 3.492601506590843, "type": "train", "error": 0.7515000000000001}
train 1076 updates (34432 samples) time: 0:06:18.499071 (90.96984021570272 images/sec)epoch 6
learning rate 0.008587340256999998
train 1291 updates (41312 samples) time: 0:07:33.814653 (91.03275910661202 images/sec)epoch 7
train 1292 updates (41344 samples) time: 0:07:34.163553 (91.03328455913719 images/sec)learning rate 0.008329720049289998
train 1508 updates (48256 samples) time: 0:08:49.969721 (91.05425849623073 images/sec)epoch 8
learning rate 0.008079828447811297
train 1723 updates (55136 samples) time: 0:10:05.225559 (91.09991998924508 images/sec)epoch 9
learning rate 0.007837433594376959
train 1939 updates (62048 samples) time: 0:11:20.618070 (91.16419722270432 images/sec)epoch 10
learning rate 0.00760231058654565
train 2000 updates (64000 samples) time: 0:11:41.906984 (91.18017265906045 images/sec)
{"iteration": 2000, "loss": 2.3284159172177317, "type": "train", "error": 0.5715}
train 2157 updates (69024 samples) time: 0:12:36.977541 (91.18368276565492 images/sec)

訓練したモデルを使用

訓練したモデルを使用して、画像の識別を行うには、スクリプトが用意されていないので、自分で作成する必要があります。

ここのサイトなどが参考になると思います。


※Pycudaのインストール手順を記載していましたが、Chainer1.3以降はCuPyを使用しているので不要でした。