tensorflow(GPUバージョン)をdockerで動かす(修正)

#はじめに
新たな環境にtensorflowを導入する機会がありましたので，備忘録としてその手順をまとめておきます． ~~[公式のチュートリアル](https://www.tensorflow.org/versions/master/get_started/os_setup.html)に従っていくだけですが．~~ 
**16/4/30 - cuDNNライブラリをdocker内に導入する必要があるようです**
**16/5/10 - [新たな記事](http://qiita.com/ymfj/items/6d2658240aaa02663453)を追加しました．nvidia-dockerを使うと簡単です**

#導入手順
以前はホスト環境に直接インストールしたのですが，最近dockerを推進しているので[誰が?]今回はdockerを使ってみました．分散コンピューティングするときとかに便利かなと．
手順は(1)cuda環境の導入，(2)dockerを走らせる，です．cudaの環境はホストの環境に導入してある必要があります．ちなみにGPUを使わないのであればとくに環境の準備なくtensorflowを走らせることができます．dockerすごいですね．

##cudaの導入
Cuda ToolkitとcuDNNを導入します．Nvidiaのサイトからダウンロードしてきますが，バージョンが複数あります．環境構築では最新バージョンを入れるとうまくいかないといったトラブルがよくありますが，~~私の知る限り7.0-v4, 7.5-v4, 7.5-v5 (toolkit-cuDnn)の組み合わせは動いています．~~今回は7.5-v4を導入しました．
**16/4/30 - cuDNN v5は動きませんでした，すみません．**
**16/5/2 - 再修正です，7.5-v4の組み合わせのみサポートのようです．混乱してしまい申し訳ありません**
> The GPU version (Linux only) works best with Cuda Toolkit 7.5 and cuDNN v4. 

###ダウンロード
Cuda toolkitはググッてnvidiaのサイトからOSやバージョンを選択してダウンロードします．インストール方法を複数選択できますが，私はローカルの.debを選びました．ローカルであればダウンロードしたファイルを再利用できますので．
ダウンロードファイル: ``cuda-repo-ubuntu1404-7-5-local_7.5-18_amd64.deb``

cuDnnはアカウントを登録しないとダウンロードできません．有効なメールアドレスを使って登録します．インストールではなく.tgzのファイルをダウンロードします．
~~ダウンロードファイル: ``cudnn-7.5-linux-x64-v5.0-rc.tgz``~~
ダウンロードファイル: ``cudnn-7.0-linux-x64-v4.0-prod.tgz``

###インストール
####cuda toolkit
cuda toolkitをインストールします．

```
sudo dpkg -i cuda-repo-ubuntu1404-7-5-local_7.5-18_amd64.deb 
sudo apt-get update  
sudo apt-get install cuda
```

cudaのサンプルプログラムでCUDA環境を確認できます．

```
$ /usr/local/cuda/samples/1_Utilities/deviceQuery/deviceQuery


 CUDA Device Query (Runtime API) version (CUDART static linking)

Detected 1 CUDA Capable device(s)

Device 0: "GeForce GTX 750 Ti"
  CUDA Driver Version / Runtime Version          7.5 / 7.5
  CUDA Capability Major/Minor version number:    5.0
  Total amount of global memory:                 2045 MBytes (2144010240 bytes)
  ( 5) Multiprocessors, (128) CUDA Cores/MP:     640 CUDA Cores
  GPU Max Clock rate:                            1110 MHz (1.11 GHz)
...
```

####cuDNN
~~cuDNNは展開してライブラリをコピーします．``cudnn-7.5-linux-x64-v5.0-rc.tgz``の展開先を``./cudnn''とします．~~
**16/4/30 - 以前の方法では正しく導入できていなかったため修正しました**
cuDNNはdocker環境の中に導入しなければならないようです．うまく環境構築できたと思っていたら，実際の計算を回したところでエラーが発生しました．そこで以下のようなDocker Imageを作成しました．

```Dockerfile
FROM gcr.io/tensorflow/tensorflow:0.8.0-gpu

RUN mkdir /tmp/cudnn
COPY ./cudnn-7.0-linux-x64-v4.0-prod.tgz /tmp/cudnn
RUN tar xvzf /tmp/cudnn/cudnn*.tgz -C /tmp/cudnn/
RUN cp /tmp/cudnn/cuda/include/cudnn.h /usr/local/cuda/include
RUN cp /tmp/cudnn/cuda/lib64/libcudnn* /usr/local/cuda/lib64
RUN chmod a+r /usr/local/cuda/lib64/libcudnn*
RUN ln -s /usr/local/cuda /usr/local/nvidia
```
Docker初心者なのでこれでいいのか分かりませんが，``cudnn-7.0-linux-x64-v4.0-prod.tgz``は会員登録をしないとダウンロード出来ませんので，Dockerfileと同じディレクトリにダウンロードしておき，コンテナ内にコピーして使うようにしました．FROMについては次節を参照ください．



##docker run
~~cuda環境さえ導入できればあとは簡単です(docker環境は導入済みとする)．~~
cuDNNを導入するためにDockerfileをbuildして自分のimageを作成しなければなりません．

>We provide 4 Docker images:
>
>* gcr.io/tensorflow/tensorflow: TensorFlow CPU binary image.
>* gcr.io/tensorflow/tensorflow:latest-devel: CPU Binary image plus source code.
>* gcr.io/tensorflow/tensorflow:latest-gpu: TensorFlow GPU binary image.
>* gcr.io/tensorflow/tensorflow:latest-devel-gpu: GPU Binary image plus source code.

###CPUモード(参考)
GPUを使わないイメージの場合
```
docker run -it gcr.io/tensorflow/tensorflow
```

###GPUモードの場合  **16/4/30 - 修正しました**

まず，Dockerfileをbuildする必要があります．Dockerfileの存在するディレクトリで以下のコマンドでbuildします．

```
docker build -t="userName/imageName" .
```


実行にはscriptを使います．

>If you're using a container with GPU support, some additional flags must be passed to expose the GPU device to the container. For the default config, we include a [script](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/tools/docker/docker_run_gpu.sh) in the repo with these flags, so the command-line would look like ...

ダウンロードした``docker_run_gpu.sh``を使うと以下のように起動できます．

```
./docker_run_gpu.sh userName/imageName /bin/bash
```

docker環境を起動した状態でtensorflowを動かしてみると以下のようにcuda環境が正しく動いていることが分かります．**実際に自分のコードを実行してみて計算可能なことを確認しました．**

```test.py
$ python
>>>import tensorflow as tf #以下のようにすべてのCUDA libraryがsuccessfullyにopenできればOKです
I tensorflow/stream_executor/dso_loader.cc:105] successfully opened CUDA library libcublas.so locally
I tensorflow/stream_executor/dso_loader.cc:105] successfully opened CUDA library libcudnn.so locally
I tensorflow/stream_executor/dso_loader.cc:105] successfully opened CUDA library libcufft.so locally
I tensorflow/stream_executor/dso_loader.cc:105] successfully opened CUDA library libcuda.so.1 locally
I tensorflow/stream_executor/dso_loader.cc:105] successfully opened CUDA library libcurand.so locally
>>>sess = tf.Session()
I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:900] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
I tensorflow/core/common_runtime/gpu/gpu_init.cc:102] Found device 0 with properties:
name: GeForce GTX 750 Ti
...
>>>hello = tf.constant('hello')
>>>sess.run(hello)
'hello'
```