Ubuntu16.04LTSにkerasを入れる（自分用）

#この記事について
環境構築で何度も調べて壁にぶつかりを繰り返していたので、自分用の備忘録として保存したいと思った。メモ程度に。

# 環境
Ubuntu 16.04 LTS
Python 3.5
CUDA 8.0
CuDNN 6
tensorflow-gpu 1.4.0
keras 2.0.8

#流れ
クリーンインストールから、kerasでサンプルプログラムが動かせるようになるまで
python入れるとこから、kerasを入れるところまで参考サイト：https://qiita.com/neet-AI/items/6a4233a1c16ba0cf7d53
流れはだいたいこの記事通りだが、細かいとこまでコマンドをメモっておく。

# クリーンインストール
めんどくさいから、「ディスクを削除してインストール」する。

# NVIDIAのドライバを入れる
まずおまじない。

``` terminal
$ sudo apt update
$ sudo apt upgrade
$ sudo apt-get update
$ sudo apt-get upgrade
```
最新のドライバを入れる。

```terminal
$ apt search nvidia
```
で出てくる、nvidia-***を入れる。自分の場合、nvidia-384だった。

```terminal
$ sudo apt install nvidia-384
```
できたらリブート。


# Pythonを入れる
### まずはpyenv

必要なパッケージをインストール。

```terminal
$ sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev libpng-dev
```
gitを入れて、pyenvを入れる。

```terminal
$ sudo apt install git
$ git clone git://github.com/yyuu/pyenv.git ~/.pyenv
$ git clone https://github.com/yyuu/pyenv-pip-rehash.git ~/.pyenv/plugins/pyenv-pip-rehash
```
bashrcに記述していく。

```terminal
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
$ source ~/.bashrc
```

ここでターミナルを再起動する。
pyenvと打って、反応してればOK

```terminal
$ pyenv
```

### 次にAnaconda
pyenv上からanacondaをインストール

```terminal
$ pyenv install anaconda3-4.2.0 # インストール
$ pyenv global anaconda3-4.2.0 # pyenvの設定
```

ターミナルの再起動。

```terminal
$ python -V
```
通常なら、python2が反応するが、pyenvの設定で、Anacondaで入れたPython3.5が返ってくるはず。

# CUDAをインストール
[NVIDIA公式サイト](https://developer.nvidia.com/cuda-80-ga2-download-archive)からCUDAのToolkitを入れる。
Linux→Ubuntu→x86_64→deb(local)とか選択していく。選択したらダウンロードをクリック。


```terminal
$ cd Downloads
$ sudo dpkg -i cuda-repo~~.deb
$ sudo apt update
$ sudo apt install cuda-8-0
```

###　パスの設定
~/.bashrcにCUDAのパスを書き込む。

```terminal
$ echo -e "\n## CUDA and cuDNN paths"  >> ~/.bashrc
$ echo 'export PATH=/usr/local/cuda-8.0/bin:${PATH}' >> ~/.bashrc
$ echo 'export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64:${LD_LIBRARY_PATH}' >> ~/.bashrc
$ source ~/.bashrc # CUDAのパスが書き込まれた~/.bashrcを読み込む。
```
CUDAのパスが追加されているか確認。

```terminal
$ echo $PATH             # 出力に"/usr/local/cuda-8.0/bin"が含まれているか？
$ echo $LD_LIBRARY_PATH  # 出力に"/usr/local/cuda-8.0/lib64"が含まれているか？
$ which nvcc             # 出力が"/usr/local/cuda-8.0/bin/nvcc"になっているか？
$ nvidia-smi             # nvidiaのGPUの情報が表示されているか？
```



# CuDNNを入れる
[ここ](https://developer.nvidia.com/rdp/cudnn-download)から、CuDNN for CUDA8.0のdebパッケージをダウンロードする。
※ 要登録

以下の3つのdebパッケージをダウンロードする。
・cuDNN v6.0 Runtime Library for Ubuntu16.04 (Deb)
・cuDNN v6.0 Developer Library for Ubuntu16.04 (Deb)
・cuDNN v6.0 Code Samples and User Guide for Ubuntu16.04 (Deb)

これらをそれぞれインストール。

 ```terminal
# Install Runtime library
$ sudo dpkg -i libcudnn6_6.0*+cuda8.0_amd64.deb
# Install developer library
$ sudo dpkg -i libcudnn6-dev_6.0*+cuda8.0_amd64.deb
# Install code samples and user guide
$ sudo dpkg -i libcudnn6-doc_6.0*+cuda8.0_amd64.deb
```

##動作確認

```terminal
$ cuda-install-samples-8.0.sh ~ # ホームディレクトリにサンプルコードをコピー。
$ cd ~/NVIDIA_CUDA-8.0_Samples/
$ make
$ cd bin/x86_64/linux/release   # サンプルの実行ファイルがあるディレクトリに移動。
$ ./smokeParticles
```
makeでエラーが出たら、[ここ](http://d.hatena.ne.jp/taksei/20170107/1483800327)を参照。makeには結構時間がかかった。

# tensorflow-gpuとkerasを入れる。

```terminal
$ pip install tensorflow-gpu==1.4.0
$ pip install keras==2.0.8
```

pythonを開いてimportしてみる。importできればOK。

```terminal
$ python
```

```python
import keras
import tensorflow
```

# 最後に
mnist_cnn.pyを実行してみる。

```python:mnist_cnn.py
'''Trains a simple convnet on the MNIST dataset.

Gets to 99.25% test accuracy after 12 epochs
(there is still a lot of margin for parameter tuning).
16 seconds per epoch on a GRID K520 GPU.
'''

from __future__ import print_function
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K

batch_size = 128
num_classes = 10
epochs = 12

# input image dimensions
img_rows, img_cols = 28, 28

# the data, split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

if K.image_data_format() == 'channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
    input_shape = (1, img_rows, img_cols)
else:
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
    input_shape = (img_rows, img_cols, 1)

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adadelta(),
              metrics=['accuracy'])

model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
```
実行中にGPUが使われているか確認。

```terminal
$ nvidia-smi -l 1
```

# その他
CUDAとCuDNNのバージョンは[ここ](https://www.tensorflow.org/install/source#common_installation_problems)で確認。