ディープラーニングを始めたいひとのLinux環境構築【Python×Keras】

LinuxでKerasを動かす際の環境構築手順をまとめました。
ディストリビューションはUbuntu 16.04 LTS、GPUで学習を行うことを想定しています。
なお、本投稿によって生じた全ての事象について私は責任を負いかねますので、必ず自己責任で行うようお願いします。
今回はこのような流れで進めていきます。

- はじめに
- Google Chromeをインストール
- Visual Studio Codeをインストール
- fishをインストール
- Pythonをインストール
- CUDAをインストール
- Tensorflow/Kerasをインストール
- Kerasでmnistの学習を実行
- 終わりに


## はじめに
まずはじめにターミナルを開き、下記を実行しておきます。

```shell
$ sudo apt update
$ sudo apt upgrade
```

## Google Chromeをインストール
普通にChromeをインストールしようとすると「インストール中」でフリーズするので、まず下記のパッケージをインストールする必要があります。

```shell
$ sudo apt install libappindicator1

# ここでエラーが発生する場合は現状インストールされているChromeを削除します。
$ sudo apt remove google-chrome-stable
```

その後下記URLから`.dev`のインストーラをダウンロード、インストールを行います。
https://www.google.co.jp/chrome/browser/desktop/

下記コマンドでChromeが起動します。

```shell
$ google-chrome
```


## Visual Studio Codeをインストール
ソースコードを編集する際に必要なエディタをインストールします。
ソースコードエディタは種類が豊富で、PythonにはPyCharmという統合開発環境もありますが、個人的な好みと拡張機能の多さから今回はVisual Studio Code（以下VSCode）をインストールします。
Ubuntuを使っているので下記URLから`.deb`のインストーラをダウンロード、インストールを行います。
https://code.visualstudio.com/download

その後下記コマンドでVSCodeが起動します。

```shell
$ code
```

また下記の基本的な拡張機能をインストールしておくと便利です。

- Japanese Language Pack for VS Code
- Python extension for Visual Studio Code

次にUbuntuはデフォルトのフォントが少々見づらいので、フォントを`Fira Code`に変更します。
下記Githubの指示に沿ってインストールしていけばいいのですが、今回は下部の`Manual Installation`通りにインストールしました。
https://github.com/tonsky/FiraCode/wiki/Linux-instructions#installing-with-a-package-manager

まずシェルスクリプトを作ります。

```shell
$ touch download_and_install.sh
```

上記のファイルを開き、リンク先に書いてあるソースコードをコピペします。

```shell:download_and_install.sh
#!/usr/bin/env bash

fonts_dir="${HOME}/.local/share/fonts"
if [ ! -d "${fonts_dir}" ]; then
    echo "mkdir -p $fonts_dir"
    mkdir -p "${fonts_dir}"
else
    echo "Found fonts dir $fonts_dir"
fi

for type in Bold Light Medium Regular Retina; do
    file_path="${HOME}/.local/share/fonts/FiraCode-${type}.ttf"
    file_url="https://github.com/tonsky/FiraCode/blob/master/distr/ttf/FiraCode-${type}.ttf?raw=true"
    if [ ! -e "${file_path}" ]; then
        echo "wget -O $file_path $file_url"
        wget -O "${file_path}" "${file_url}"
    else
	echo "Found existing file $file_path"
    fi;
done

echo "fc-cache -f"
fc-cache -f
```

download_and_install.shを実行します。

```shell
$ sh download_and_install.sh
```

これでFira Codeをインストールできたので、VSCodeに適用します。
メニューの「Code」→「基本設定」→「設定」を開き、
`Editor:Font Family`を`"Fira Code Retina"`、
`Editor: Font Ligatures`を`有効`にすればフォントが変更されます。
変更されないときは`Retina`部分を`Regular`や、`Bold`にしたりしてみてください。
あとはメニューの「Code」→「基本設定」→「配色テーマ」から、カラーテーマを好きなものに変更します。

