WindowsでGPU使ってTensorFlowを動かすメモ(TensorBoardも動かす)

ここ何年か数ヶ月おきに「なんか流行ってるし機械学習やらねば」と思って手をつけるけどすぐに頓挫するというのを繰り返すうち，続かない原因のひとつが実行時間だと気づきました．自分以外にも実際に動くものを触りながらじゃないと勉強のモチベーションを保てない人は実行時間で苦戦しているかと思います．

GPU使うと10倍くらい高速化するらしいので使いたいなと思っていたところで，[TensorFlow](https://www.tensorflow.org/)がWindowsに対応していたので，ひとまず普段使っているWindowsノートで実行してみました．

- [TensorFlow 0.12 が Windows をサポート](https://developers-jp.googleblog.com/2016/12/tensorflow-0-12-adds-support-for-windows.html)
- [CPU/GPU/AWSでのTensorflow実行速度比較](http://qiita.com/shouta-dev/items/5aa4a746b31b9be4838d)

# 準備

環境．

- Windows 10(64bit)
- Python 3.5 (今回は本家のやつを使いました．Anaconda等のお好きな物を)
- NVIDIAのGPU
- CUDA + cuDNN

## 使えるGPU

NVIDIAのグラフィックボードが必要です．

CUDAを使うのでNVIDIA縛りになってしまいます．OpenCLかなにかに対応してGPUベンダに依存しないようになってほしいですが，いまのところはみんなCUDA使っているようです．

今回はノートPCに載っていた GeForce GT 730M です．(ディーブラーニングとかするならもっとスペックの高いグラフィックボードが欲しいところ)

## CUDA と cuDNN のインストール

CUDA とcuDNN をインストールする必要があります．両方とも必須です．

- CUDA 8.0 https://developer.nvidia.com/cuda-downloads
- cuDNN 5.1 https://developer.nvidia.com/cudnn

CUDAのインストールは問題ないと思います．
インストールしたら，CUDAのbinディレクトリをPATH環境変数に追加します(もしかしたら自動的に追加されているかもしれません．うろ覚え)．

cuDNN はちょっと難易度が高くてユーザー登録をしないとダウンロードできません．
登録に時間がかかるという記事も見かけましたが，今回は登録して数分でメールが届きました．
組織名とか用途とかの入力が必須で面倒ですが，個人利用で遊びたいだけなので，全部1～2単語で雑に埋めました．

cuDNNはDLLとプログラムから利用するためのヘッダファイル等がzipで固められてるだけなので，TensorFlowで使うためにはPATHが通った場所にDLLを置けば良いです．CUDA8 のディレクトリに放り込んでしまうが良いと思います．


# TensorFlowのインストール

pip installするだけなので簡単です．GPUサポートの有無でパッケージが別れているので，名前に`-gpu`がついてる方をインストールします．(GPUサーポート有りの方はCUDAが無いと実行できないようなので，GPUを使わない場合はGPU無し版を入れて下さい)

```
% pip install tensorflow-gpu
```

詳しくは [Pip installation on Windows](https://www.tensorflow.org/get_started/os_setup#pip_installation_on_windows)を読んで下さい．このページに書かれていますが，環境によってはDLL load failedエラーが出て，`Visual C++ 2015 redistributable`のインストールが必要かもしれません．

```
% python
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os; import inspect; import tensorflow; print(os.path.dirname(inspect.getfile(tensorflow)))
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:128] successfully opened CUDA library cublas64_80.dll locally
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:128] successfully opened CUDA library cudnn64_5.dll locally
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:128] successfully opened CUDA library cufft64_80.dll locally
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:128] successfully opened CUDA library nvcuda.dll locally
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:128] successfully opened CUDA library curand64_80.dll locally
C:\Users\kosuke_kawahira\AppData\Local\Programs\Python\Python35\lib\site-packages\tensorflow
>>> exit()
%
```

無事に，CUDAとcuDNNが読み込めてるようです．


## CIFAR-10を実行してTensorBoardで見る

TensorFlowの一番便利な機能はTensorBoardでの可視化だと思うので，試しにCIFAR-10を実行してみます．
(MINSTはそのままではTensorBoard用の情報を出力しない)．

### cifar10_trainを実行

```
python -m tensorflow.models.image.cifar10.cifar10_train
```

### 実行しつつTensorBoard の起動

```
tensorboard --logdir=/tmp/cifar10_train
```

logdirでcheckpointファイルがある場所を指定します．Windowsでもすんなり動きました．

Windowsの場合はlogdirどこだろうと思ったのですが，Cドライブ直下にtmpディレクトリが作られてました．．．出力先を指定したい場合は，cifar10_trainの実行時に `--train_dir=～` を付けて下さい．オプションの指定方法はソース見るか `--help` 付きで起動することで確認できます．

起動するとポート番号(デフォルト6006)とURLが表示されるのでブラウザで開けば使えます．

![tfhistograms.png](https://qiita-image-store.s3.amazonaws.com/0/58515/911d9144-15ea-4b5d-ed42-338d1d15fc48.png)


### 評価

```
python -m tensorflow.models.image.cifar10.cifar10_eval --checkpoint_dir=/tmp/cifar10_train --run_once
```

10000step くらい実行すれば80%くらいの精度になると思います．

# CPUとGPU比較

使ったのがノートPCのGeForce GT 730Mなのであまり期待してなかったのですが，それでもCore i7 2.6GHzより3倍速くなりました(実際は3倍じゃ全然足りないのですが)

ちゃんと計測したわけではないので参考程度に．

GPU

```
2016-12-19 22:11:01.292278: step 0, loss = 4.68 (6.4 examples/sec; 19.947 sec/batch)
2016-12-19 22:11:06.451778: step 10, loss = 4.61 (428.8 examples/sec; 0.299 sec/batch)
2016-12-19 22:11:09.542778: step 20, loss = 4.49 (421.7 examples/sec; 0.303 sec/batch)
2016-12-19 22:11:12.775778: step 30, loss = 4.40 (392.6 examples/sec; 0.326 sec/batch)
2016-12-19 22:11:16.302278: step 40, loss = 4.38 (327.8 examples/sec; 0.391 sec/batch)
2016-12-19 22:11:19.863778: step 50, loss = 4.19 (356.5 examples/sec; 0.359 sec/batch)
2016-12-19 22:11:23.235278: step 60, loss = 4.25 (381.5 examples/sec; 0.336 sec/batch)
2016-12-19 22:11:26.768778: step 70, loss = 4.23 (357.5 examples/sec; 0.358 sec/batch)
...
```

CPU

```
2016-12-23 09:04:05.700890: step 0, loss = 4.69 (35.5 examples/sec; 3.605 sec/batch)
2016-12-23 09:04:18.250149: step 10, loss = 4.61 (120.8 examples/sec; 1.059 sec/batch)
2016-12-23 09:04:28.883700: step 20, loss = 4.44 (121.0 examples/sec; 1.058 sec/batch)
2016-12-23 09:04:39.597807: step 30, loss = 4.34 (119.8 examples/sec; 1.068 sec/batch)
2016-12-23 09:04:50.636108: step 40, loss = 4.28 (120.0 examples/sec; 1.067 sec/batch)
2016-12-23 09:05:01.245141: step 50, loss = 4.24 (120.8 examples/sec; 1.059 sec/batch)
2016-12-23 09:05:11.825731: step 60, loss = 4.34 (120.4 examples/sec; 1.063 sec/batch)
2016-12-23 09:05:22.397288: step 70, loss = 4.61 (121.5 examples/sec; 1.053 sec/batch)
...
```

# まとめ

Windowsで動かそうとすると色々上手く行かないことを予想して手順を残しながらやったけど，何も起きずにあっさり動いてしまった．よくできている．

- GPU使わないと現実的じゃない
- 高スペックのグラフィックボードが必要
- cuDNNをダウンロードするための登録が一番の難関