Ubuntu18.04に機械学習環境一式を入れる

## 導入環境
CPU: Intel core-i7 7700K
GPU: GeForce GTX1080Ti

## 入れるもの
Ubuntu18.04
CUDA 9.0
cuDNN 7.3.1 for CUDA9
tensorflow-gpu==1.11
Anaconda 2019.03 for Linux
scipy
pandas
matplotlib
seaborn
scikit-learn
xgboost
lightgbm
catboost

## 本記事の内容
UbuntuのインストールからスタートしてCUDA使ってTensorflowが動くところまで機械学習環境を構築します。

## CUDAとtensorflowのバージョンについて

今回使うGPUはpascalアーキテクチャの<font color="red">GTX1080TiですのでCUDAは8.0以降で使うことができます。</font>
https://en.wikipedia.org/wiki/CUDA

PyPIに置いてあるtensorflow-gpuは特定のバージョンのCUDA用にビルドされたもので、対応しているCUDAは以下のリンク先で確認できます。
https://www.tensorflow.org/install/source
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/9f443b91-d5ac-19c4-77cd-5c02651e427c.png" width=50%>

例えばUbuntu用にビルドされたtensorflow-gpu==1.13.1ではCUDA10.0しか使えません。<font color="red">幸い、今回使おうとしているGTX1080TiならCUDA8～10が選べる</font>ので現時点でリリースされているすべてのビルド済みtensorflow-gpuが使えます。

せっかくなのでCUDA10.0 + tensorflow1.13.1にしようと思ったんですが、僕の環境でCUDA10.0をインストールするとマウスポインタが動かなくなるという謎の症状が出てしまった為、問題の出なかったCUDA9.0をインストールして使えるようにしちゃいました。

## 1. Ubuntu18.04をインストールする

ubuntu18.04LTSのisoイメージを取ってきます。
https://www.ubuntulinux.jp/download

今回はライブUSBをrufusを使って作成しました。
https://rufus.ie/
![images.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/51666a0e-fff7-7b29-fc5b-d6bc7d7fdceb.jpeg)
できました。

## 2. ファイアーウォールを有効にする

ネットに繋ぐ前にファイアウォールを有効にしておきます。とりあえず全部のポートを閉じておいて必要があったら開けると良いですね。

```terminal:terminal
$ sudo ufw default deny
$ sudo ufw enable
```
statusを確認しておきます。

```terminal:terminal
$ sudo ufw status verbose

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
```
外からのアクセスは一律拒否するようにしました。sshとか使うときは個別にallowしましょう。

## 3. nvidia driverをインストールする

ここからネットに接続して作業していきます。

まずはいつものを

```terminal:terminal
sudo apt-get update
sudo apt-get upgrade
```

続いてnvidia driverをインストールします。以下の手順だと最新のドライバーが入らない (2019年5月8日現在でnvidia390が入る) んですがCUDA9.0を使う場合は問題ありません。

```terminal:terminal
sudo ubuntu-drivers autoinstall
```

インストールが終わっても再起動しないとドライバが有効になりませんので再起動します。

```terminal:terminal
sudo reboot
```
起動したらnvidia driverが動いてるか確認します。

```terminal:terminal
$nvidia-smi

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 390.116      Driver Version: 390.116                             |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 108... Off   | 00000000:01:00.0 Off |                  N/A |
|  0%   28C    P0    73W / 320W |    167MiB / 11178MiB |      1%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Process:                                                        GPU Memory  |
|  GPU          PID    Type   Process name                        Usage       |
|=============================================================================+
|    0         1789       G    /usr/lib/xorg/Xorg                       96MiB |
|    0         1920       G    /usr/bin/gnome-shell                     68MiB | 
+-----------------------------------------------------------------------------+
```
どうやら大丈夫そうですね。

#### 4. CUDA9.0をインストール
先に必要なコンパイラをインストールしておきます。

```terminal:terminal
apt-get install libglu1-mesa libxi-dev libxmu-dev libglu1-mesa-dev
```
続いてCUDAのインストールをやっていきます。

CUDAのインストールにはsudo apt-getで取ってくる方法、公式サイトからdebファイルを取ってきてdpkgでインストールする方法、公式サイトからインストーラーであるrunファイルを取ってきてインストールする方法があるようです。今回はrunファイルでやります。

まず公式サイトからrunファイルをダウンロードしてきます。僕の環境ではCPUがcore-i7 7700Kなので、アーキテクチャはx86_64です。ppc64leはpowerプロセッサですから間違えないようにしましょう。Ubuntu18.04の選択肢がありませんが、17.04を選んで出てくるcuda_9.0.176_384.81_linux.runで問題なくインストールできました。パッチが4つあたってたのでそちらもダウンロードします。

