Windows10でTensorflow(GPU版)をインストールする

　インターネット上の情報通りに作業を進めれば変なところでつまづくことはないと思います。
　重要なのは各導入ソフトのバージョンを合わせるところぐらいです。とにかく最新版を入れておけばいいや、という考えだと、意味のない作業に時間を取られることがあるので注意しましょう。


# CUDAドライバのインストール

## Visual Studio 2015（VS2013でも可）のインストール

　CUDAを正しくインストールするためには**VisualC++**が必要になります。実験はしていませんが、VisualC++無しでインストールした場合、形式上インストールは成功するようですが、うまく動かないそうです。
　Visual Studio 2015は[以前の Visual Studio ソフトウェアのダウンロード | Visual Studio](https://www.visualstudio.com/ja/vs/older-downloads/)からダウンロードできます（要MSDNサブスクリプションの登録）。デフォルトインストールでは、VisualC++はインストールされないため、下記のようにVisualC++を指定してインストールする必要があります。

![VC_install.png](https://qiita-image-store.s3.amazonaws.com/0/117636/07df1875-0378-0a72-17fa-5378b1b2e009.png)


　ちなみに、Visual Studio 2017をインストールした場合、MSDNサブスクリプションの登録は不要ですが、2017年6月現在、CUDAインストール時に未サポートのVisual Studio扱いにされました。


## CUDA Toolkitのインストール

　CUDA Toolkitは[CUDA Toolkit Download](https://developer.nvidia.com/cuda-downloads)からダウンロードできます。2017年6月現在では、v8.0.xxになると思います。事前にVisualC++をインストールしてれば、インストールオプションは全部デフォルトのままで良いみたいですので、戸惑うところはないと思います。


## cuDNNのインストール

　cuDNNは、インストールファイルをダウンロードするためにユーザ登録が必要です。
　[NVIDIA cuDNN | NVIDIA Developer](https://developer.nvidia.com/cudnn)の「Download」をクリックするとログイン画面が表示されます。「Just Now」からアカウント登録ができます。
　アカウントを登録し、ログインが終わったら、**cuDNN5.1**（6.0ではない）をダウンロードします。間違って6.0をダウンロードしてきた場合、Tensorflowのインストールまではいけますが、importのところでエラーになります。

　cuDNNにはインストーラはなく、zipファイルを展開し

- 「cuDNNを展開したフォルダ\cuda\bin」にパスを通す
- CUDA Toolkitインストールフォルダ（何も考えずにインストールすると「C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0」のはず）にcuda\\{bin,include,lib}を上書きコピーする

のいずれかを実施することでインストールします。ちなみに、私は後者の上書きコピーでインストールしました。


---
　ここまででWindows10のCUDAドライバのインストールは完了です。あとはPython3.5環境で

```cmd:
(python35)> pip install --upgrade tensorflow-gpu
```

の要領でtensorflow-gpuをインストールします。


# 動作確認

　下記のコードを実行します。対話形式だと、どこでエラーになったかがわかりやすいです。

- 「import tensorflow as tf」でロードモジュール系のエラーが出ない
- 「sess = tf.Session()」実行後、GPUに関する情報が出力される

あたりをチェックします。

```py3:example.py
import tensorflow as tf
message = tf.constant('test message')
sess = tf.Session()
print(sess.run(message))
```


　下記は私のPCで実行したときのログ。

```cmd:
C:\>python
Python 3.5.3 |Continuum Analytics, Inc.| (default, May 15 2017, 10:43:23) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow as tf
>>> message = tf.constant('test message')
>>> sess = tf.Session()
2017-06-25 14:46:26.413269: W c:\tf_jenkins\home\workspace\release-win\m\windows-gpu\py\35\tensorflow\core\platform\cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE instructions, but these are available on your machine and could speed up CPU computations.
2017-06-25 14:46:26.413729: W c:\tf_jenkins\home\workspace\release-win\m\windows-gpu\py\35\tensorflow\core\platform\cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE2 instructions, but these are available on your machine and could speed up CPU computations.
2017-06-25 14:46:26.414112: W c:\tf_jenkins\home\workspace\release-win\m\windows-gpu\py\35\tensorflow\core\platform\cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE3 instructions, but these are available on your machine and could speed up CPU computations.
2017-06-25 14:46:26.414440: W c:\tf_jenkins\home\workspace\release-win\m\windows-gpu\py\35\tensorflow\core\platform\cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE4.1 instructions, but these are available on your machine and could speed up CPU computations.
2017-06-25 14:46:26.414755: W c:\tf_jenkins\home\workspace\release-win\m\windows-gpu\py\35\tensorflow\core\platform\cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE4.2 instructions, but these are available on your machine and could speed up CPU computations.
2017-06-25 14:46:26.415083: W c:\tf_jenkins\home\workspace\release-win\m\windows-gpu\py\35\tensorflow\core\platform\cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use AVX instructions, but these are available on your machine and could speed up CPU computations.
2017-06-25 14:46:26.415468: W c:\tf_jenkins\home\workspace\release-win\m\windows-gpu\py\35\tensorflow\core\platform\cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use AVX2 instructions, but these are available on your machine and could speed up CPU computations.
2017-06-25 14:46:26.415812: W c:\tf_jenkins\home\workspace\release-win\m\windows-gpu\py\35\tensorflow\core\platform\cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use FMA instructions, but these are available on your machine and could speed up CPU computations.
2017-06-25 14:46:27.532632: I c:\tf_jenkins\home\workspace\release-win\m\windows-gpu\py\35\tensorflow\core\common_runtime\gpu\gpu_device.cc:940] Found device 0 with properties:
name: GeForce GTX 1050
major: 6 minor: 1 memoryClockRate (GHz) 1.493
pciBusID 0000:01:00.0
Total memory: 4.00GiB
Free memory: 3.34GiB
2017-06-25 14:46:27.532823: I c:\tf_jenkins\home\workspace\release-win\m\windows-gpu\py\35\tensorflow\core\common_runtime\gpu\gpu_device.cc:961] DMA: 0
2017-06-25 14:46:27.534006: I c:\tf_jenkins\home\workspace\release-win\m\windows-gpu\py\35\tensorflow\core\common_runtime\gpu\gpu_device.cc:971] 0:   Y
2017-06-25 14:46:27.534557: I c:\tf_jenkins\home\workspace\release-win\m\windows-gpu\py\35\tensorflow\core\common_runtime\gpu\gpu_device.cc:1030] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX 1050, pci bus id: 0000:01:00.0)
>>> print(sess.run(message))
b'test message'
>>> exit()
```

ここまでくるとCPU版のTensorflowと同じように使えます。


# 稀によくある問題

## GPUメモリが足りない？？

　GPU版Tensorflowを実行した時、下記のようにCUBLAS_STATUS_ALLOC_FAILEDのエラーが発生することが稀によくあるみたいです。
　インターネット上の記事を読む限り、GPU版Tensorflowをデフォルト設定で起動した場合、使用可能なGPUメモリを全部確保しようとする、とのことなので、他のアプリが使用しているメモリまで確保しようとして失敗した、とかですかね？（詳細は不明）

```cmd:
2017-06-28 20:33:08.286260: E c:\tf_jenkins\home\workspace\release-win\m\windows-gpu\py\35\tensorflow\stream_executor\cuda\cuda_blas.cc:365] failed to create cublas handle: CUBLAS_STATUS_ALLOC_FAILED
```

　このエラーはTensorflowのセッションを開始するときに、GPUメモリの使用制限を設定すると回避できます。

```py3:example_of_limiting_GPU_memory
gpuConfig = tf.ConfigProto(
    gpu_options=tf.GPUOptions(per_process_gpu_memory_fraction=0.95),
    device_count={'GPU': 0})
sess = tf.Session(config=gpuConfig)
```