Ubuntu16.04 でDeep learning環境を整える（Anaconda,NVIDIA-driver-384,CUDA-9.0,cuDNN7.０）〜ログインループとの戦い〜

# まず最初に
少し期間が空いた後にDeep learningをしようと、Ubuntu（環境構築済み）で実行してみるとエラーが出てしまった。
原因としては、Ubuntuが入っているパソコンは研究などで複数人使うため、どこかのタイミングでカーネルの更新をしてしまったので、グラボの対応がうまくいってないような感じだった。
そのため、起動時のグラボのバージョンの選択やNVIDIAのドライバーのインストールなどをしたが、うまくいかずに案の定ログインループにハマった。
ここに書くのは、自分の環境での[ログインループから抜け出た方法](https://qiita.com/pkaiky/items/560d15998daa4ae10c14#%E3%83%88%E3%83%A9%E3%83%96%E3%83%AB%E3%82%B7%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0)やその後のDeep learningを行うまでの環境構築、起こったトラブルなどです。
自分でハマった際にたくさん調べていろんなものを参考にしたので、またこのような事態が起こったときに調べまくるのが辛いので、メモがてらに一連の流れを書いていきます。
参考になれば、幸いです。

# 現環境＆最終的に入れたもの
- Ubuntu16.04 LTS
- Linux
- Anaconda
- Python 3.6.6
- Geoforce GTX 1070 Ti
- NVIDIA-driver-384(色々試したが、現環境ではこれが最適だった)
- CUDA 9.0
- cuDNN 7
- tensorflow-gpu 1.10.0

#Ubuntu16.04についての前段階
インストールについてはここに書くことはないですが、インストールした後のイーサネット接続（有線）については書こうと思います。
ログインループなどで再起動した際に有線の接続が切れてしまうことが多々あったため、接続方法を記載します。環境構築に進みたい人は[こちら](https://qiita.com/pkaiky/items/560d15998daa4ae10c14#%E3%81%93%E3%81%93%E3%81%8B%E3%82%89%E3%81%AF%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E6%9B%B8%E3%81%84%E3%81%A6%E3%81%84%E3%81%8F)
##１．設定からネットワークのところをみると有線の表示がなかった...
そのため、NICなどを認識しているかの確認と接続するまでをここに書いていく。
 NICは有線接続の際にパソコンが入っているカードのことで、それを認識しているかの確認を行う。

```
$ ifconfig
```
NICを認識していなければ、表示される内容に**ローカルループバック**しか表示されない。
これでは接続されていないということ。
##２．認識してもらうため、ドライバのダウンロードを行う
どのドライバを選べばいいかわからないため、それを探すために以下のコマンドを打って確認。

```
$ lspci | grep 'Ethernet/ | Network'
```
確認ができたら、インターネットにつながっているパソコンからダウンロードを行い、USBなどでUbuntuの方へダウンロードしたものを持ってくる。私の場合は、インテルのドライバが必要であった。
ちなみに[ここから](https://downloadcenter.intel.com/download/15817)ダウンロードした。
##３．コマンドを打って有線接続
フォルダの解凍後に接続を開始する。
流れとしては、ドライバのインストール後にインストールできているかの確認を行っている。

```
$ cd ./解凍場所（私はもうホームにした）/解凍したフォルダに入る/src/
$ sudo make install
$ sudo modprobe -r e1000e
$ sudo modprobe e1000e
$ lsmod | grep e1000e
```
最後のコマンド実行後にどこかにe1000eと数字の羅列が出てきてたら、認識していると思って大丈夫。
ここで最初に打ち込んだ$ ifconfig を打ち込んでローカルループバック以外が表示されていれば、もう完璧。
あとは最後にネットワークの設定（アドレス・DNSサーバー・ネットマスクなど）を設定して保存すればOK！
これで有線接続については終わり。
#ここからは環境構築について書いていく
まず最初に現環境を最新のものに切り替える

```
$ sudo apt-get upgrade
$ sudo apt-get update
```
これで最新になる
##１．Anacondaのインストール
Anacondaのインストールは[ここから行う。](https://www.anaconda.com/distribution/)
今回は、Linuxへのインストールなので、ダウンロードページでLinuxのところを選択
<img width="1227" alt="スクリーンショット 2019-10-26 12.34.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315165/62d29873-87fe-b7c8-ed5b-a5d873912f64.png">
その下に、Pythonのバージョンが書かれたダウンロードのところがあるので、選択してダウンロードする。
（今回は、Pythonの最新バージョンの3.7系）
<img width="1055" alt="スクリーンショット 2019-10-26 12.34.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315165/78018009-3cb1-7bea-6e60-06e2e74a43ad.png">
ダウンロード後にその端末上でそのディレクトリに移動し、bashコマンドを実行する。
AAAはその時の最新バージョンが入る。

```
$ bash Anaconda3-AAA-Linux-x86_64.sh
```
実行すると以下のメッセージが表示される。

```
Welcome to Anaconda3 （バージョン）

In order to continue the installation process, please review the license
agreement.
Please, press ENTER to continue
>>>
```
Enterキーを押して進めていく。ずーっと進んでいくと最後にyes/noを聞かれるので、yesと入力し、Enterキーを押す。
次に、Anacondaのインストール先を聞かれるので、自分がインストールしたい場所にしてください。

```
[/home/デフォルト/anaconda3] >>>（インストールしたい場所のPATHを追記）
```
デフォルトでいいなら、Enterキーを押して、進めていく。
この後に、Anacondaの初期化をしていいか聞かれるので、yesを入力して、Enterキーを押す。
その後インストールが完了する。インストールの完了後にVisual Studio Codeをインストールするか聞かれるが、いる場合はyesを選択して入れる。Anacondaは使うことを推奨しているみたい。
一応condaコマンドを使って、インストールできているかの確認。

```
$ conda -V
```
ここで、condaコマンドがありませんとでてしまうこともありますが、特に焦る必要はありません。
AnacondaのPATHが通っていないだけで、インストールはうまくいっているはずなので、以下のコマンドを打ってみてください。

```
$ export PATH=~/anaconda3/bin:$PATH
```
上記のコマンドでPATHを通すことができるので、もう一度先ほどのコマンドを打ってみてください。

```
$ coda -V
```
今度はうまくいくはず。
これでcondaのバージョンみたいなのが表示されればOKです。

ちなみに...
Anacondaは最新のものを入れるのは構わないですが、後々のCUDAなどの互換性を考えると、Pythonは3.3〜3.6の環境にしておくことが必要。バージョンなどの対応表は後ほど
Anaconda環境でのPythonバージョン指定インストール方法（予めしておくことをオススメします。）

```
$ conda install Python==3.6.6
```
今回は、3.6.6をインストールした。
##２．NVIDIA-driverのインストール前にやっておくこと
Linuxだとデフォルトのnouveauグラフィックドライバを使っているので、使わないように設定してあげる。

```
$ lsmod | grep -i nouveau
```
これを打ち込んで何も返ってこなければ、ここは無視してもらってもいい。
返ってきた場合は、以下のものを書き込む。

```
$ sudo sh -c "cat << ETX > /etc/modprobe.d/blacklist-nouveau.conf
```
これを打って、Enterキーを押した後にこちらを入力。

```
blacklist nouveau
blacklist lbm-nouveau
options nouveau modeset=0
alias nouveau off
alias lbm-nouveau off
ETX" && cat /etc/modprobe.d/blacklist-nouveau.conf
```
入力した後にEnterキーを押す。その後、反映させる。

```
$ sudo sh -c "echo 'options nouveau modeset=0' > /etc/modprobe.d/nouveau-kms.conf" && cat /etc/modprobe.d/nouveau-kms.conf
```
反映させたら、一度再起動をかけてあげる。

```
$ sudo update-initramfs -u
$ sudo reboot
```
再起動後にビルドツールのインストール

```
$ sudo apt-get install build-essential
```
##3．NVIDIA-driverのインストール
NVIDIAのドライバはCUDAとのバージョンを合わせないとログインループに確実に陥る。（何回も体験した）
[ここ](https://www.nvidia.co.jp/Download/index.aspx?lang=jp)でNCIDIAドライバの最新バージョンの確認をしてもらいたい。基本的にはNVIDIA-driverの方が最新なため、それよりも低いバージョンのドライバをインストールしてもらいたい。
ここでは、バージョン確認だけでインストール自体はコマンドで行う。
（自分のマシンに搭載しているものを入力）
その後にCUDAとのバージョン確認を下の画像をみて確認する。

CUDA確認ページはこれ→ https://www.nvidia.co.jp/Download/index.aspx?lang=jp
<img width="769" alt="スクリーンショット 2019-10-25 14.54.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315165/38615b50-bf5a-5f90-d931-2b3838b30090.png">

私が行った時はNVIDIAドライバの最新バージョンが430とかだったが、それをインストールしても対応するものがないため、今回は384.81を入れた。対応していればOK

実際に入れた時のコマンドを以下に示す。AAAは自分のバージョンを入れてください。私の場合は、384

```
$ sudo apt-get update && sudo apt-get install nvidia-AAA
```
これでドライバのインストールが完了

一応ドライバがインストールできているかの確認のため、以下のコマンドを打ち込む

```
$ nvidia-smi
```
実行後に表のようなものが出てくればOK！

##４．CUDA-9.0のインストール
[こちら](https://developer.nvidia.com/cuda-toolkit-archive)のダウンロードサイトにいって、ダウンロードしたいものをインストールページにいけばいい。
今回選択するのは、CUDA Toolkit 9.0を選択。
その際に、Linux，x86-64，Ubuntu，16.04，deb(Network)を選択して、下に表示されるコマンドを実行していく。
**注意:**最後のコマンドに追記をしているが、これはそのままダウンロードページに表示されている　sudo apt-get install cuda 実行してしまうと、最新のNVIDIA-driverがダウンロードされてしまい、ログインループに陥るようです。（一回ハマりました）
もし、cuda-9-0でエラーが出るようなら、cuda-toolkit-9-0で実行してみてください。

```
$ sudo dpkg -i cuda-repo-ubuntu1604_9.0.176-1_amd64.deb
$ sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
$ sudo apt-get update
$ sudo apt-get install cuda-9-0
```
これでインストール自体は完了したので、環境設定をしておく。以下のコマンドを打ち込む。(自分の環境に入れたcudaのバージョンを書くこと。)

```
$ export PATH=/usr/local/cuda-9.0/bin${PATH:+:${PATH}}
$ export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
```
ここでまた再起動。

```
$ sudo reboot
```
再起動後に念のため、CUDAのバージョンを確認する。

```
$ dpkg -l | grep cuda
```
CUDA-9.0という表示の一覧が出る。
##５．cuDNNのインストール（ついにここまで来た）
さぁ、ここまでくればあとはもう少しです。
cuDNNを入れましょう！！
公式のサイトにいけば、ダウンロードページを選択して、cuDNNのダウンロードを行う。
サイトはこれ→https://developer.nvidia.com/rdp/form/cudnn-download-survey
会員登録が必要なので、してください。
同意するところにチェックマークを入れると、最新のcuDNNの一覧がずらっと出てくる。
ここでは、CUDAとのバージョン対応表よりcuDNNのバージョンを選択する。
[ここから確認してください](https://www.tensorflow.org/install/source#linux)
対応表は以下に貼ります。
<img width="871" alt="スクリーンショット 2019-10-25 16.00.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315165/d0af99b9-2f1c-d2f9-ac30-37f807765a98.png">
今回はcuDNNの7.0.5を選択した。
先ほどのダウンロードページから下の方にいくと、Download cuDNN v7.0.5 (Dec 5, 2017), for CUDA 9.0 のようなものがあるので、選択する。
すると、また一覧がずらっと出てくるので、その中から現環境なら、Ubuntu16.04[Deb]と書いてあるものをダウンロードしていく。ちなみに、種類は以下のようなもの

- Runtime
- Developer Library
- Code Samples and User Guide

上記の３つをダウンロードしたあと、ダウンロードした場所に移動し、コマンドを実行していく。

```
$ sudo dpkg -i libcudnn7_7.0.5.15-1+cuda9.0_amd64.deb
$ sudo dpkg -i libcudnn7-dev_7.0.5.15-1+cuda9.0_amd64.deb
$ sudo dpkg -i libcudnn7-doc_7.0.5.15-1+cuda9.0_amd64.deb
```
実行すればこれでインストール完了
基本的な環境構築はこれで終了

ここでも念のため、cuDNNが入っているかを確認する。

```
$ dpkg -l | grep cudnn
```
ここでもlibcudnn-7.05などが出ていれば、OK
##６．Tensorflow-GPUのインストール
あとは、Deep learningを行うためにTensorflow-gpuを入れていく。
先ほど載せた対応表ではTensorflow-gpuは対応してるものは結構ありそうだが、今回は1.10.0のバージョンを指定して入れることにする。
ちなみに、tensorflowとtensorflow-gpuが共存しているのはよくないので、Anacondaの環境で確認後に二つある場合は pip unistall で両方消しておく。もう一度gpuバージョンのみをインストール。 

```
$ pip install tensorflow-gpu==1.10.0
```
やっと環境構築が終わったと一安心。
これでGPUを認識していないと怖いので、一応確認する。

###全て正しく入っているかの確認
端末上でpythonと打ち込んでPython環境に入る

```
$ python
>> import tensorflow
```
これでエラーが出なけれな、とりあえずOK
バージョンの対応があってなければ、以下のようなエラーが出る。
CUDAのバージョンが9.0じゃないと駄目だよーのエラー

```
ImportError: libcudart.so.9.0: cannot open shared object file: No such file or directory
```
これが出てきたら、辛い状況ではあるが、以下のコマンドを打ってそれぞれのバージョンの確認をする

```
$ dpkg -l | grep nvidia
$ dpkg -l | grep cuda
$ dpkg -l | grep cudnn
$ pip show tensorflow-gpu
```
ここであっていないものがあれば、対応するようにインストールをし直す。
###無事にインポートできたらGPUの確認

```
$ python
>> import tensorflow
>> from tensorflow.python.client import device_lib
>> device_lib.list_local_devices()
```
最後のコマンドを実行後にGPUの表示があればOK
#まとめ
私自身は何回もログインループに陥り、一度はUbuntuの再インストールを考える状況にもなったが、なんとか元の状態に戻すことができました。この後にトラブルシューティングについても書きますが、この記事がみなさんが同じような状況に陥らないようになっていれば幸いです。
長くなりましたが、最後まで読んでいただき、ありがとうございました。

#トラブルシューティング
####ログインループについて
いろいろ試した結果、分かったこと。
ログインループにハマったときはubuntuと対応していないNVIDIAドライバが入っている可能性が高いので、すべて真っ白にして、環境構築をもう一度やり直すのがいい。(cuda,cudnn,NVIDIAドライバを削除した段階でログインループから抜けることができる)
めんどくさいとは思うが、結局同じぐらいの時間な気がするので、私は全て消すことにしました。
やり方は以下に書きます。
####対処の流れ
まず、最初にログイン画面からでは何も操作ができないので、Ctrl + Alt + F1を押して仮想コンソールに入ります。
次に、自分のユーザーネームとパスワードを打ち込み仮想コンソール上でログインします。
その後、ルートユーザーになるために以下のコマンドを打ち込みます。

```
$ sudo su -
```
ここでパスワードが聞かれるのでルートユーザーのパスワードを入力する。
すると、今まで$マークだったところが#マークに変わっているかを確認してください。
なっていれば、ルートユーザーということです。
その後、仮想コンソール上で以下のコマンドを打ち込みます。 

```
# sudo apt-get remove nvidia*
# sudo apt-get remove cuda*
# sudo apt purge cuda*
# sudo apt purge nvidia-cuda*
# sudo apt purge libcuda*
```
これで綺麗さっぱり全て消えるはずなので、環境構築をやり直します。
一応本当に消えているかの確認。

```
# dpkg -l | grep nvidia
# dpkg -l | grep cuda
# dpkg -l | grep cudnn
```
何も表示されなければ、消えてます。これで、ログインできるはずなので、再起動後にGUI画面上でログインしてください。（おそらく、再起動しなくても、Ctrl + Alt + F7で仮想コンソールを抜け出し、GUI画面上でログインすれば入れます。）

念のためですが、ルートユーザーからのログアウトの仕方は # logoutで大丈夫です。
[環境の再設定をする人はここから](https://qiita.com/pkaiky/items/560d15998daa4ae10c14#ubuntu1604%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E5%89%8D%E6%AE%B5%E9%9A%8E)