Docker環境でPyTorch 〜画像解析〜 #01 環境構築編

## はじめに
[株式会社クリエイス](http://creaith.jp/)CTOの[志村](https://qiita.com/naoto1222)です。
何回かに渡り、PyTorch(ディープラーニング)で画像解析をする実践で使えそうなコードを掲載していきたいと思います。
せっかくなのでDockerで環境構築をしていきます。
最終的にはキャプチャー認証を突破できるレベルまで持ってけたらと思っています。(できなかったらごめんなさい)
大前提として自分、AI絡みの裏の仕組みは全くと言っていいほど理解していませんから。
今となっては微分積分すら怪しいです。はい。
そんな感じですが、その辺の意味不明な計算式を勝手にやってくれるフレームワークがせっかくあるのですからあやかれば良いんです。

## 経緯
[上田](https://qiita.com/uedashuhei)「PyTorchが正式リリースされたから他のフレームワークと何が違うのか触ってみよう」
志村「来たAI！！[クリエイス](http://creaith.jp/)もとうとうこの分野に手を出しちゃいますか！」
[曽宮](https://qiita.com/ryosomiya)・[モトキ](https://qiita.com/pickles)「AI？それっておいしいんですか？」(誇張してます)
志村「・・・。全く知らなくても案外出来ちゃうってのを見せたれ！」
ということで勉強兼ねて、知見が多少ある志村・上田は画像解析を、知見ゼロの曽宮・モトキは株価予想をそれぞれ記事を書くことになりました。

## この記事でやること
Mac上にPyTorchの環境をDockerで構築し、CIFAR10のデータセットを利用しサンプルコードを動かすところまで

## 登場人物
### 画像解析班(この記事の筆者)  
* [志村](https://qiita.com/naoto1222)、[上田](https://qiita.com/uedashuhei)  
はたしてキャプチャー認証を突破することができるのか？！

### [株価予想班](https://qiita.com/creaith/items/f47c33e78fb97349b4c8)
* [曽宮](https://qiita.com/ryosomiya)、[モトキ](https://qiita.com/pickles)  
はたして知見ゼロでどこまでできるのか？！


## 前提条件
1. 実験場を作成する目的
2. 今回は最終にImageをビルドする訳ではない
3. というわけで、かな〜り緩めにvolumesで実験ソースをマウントして行きます
4. ホストでIDEをつかってガンガン修正しつつ、コンテナ上でガンガンテストできる環境を目指します
 
**この記事でやらないこと**
1. Dockerfileを使って公式Imageを元にカスタムImageを作りません
2. AWSのECS,　EKSには対応いたしません
3. コピペしやすい様にコードブロックの頭のユーザーマーク($, %, #)は記述いたしません

## 環境構築手順
ざっくりとこんな感じで進めて行きます
1. Docker環境を作成する。(local環境を汚さないように...)
2. Examples系を利用できるようにディレクトリを整備する。
3. docker-compose.ymlを作成する。
4. テストコードを作成する
5. 公式Imageからコンテナを起動してアクセスする
6. 公式Imageに足りないライブラリを入れる
7. テストする
8. dockerの後片付け
 
**Localに次の様なディレクトリ構造で構築して行きます**

```
# ディレクトリ構成
~
└── git  
    ├── deep-learning
    │   └── pytorch (★current workspace)
    │       ├── src
    │       │   └── ...
    │       └── docker-compose.yml  
    └── education  
        └── pytorch-examples  
            └── ...
```

全部educationだろっ！って声が聞こえなくもないですが、そんな方は後述する　　
`2. Examples系を利用できるようにディレクトリを整備`と
`4. テストコードを作成する`のパスを変更して使ってください。

### 1. Docker環境を作成します

vagrantとvirtual boxは使わずに、brewでdockerを入れます
あとはLaunchpadからDockerを起動して数秒待つだけ

```shell
brew update
brew cask install docker
```

### 2. Examples系を利用できるようにディレクトリを整備

```console
## ディレクトリを作成
mkdir -p ~/git/deep-learning/pytorch/src
mkdir -p ~/git/deep-learning/pytorch/tmp
mkdir -p ~/git/education && cd $_

## examplesをクローン
git clone https://github.com/pytorch/examples pytorch-examples
cd ~/git/deep-learning/pytorch

## docker-composeからファイルを作成
touch docker-compose.yml
```

### 3. docker-compose.ymlを作成する
２の最後で作成した`docker-compose.yml`を記述して行きます。

```docker-compose.yml
version: '3.3'
services:
  pytorch:
    container_name: pytorch
    image: pytorch/pytorch
    tty: true
    # runtime: nvidia
    stdin_open: true
    ipc: host
    volumes:
      - ~/git/education/pytorch-examples:/workspace/examples
      - ./tmp:/workspace/tmp
      - ./src:/workspace/src
      - ./data:/workspace/data
    working_dir: /workspace/examples
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "10"
```
### 4. テストコードを作成する

[公式のcifar10_tutorial.pyをコピーします](https://github.com/pytorch/tutorials/blob/master/beginner_source/blitz/cifar10_tutorial.py)

```console
# viで開いてペーストする
vi ~/git/deep-learning/pytorch/src/cifar10_tutorial.py
```

または、Macの人は以下でもOKです

```sh
pbpaste > ~/git/deep-learning/pytorch/src/cifar10_tutorial.py
```
甘んじてbeginner_sourceを使わせていただきます。
これもvolumeで入れろよ！って声が聞こえなくもないですが　　
ゆくゆくはこれをバラして行く予定なので我慢です


### 5. 公式Imageからコンテナを起動してアクセスする

アクセス方法は３通り

```console
## 1. compose run (おすすめ)
docker-compose run --name pytorch --entrypoint=/bin/bash pytorch

## 2. compose up　& exec
docker-compose up -d pytorch
docker exec -it pytorch bash

## 3. run
docker run --name pytorch -it --ipc=host -v ~/git/education/pytorch-examples:/workspace/examples
```

### 6. 公式Imageに足りないライブラリを入れる

```bash
pip install -r /workspace/examples/mnist/requirements.txt
pip install cython
pip install --upgrade pip
pip install matplotlib
apt-get update
apt-get install -y xvfb
```

これを入れずに進めると、pythonに「ねーよ」と怒られたやつを入れている感じです。
本来はこれらを含めたDockerfileを作成してカスタムImageを作成すべきでしょう。
ま~今回は割愛です、ごめんなさい。

### 7. テストする

```bash
cd /workspace/src
python cifar10_tutorial.py
```

すると結果が出ました

```sh
Accuracy of plane : 71 %
Accuracy of   car : 67 %
Accuracy of  bird : 29 %
Accuracy of   cat : 55 %
Accuracy of  deer : 37 %
Accuracy of   dog : 15 %
Accuracy of  frog : 67 %
Accuracy of horse : 71 %
Accuracy of  ship : 71 %
Accuracy of truck : 47 %
```
飛行機だったようですね、って何がやねん.....まーサンプルコードは動いたので今回はOKです。

### 8. dockerの後片付け

dockerはimageが結構かさむので、こまめに掃除しましょう。

```console
docker rm -f $(docker ps -qa)
docker volume prune
docker rmi `docker images -aq`
```

## 次回
サンプルコードを改変して、モデルの訓練と保存をしていきます。