最後に個人的に不便なプレビューモードを解除しておきます。
`Workbench › Editor: Enable Preview`と、
`Workbench › Editor: Enable Preview From Quick Open`を`無効`にすればOKです。


## fishをインストール
引き続きターミナルを操作していきますが、今回はshellにfishを使用します。
fishはfriendly interactive shellの略称とのことですが、特徴はやはりわかりやすさだと感じます。コマンドを途中まで入力するとその先をわかりやすく補完してくれたり、シンタックスハイライトによってそのコマンドが正しいのか間違っているのかということも示唆してくれます。
Ubuntuのデフォルトシェルはbashですが、一応現在のシェルを確認しておきます。現在のシェルは`SHELL`という環境変数に設定されているので`$SHELL`の中身を出力することで確認できます。

```shell
$ echo $SHELL
/bin/bash
```

それではデフォルトシェルをbashからfishに変更していきます。
まずはfishをインストールします。

```shell
$ sudo apt install fish
```

インストールができたら、fishのパスを確認します。

```shell
$ which fish
/usr/local/bin/fish
```

自分のマシン環境で使用可能なシェル一覧を確認します。

```shell
$ cat /etc/shells
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
/usr/local/bin/fish
```

末尾に上記fishのパスが追加されていたらOKですが、なければvimを使って手動で追記します。
下記コマンドでvimエディタを開いたら`i`でインサートモードに切り替え、テキストを入力します。
入力が終わったら`esc`でノーマルモードに戻り、`:w`で上書き保存、`:q`でエディタを閉じます。

```shell
$ sudo vim /etc/shells

# vimがインストールされていなかったら下記を実行します。
$ sudo apt install vim
```

下記コマンドでデフォルトシェルをfishに変更します。

```shell
chsh -s /usr/local/bin/fish
```

これでデフォルトシェルを変更できました。パソコンを一度ログアウトするとこの変更が適用されます。
再ログインして変更が適用されたかを確認します。ターミナルを起動し、最初のメッセージがbashのときから変わって`Welcome to fish, the friendly interactive shell`と表示されていたらOKです。一応現在の環境変数も確認しておきます。

```shell
$ echo $SHELL
/usr/local/bin/fish
```

なお、現在使用しているシェルは下記方法でも確認できます。

```shell
cat /etc/passwd | grep username
```

デフォルトシェルはbashのままfishを起動したい場合は`.bashrc`の末尾に`exec fish`と記述しておけば同様にfishを使用できます。

## Pythonをインストール

### pyenvをインストール
pyenvはPythonのバージョン管理ができるコマンドラインツールです。
pyenvを使うことで例えばディレクトリAではPython2系を使う、ディレクトリBではPython3系を使うといったことが可能になります。
公式Github：https://github.com/pyenv/pyenv/wiki
まず上記Githubからpyenvをホームディレクトリにダウンロードします。

```shell
$ git clone git://github.com/yyuu/pyenv.git ~/.pyenv

# Gitがインストールされておらず、上記でエラーが起こる場合はまずこちらを実行します。
$ apt install git
```

次にダウンロードしたpyenvのパスを通します。
「パスを通す」とは「コマンド検索パスを追加する」ことだと考えるとわかりやすいです。コマンドライン上に入力したコマンド（例えば`ls`や`cd`）が正しく動作するのと同じように、コマンドライン上で`pyenv`と入力したらどのファイルを実行してねということを設定します。
現時点ではパスを通していないので下記を実行しても何も表示されません。

```shell
$ which pyenv
```
それではpyenvのパスを通します。今回はシェルスクリプトにfishを使っているので書き込み先は`.config/fish/config.fish`です。

```shell
$ echo 'set -x PATH $HOME/.pyenv/bin $PATH' >> .config/fish/config.fish
$ echo '. (pyenv init - | psub)' >> .config/fish/config.fish
```
書き込みを適用します。（下記コマンドではなくターミナルを再起動しても適用されます。）

