TensorFlow upgrade時 (to 1.3) の注意点

**（ nvidia-dockerの利点について [追記]
(http://qiita.com/TomokIshii/items/0cf8bbf64be2823a82a8#%E8%BF%BD%E8%A8%98nvidia-docker-%E3%81%AB%E3%82%88%E3%82%8B%E7%92%B0%E5%A2%83%E6%95%B4%E5%82%99%E3%81%AE%E5%88%A9%E7%82%B9) しました．）**

TensorFlow 1.3 の正式版(RCが取れた版)がリリースされました．
https://github.com/tensorflow/tensorflow/blob/r1.3/RELEASE.md

新機能等につきましてはリリースノートを参照いただくとして，インストールに少し手間取りましたので，以下，情報を共有します．

(プログラミング環境は，次になります．
- OS: Ubuntu 16.04LTS
- Python: 3.5.2
- TensorFlow(前のバージョン): 1.2.1 (tensorflow-gpu)
- TensorFlow(新しいバージョン): 1.3.0 (tensorflow-gpu)
- CUDA toolkit: 8.0 )

## いつも正式版のbinaryをpipで入れている
Deep Learningのフレームワークは，動きが激しいので，通常は正式版(RC=Release Candidateが取れた版)がリリースされてから，binary配布のものを入れるようにしています．細かい不具合が取れるのを期待して，トラブルを最小化するのが目的です． （裏を返せば，Source code buildする根性がないとも言えます．）

```bash
# From TensorFlow documentation
$ pip install --upgrade tensorflow      # for Python 2.7
$ pip3 install --upgrade tensorflow     # for Python 3.n
$ pip install --upgrade tensorflow-gpu  # for Python 2.7 and GPU
$ pip3 install --upgrade tensorflow-gpu # for Python 3.n and GPU
```

その後，MNISTのコードを使ってテストしました．

1. MNIST分類のシンプルなモデルを使ったコード．**問題なし**．
2. MNIST CNN（Convolutional Neural Network)モデル．**動かない** ...

```text
ImportError: libcudnn.so.6: cannot open shared object file: No such file or directory

Failed to load the native TensorFlow runtime.

See https://www.tensorflow.org/install/install_sources#common_installation_problems

for some common reasons and solutions.  Include the entire stack trace
above this error message when asking for help.
```

