dockerでKerasを使える環境を構築する


# はじめに

Docker上で手軽にKerasの環境構築を行います。
使用環境はMacを想定しています。

# DockerにKerasイメージをインストールする

dockerにKerasの環境が用意されたイメージをpullします。

```bash
$ docker pull floydhub/dl-docker:cpu
```

このコマンドによって、Kerasを利用するために必要なあらゆるフレームワークがインストールされた環境を用意できます。

# インストールしたイメージからコンテナを作る

イメージはプログラムでいう**クラス**にあたり
コンテナはプログラムでいう**インスタンス**にあたります。

よって、使用するためにはコンテナをイメージから生成する必要があります。

コンテナの生成のために以下のコマンドを使用します。

```bash
$ docker run -d -it --name docker_keras -p 8888:8888 -p 6006:6006 floydhub/dl-docker:cpu bash
```

-d は**バックグラウンドで起動しておく**という意味です。
これがないと、一回つないだコンテナのシェルから抜けただけでコンテナが終了してしまいます。

-it　をつけることで、**生成されたコンテナの標準入出力(シェル)と、ホスト（Mac）のターミナルをがっちゃんこ**します。
つまり、このオプションをつけることで、MacのターミナルからコンテナのCLIを操作できます。嬉しいですね。

--name docker_kerasでは、このコンテナにdocker_kerasという名前を付けています。名前を付けないとあとから色々とIDを指定しないといけないなど面倒なので付けたほうがいいです。


-p では、ホストOSのポートと、コンテナのポートをガッチャンコします。
-p 8888(ホストOS側):8888（コンテナ側）のイメージです。
Kerasの仮想環境では、コンテナ内でJupyter Notebookを起動・利用することができます。しかし、せっかくコンテナ内でJupyter Notebookを起動しても、デフォルトのままではホストOS側のブラウザから、コンテナ内のlocalhost:8888にアクセスできません。
そこで、ホストOS（Mac)の8888ポートと、Jupyter Notebookの８８８８ポートをつなぐことで、ホストOSのブラウザで
localhost:8888
にアクセスすれば、コンテナ内のJupyter Notebookにアクセスすることができます。
もし、-p 83872:8888とすれば、ホストOSで
localhost:88372
とブラウザでアクセスすれば、おそらくコンテナ内のJupyter Notebook(ポートは8888)にアクセスすることができます。


-p 6006:6006はやっていることは同じです。しかし、6006はTensorFlowのTensorboardというアプリのポートとなっています。
よって、コンテナ内で実行されているTensorboard(6006)に、Macのブラウザ側から6006というポートを指定することでアクセスできるようにしています。

最後に、利用するイメージfloydhub/dl-docker:cpuと、起動するコンテナ内で利用するシェル（Bash)を指定しています。

# コンテナとホストOS（Mac）側のシェルをつなぐ

現在、Kerasのコンテナは上記のコマンドによって、バッググラウンドで動き続けています。
よって、このコンテナにMacのターミナルを接続して、コンテナ内部のCLIにアクセスする必要があります。

```bash
$ docker exec -it docker_keras /bin/bash
```

上記のコマンドを打ち込むと、コンテナ内のバッシュのプロセスを起動して、自分のMac上のOSのターミナルと接続することができます。

上記のコマンドは以下のような概念イメージになっています。

```
$ すでに動いているコンテナのプロセスを新しく作るよ -it(MacのターミナルとコンテナのCLIをつなぐよ) docker_keras(つなぐコンテナ名) /bin/bash(新しいプロセスで実行するコマンド)
```

というイメージです。

よって、

```
$ docker exec -it docker_keras pwd
```

と打ち込むと

1. バックグラウンドで動いているdocker_kerasのコンテナを、Dockerが持ってくる
2. docker_kerasの新しいプロセスを作る。
3. そのプロセス内でpwdコマンドを実行する。

という流れで実行されて、

```
/root
```
というpwdの結果が表示されます。

よって、

```bash
$ docker exec -it docker_keras /bin/bash
```

では、docker_kerasのコンテナで新しくバッシュのプロセスを動かして、それを-itオプションでMacのターミナルとつないでいるため、コンテナのCLIをいじることができます。

# jupyternotebookを起動する

```bash
$ docker exec -it docker_keras /bin/bash
```
のコマンドでコンテナのCLIにアクセスできたはいいものの、この環境下で
VimでPythonを書くのはなかなか厳しいです（Vim使えないので）

よって、Jupyter Notebookを利用してみます。

上記のコマンドでコマンドにつないだあとで

```bash
root@ecdf16228bef:~# sh run_jupyter.sh 
```
と打ち込みます。
現在コンテナ内の/rootディレクトリに
run_jupyter.shというシェルスクリプトがあるため、それを実行することで
JupyterNotebookが起動します。
そして、コンテナ接続時にポートを設定していたため、Macのブラウザで
`http://localhost:8888/tree`にアクセスすることで、Jupyter Notebookを利用できます。

# Tensorboardを起動する

KerasはTensorFlowをラッパーしたライブラリで、Tensorboardという、ディープラーニングの実行結果過程などの結果をGUIで見れるツールがあります。

よって、このTensorboardを利用することで、より直感的にわかりやすく学習度や精度の変化を見ることができます。

```bash
$ docker exec -it docker_keras /bin/bash
```

をして、コンテナに接続したあとに

```bash
root@46e6ade2f98a:~# tensorboard --logdir .
```

をすることで、Tensorboardを起動することができます。
ポートをコンテナ作成時に設定しておいたため、
localhost:6006とブラウザに打ち込むことで、Tensorboardを利用することができます。


# 参考文献

- [docker exec -itって実際は何をしてるの？【90日目】](https://www.nyamucoro.com/entry/2018/01/11/224932)
- [【図解】docker runのオプションいろいろ #マンガでわかるDocker 番外編](https://webdesign-manga.com/docker_run_option/)