公式サイト
https://developer.nvidia.com/cuda-90-download-archive

![image.png](https://qiita-image-store.s3.amazonaws.com/0/277233/c22a3c7c-71ca-00c7-4cd6-3db40d89ae51.png)

runファイルは直接実行するファイルですが、初期の設定だと実行権限が付いてないのでchmodで変更してから実行することになります。

```terminal:terminal
$ cd ファイルを置いたフォルダパス
$ sudo chmod +x cuda_9.0.176_384.81_linux.run
$ sudo ./cuda_9.0.176_384.81_linux.run --override
```
その後、４つのパッチもchmodして実行しておきます。

```terminal:terminal
$ sudo chmod +x cuda_9.0.176.1_linux.run
$ sudo chmod +x cuda_9.0.176.2_linux.run
$ sudo chmod +x cuda_9.0.176.3_linux.run
$ sudo chmod +x cuda_9.0.176.4_linux.run
$ sudo ./cuda_9.0.176.1_linux.run
$ sudo ./cuda_9.0.176.2_linux.run
$ sudo ./cuda_9.0.176.3_linux.run
$ sudo ./cuda_9.0.176.4_linux.run
```

#### 5. cuDNN7.3.1 for CUDA9.0 をインストール
公式サイトからダウンロードします。今回はCUDA9.0を使いますのでcuDNN v7.3.1 for CUDA9.0の中でLinux用のものを選びました。
https://developer.nvidia.com/rdp/form/cudnn-download-survey
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277233/09c2057b-119d-8905-9ac7-a74f1b9a4422.png)

ダウンロードしてきたcudnn-9.0-linux-x64-v7.3.1.20を解凍し、解凍して出てきた「CUDA」フォルダから必要なファイルをCUDAをインストールしたフォルダにコピーします。この辺はwindowsと同じですね。

```terminal:terminal
$ cd ファイルを置いたフォルダパス
$ tar xzvf cudnn-9.0-linux-x64-v7.3.1.20.tgz
$ sudo cp -a cuda/lib64/* /usr/local/cuda-9.0/lib64/
$ sudo cp -a cuda/include/* /usr/local/cuda-9.0/include/
```

#### 6. PATHを通す
~/.bashrcを書き換えてPATHを通します。vimがない人はsudo apt-get install vim辺りでインストールしておいてください。

```terminal:terminal
$ vim ~/.bashrc
```

```vim:~/.bashrc
## CUDA and cuDNN paths`
export PATH=/usr/local/cuda-9.0/bin:${PATH}`
export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64:${LD_LIBRARY_PATH}`
```
PATHが正しく通っていれば以下でCUDAのバージョンが表示される筈です。

```terminal:terminal
$ nvcc -V

nvcc:NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2017 NVIDIA Corporation
Built on Fri_Sep__1_21:08:03_CDT_2017
Cuda compilation tools, reolease 9.0, V9.0.176
```
どうやら無事インストールできたようです。

#### 7. Anacondaでpython環境をインストール
公式サイトからlinux用python3系64bit版インストーラーをダウンロードします。
https://www.anaconda.com/distribution/
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/1519d038-042e-f39a-0d5f-2ff203814c11.png" width=50%>
インストールしていきます。

```terminal:terminal
$ cd ファイルを置いたフォルダパス
$ sh Anaconda3-5.3.0-Linux-x86_64.sh
```

インストールが完了したらpython環境を作ります。最近python3.7で上手くいかなかったことがあるので3.6指定で作りました。環境名は短いほうが後々楽なのでtfにしてみます。

```terminal:terminal
$ conda create -n tf python=3.6
```
環境をactivateします

```terminal:terminal
$ conda activate tf
```
pipでtensorflowをインストールします。

```terminal:terminal
$ pip install tensorflow-gpu
```

pythonを立ち上げてtensorflowがimport出来ればCUDAが入ってます

```python:terminal
$ python
>>> import tensorflow as tf
>>> sess = tf.Session()
```
GTX-1080Tiがどうとか出てきたら上手くいってます。

ついでにtensorflowで計算してみます

```python:terminal
>>> a = tf.constant(10)
>>> b = tf.constant(32)
>>> print(sess.run(a + b))
42
```
ちゃんと動いてくれてるようです

## 8. 機械学習系パッケージをインストールする

```terminal:terminal
(base) $ conda activate tf
(tf) $ pip install pandas sklearn scipy keras matplotlib seaborn catboost xgboost lightgbm jupyter pydot3 graphviz tqdm xlrd
```

これでとりあえずの機械学習環境は用意できたと思います。
えんじょい