```shell
$ source .config/fish/config.fish
```
これでpyenvのパスが通ったので、再度下記を実行するとパスが表示されます。

```shell
$ which pyenv
/home/username/.pyenv/bin
```

### Anacondaをインストール
Anacondaは機械学習やデータサイエンスをするうえで必要になる色々なPythonパッケージをまとめて提供してくれます。
現時点ではどのバージョンもインストールしていないので下記を実行すると`system`というデフォルト項目だけが表示されます。

```shell
$ pyenv versions
* system
```

インストールできるバージョンを確認します。
下記を実行するとpyenvでインストールできるバージョンがリスト表示されます。

```shell
$ pyenv install -l
```

今回は`anaconda3-5.2.0`をインストールします。anacondaのバージョンが新しすぎるとtensorflowをインストールできないことがあるので注意してください。

```shell
$ pyenv install anaconda3-5.2.0
```
ここで再度下記を実行するとインストールできていることがわかります。
`*`が現在適用されているバージョンを示します。

```shell
$ pyenv versions
* system
  anaconda3-5.2.0 (set by /home/username/.pyenv/version)
```

pyenvではインストールしたバージョンを現在のアカウント全体で使うか、特定のディレクトリだけで使うかを指定することができます。今回はanaconda3-5.2.0をアカウント全体に適用します。

```shell
$ pyenv global anaconda3-5.2.0
```

下記を実行すると`*`が移動していることがわかります。

```shell
$ pyenv versions
  system
* anaconda3-5.2.0 (set by /home/username/.pyenv/version)
```

## CUDAをインストール
CUDAはGPUを使って学習を行う際に必要になります。
まず公開鍵を取得します。

```shell
$ sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
```

続いてパッケージをダウンロードします。

```shell
$ wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_9.2.88-1_amd64.deb
```

ダウンロードしたパッケージをインストールします。

```shell
$ sudo dpkg -i cuda-repo-ubuntu1604_9.2.88-1_amd64.deb
```

APTをアップデートし、下記をインストールします。

```shell
$ sudo apt update
$ sudo apt install cuda cuda-drivers
```

ここでPCを再起動します。

```shell
$ sudo reboot
```

このあと`.config/fish/config.fish`に追記します。

```shell
$ echo 'set -x PATH /usr/local/cuda/bin $PATH' >> .config/fish/config.fish
$ echo 'set -x LD_LIBRARY_PATH /usr/local/cuda/lib64 $LD_LIBRARY_PATH' >> .config/fish/config.fish
```

最後にログオフをして再度ログイン後、下記コマンドを実行、接続しているGPUが表示されたらOKです。

```shell
$ nvidia-smi
```

## Tensorflow/Kerasをインストール
続いてTensorflow、そのあとにKerasの順でインストールします。
今回はGPUを使用するので`tensor-gpu`としていますが、`tensorflow`だけでも問題はありません。

```shell
$ conda install tensorflow-gpu
$ conda install keras
```

## Kerasを実行
最後にKerasでmnistの学習を実行して動作確認をします。
コードはこちらを使用します。
https://github.com/keras-team/keras/blob/master/examples/mnist_cnn.py

適当なPythonファイルを作成します。

```shell
$ touch train.py
```

作成した`train.py`に上記URLのコードをコピペして保存、下記を実行します。
エラーなく処理が進めばクリアです！

```shell
$ python train.py
```

## 終わりに
私なりの手順を書かせていただきましたが、上記の手順のなかで不備や漏れ、お気づきのことがございましたらコメントをいただけますと幸いです。

また本稿作成にあたり下記を参考にさせていただきました。
https://qiita.com/shuntksh/items/1995e87fe5c1ac88296f
https://qiita.com/tkmpypy/items/9bd9692ad44dcd5710da
https://qiita.com/yukoba/items/3692f1cb677b2383c983