TensorFlowのドキュメントに明示的に書かれていないので気づきませんでしたが，[リリースノート](https://github.com/tensorflow/tensorflow/blob/r1.3/RELEASE.md)には，以下の一文が書かれていました．

>- All our prebuilt binaries have been built with cuDNN 6. We anticipate releasing TensorFlow 1.4 with cuDNN 7.

これまで使ってきたのが，cuDNN 5.1 でしたが，今回，cuDNN 6.0が必要となったようです．仕方なく，NVIDIA Developer のsiteにログインして（Deep Learningの簡単サーベイに回答後に）cuDNN 6.0をダウンロード．参考のためにそのページをキャプチャしたものを貼ります．

**Fig. NVIDIA cuDNNダウンロード・メニュー（2017年8月時）**
![NVIDIA_download.png](https://qiita-image-store.s3.amazonaws.com/0/74152/a570357d-d9c3-296c-a07d-1335b1caccfb.png)

（CUDA 9.0 RCもありますね．NVIDIAの新GPU,VOLTA対応版と推測されます．）

この cuDNN v6.0 for CUDA 8.0 をインストールすることで無事，MNIST CNNコードが無事動きました．

## TensorBoardが別パッケージに
TensorBoard が別の pip パッケージになりましたが，これは，**pip** プログラムが面倒を見てくれて，tensorflow本体(tensorflor-gpu)のインストール時に，一緒に入りました．

（参考） https://github.com/tensorflow/tensorboard

一応，テストでtensorboardデモ [mnist_with_summaries.py](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/mnist_with_summaries.py) を動かしてみました．

**Fig. TensorBoard demo**
![TensorBoard_demo.png](https://qiita-image-store.s3.amazonaws.com/0/74152/6354dd5f-2aa9-f18d-d642-295857bc6694.png)


特に，問題は生じませんでした．（タグ名が，正規表現で検索できるようになっていましたが，このバージョンからなのか，以前からサポートされていたか，把握できていません．）

## 新機能 "canned estimators" を使ってみる
せっかくインストールしたので，TensorFlow 1.3 の新機能，"canned estimators" （缶詰化した評価器，tf.estimator.* ) を使ってみました．メイン部のみを以下，載せます．

```py
def main(unused_args):
    ### Load MNIST dataset.
    mnist = tf.contrib.learn.datasets.DATASETS['mnist']('../MNIST_data')
    train_input_fn = tf.estimator.inputs.numpy_input_fn(
        x={X_FEATURE: mnist.train.images},
        y=mnist.train.labels.astype(np.int32),
        batch_size=100,
        num_epochs=None,
        shuffle=True)
    test_input_fn = tf.estimator.inputs.numpy_input_fn(
        x={X_FEATURE: mnist.train.images},
        y=mnist.train.labels.astype(np.int32),
        num_epochs=1,
        shuffle=False)

    ### Convolutional network
    classifier = tf.estimator.Estimator(model_fn=inference_fn)
    classifier.train(input_fn=train_input_fn, steps=400)
    scores = classifier.evaluate(input_fn=test_input_fn)
    print('Accuracy (conv_model): {0:f}'.format(scores['accuracy']))
```

（このコード全体，及び比較のための旧コードはこちら [gist](https://gist.github.com/tomokishii/6a5d433246003811bf215a7b86954c89) にupしました．）

変数初期化や，tf.Session() 等のコードが隠蔽されるため，なんとなく"Hi-Level"な雰囲気にはなりました．但し，まだ不慣れなせいか，あまり使いやすい印象は持てませんでした．（他にHi-Levelな "Keras API" もあるし．）正確な評価には，もう少し，使い込む必要がありそうです．

## 感想
Deep Learning ライブラリの移り変わりが激しくて，若干，ついて行けてない感があります．**TensorFlow**（GPU版）のユーザは，次の TF 1.4 で cuDNN 7.0 にシフトする予定（予定なので 6.0 維持の可能性有り？）を覚えておく必要がありそうです．**Chainer** はというと，ついこの間，v2.0 になったかと思えばもう v3.0.0beta が[リリース](https://github.com/chainer/chainer/releases/tag/v3.0.0b1)されています．（Chainerというより，CUDA周りはCuPyのスペックに注意！でしょうか？）複数のフレームワークを使っていこうとする場合，NVIDIAライブラリのバージョン管理に細かく気を使う必要がありそうです．

（一応，pyenv, virtualenvは，使っているのですが... PyTorch，Theanoも動かしたいとなると，悩みが尽きません．）

##（追記）nvidia-docker による環境整備の利点
@miumiu0917 さんから 「"nvidia-docker" で環境整備が楽になるはず」とのアドバイスをいただきましたので，その状況を確認しました．

（環境の確認）
- OS: Ubuntu 16.04LTS
- Docker: Docker version 17.06.1-ce

nvidia-docker上で，TensorFlowを動かすには，まずTensorFlow Docker イメージを用意します．TensorFlowのドキュメントには，

```bash
$ nvidia-docker run -it gcr.io/tensorflow/tensorflow:latest-gpu bash
``` 

と"latest-gpu"タグのものを使うような指示がありましたが，念の為，Docker Hubのサイトを確認してみます．（参考） https://hub.docker.com/r/tensorflow/tensorflow/tags/

タグ名に "latest" が付くものでも "latest-gpu", "latest-gpu-py3"等，8種類のバージョンがあるようですが，とりあえず "latest-devel-gpu-py3"をpullして，上記の（最初トラブルが発生した） MNIST CNNのコードが「問題なく」動くことを確認しました．TensorFlowのリポジトリ内の Dockerfile には，以下の記述があります．

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/tools/docker/Dockerfile.gpu

```bash
FROM nvidia/cuda:8.0-cudnn6-devel-ubuntu16.04

MAINTAINER Craig Citro <craigcitro@google.com>

# Pick up some TF dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
        build-essential \
        curl \
        libfreetype6-dev \
        libpng12-dev \
        libzmq3-dev \
        pkg-config \
        python \

（後略）
```

1行めの通り，ベースイメージが **"nvidia/cuda:8.0-cudnn6-devel-ubuntu16.04"** と定義されており，きちんと整合がとれるように（あたりまえですが）書かれています．"gpu" サポートを必要とするイメージは，"nvidia-docker" で起動できますので，（なるほど）Deep Learning環境整備，整合性確保において，かなり"楽"ができそうです．

## 参考 web site
- TensorFlow documentation - Installing TensorFlow on Ubuntu  
https://www.tensorflow.org/install/install_linux
- TensorFlow 1.3 Release Note  
https://github.com/tensorflow/tensorflow/releases
- TensorBoard Release Note  
https://github.com/tensorflow/tensorboard/releases/tag/0.1.4