俺の機械学習プロジェクト管理をさらす

<img width="673" alt="sequence.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221435/03343284-323c-0fd0-05e4-e99d8668e355.png">

# 自己紹介

<img src="https://qiita-image-store.s3.amazonaws.com/0/221435/16727490-2b41-4318-cc25-e2601479e77a.jpeg" width=30%> どうも、綿岡(wataoka)と申します。

機械学習を本気で勉強し続け3年目です。

Webアプリなどのプロジェクト管理はよく出回っていますが、機械学習のプロジェクト管理が少なめなので、僕の管理方法を紹介します。

「もっとこうした方が良いよ」とかあったら気軽にコメントしていってください。

|名前|綿岡晃輝|
|:--|:--|
|職業|神戸大学大学院 修士1年|
|分野|machine learning, deep learning, speaker verification, imbalanced data|
|Twitter|[@Wataoka_Koki](https://twitter.com/Wataoka_Koki)|


# 状況
- python 3.7
- Pytorch 1.1.0
- 研究室に複数GPUサーバあり
- それらを同時に動かすことあり
- デスクトップはMacOS
- GPUサーバはLinux系いろいろ

# 基本
- ソースコードはgitlabで管理。
  - 一人なのでほとんどmasterブランチしか使わない。
  - たまに試験的にdevelopブランチを切ることがある程度。
- GPUサーバにはsshでログイン。
  - ssh先で編集せずに、sshfsを用いてローカルにマウントし、ローカルで編集。
  - ssh先では必ずtmux。

# 命名規則
プロジェクトにおいて命名規則は大事ですよね。

機械学習ではモデルを大量に作ることになると思います。そこで、僕はこのような命名規則をモデルに設けています。

`<日付(8桁)>_<数字>_<手法>`
(例)`20190705_01_focalloss`

です。

`数字`の所は今日のモデルの何番目かを表しています。これにより、１日に100以上作らない限り一意にモデルidを割り振ることができます。

手打ちではなく、pythonで自動割り当てしています。

今日の日付のモデルがいくつあるのかを数え上げ、自動で`model_id`という変数を作成するようにしています。

現在までにどのようなモデルが作成されたかの管理については後述します。

# プロジェクト管理
それでは、お待ちかね。

僕のプロジェクトです。

どーーーん！

```
.
├── README.md
├── cifar10
│   ├── requirements.txt
│   ├── logs
│   │   ├── 20190702_01_softmax
│   │   ├── 20190702_02_softmax
│   │   ├── 20190702_03_softmax
│   │   ├── 20190702_04_softmax
│   │   ├── 20190702_05_softmax
│   │   ├── 20190704_01_softmax
│   │   └── etc...
│   └── src
│       ├── run.sh
│       ├── resnet_method1.py
│       ├── resnet_method2.py
│       ├── models
│       │   ├── densenet.py
│       │   ├── efficientnet.py
│       │   ├── googlenet.py
│       │   ├── lenet.py
│       │   ├── resnet.py
│       │   ├── vgg.py
│       │   └── etc...
│       ├── modules
│       │   ├── optimizer.py
│       │   └── loss.py
│       └── utils
│           ├── data.py
│           ├── eval.py
│           ├── record.py
│           └── visual.py
├── img
│   └── class_distribution.png
└── mtg
    ├── 20190521.md
    ├── 20190528.md
    ├── 20190628.md
    └── 20190703.md
```

## 最上位階層の解説
- 当然トップには`README`
- `cifar10`フォルダのようにデータセット毎に完全に分けています。Web開発で言うプロジェクトの下のアプリケーションみたいな感じです。これは、データセット毎にモデルを変えたり、前処理を変えたり、色々としなければならず、その度にファイル名に`resnet_cifar10.py`とか`dataloader_cifar10.py`とかデータセット名を書きたくないからです。
- `img`フォルダには何かしらの画像を入れておきます。
- `mtg`フォルダには担当教員とのミーティング前のメモをミーティング後のメモをマークダウンで管理しています。

## `cifar10`下の解説
- `requirements.txt`に必要なライブラリを記載しておきます。(大事だよ)
- `logs`フォルダにtensorboardのlogを保存します。
- `src`フォルダにソースコードを書き込みます。(ここがメインみたいなもの)

ここで、`logs`ファイル下に注目してください。

- 20190702_01_softmax
- 20190702_02_softmax
- 20190702_03_softmax
- 20190702_04_softmax
- 20190702_05_softmax
- 20190704_01_softmax

先ほど説明した、モデルの命名規則にしっかりと準拠したフォルダ名になっていますね。

このようにユニークなモデルidを割り振ることで、間違いのない管理を行なっています。


## `src`下の解説
- `run.sh`で再現が取れる実行コマンドを用意します。
- `resnet_method1.py`のようなファイルがメインファイルです。これは`モデル名_手法.py`と言う命名規則の元書いています。このファイルは`utils`下のファイルや`models`下のファイルなどなどを読み出しまくります。
- `models`フォルダの下にpytorchのモデルのクラスを置きます。
- `modules`フォルダの下に自作のlossや自作のoptimizerなど組み込むモジュールを置きます。
- `utils`フォルダの下に便利な関数を置きます。

# データセットについて
データセットはプロジェクトには置かないようにしています。

具体的にはホームディレクトリに`datasets`というフォルダを用意し、そのフォルダに様々なデータセットを保管しています。

理由は、CIFAR10のようなむちゃくちゃ使うデータセットは一つのプロジェクト以外でも使いまくるからです。プロジェクトの度にデータセットをダウンロードするのは馬鹿らしいので、どのプロジェクトからも`~/datasets/CIFAR10`という絶対パスで呼び出しています。

# 実験記録について
少し変わっているかもしれませんが、tensorboardとgoogleスプレットシートを利用しています。

位置付けとしましては、googleスプレットシートでモデルの管理、tensorboardで実験の詳細という感じです。

モデルの命名規則の時に言いましたが、現在までに作られているモデルと被らないようにidを自動で割り当てています。

現在までに作られているモデルは全てgoogleスプレットシートで管理しています。(当然pythonで読み書きしている。)

なぜ、googleスプレットシートで管理したかと申しますと、理由は以下です。

- 複数サーバでモデルidが被らないように、グローバルな場所でモデルidを管理したかった。
- 携帯で綺麗に見られる。
- pythonで読み書きしやすい。

です。

# 実験の流れ
複数のサーバを同時に回すことがあるので、その場合は特にモデルidの管理に気をつけています。

最初にgoogleスプレットシートに空いているモデルidを確認し、書き込みます。同時にモデルのハイパーパラメータなども書き込みます。そうすることで、様々なモデルがどのような設計なのかがわかるようにしています。(ハイパーパラメータだけではわからない部分は`memo`という欄を設けていますので、そこに記載します。)

学習中も、googleスプレットシートにtest errorの値を書き込み続けることで、携帯から綺麗に学習経過を確認することができるようにしています。

最後に学習結果などを記録して、終了です。

教授に見せる時や発表の時などは詳細がわかるtensorboardを使用します。

全体の流れの画像を作ってみました。

<img width="673" alt="sequence.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221435/03343284-323c-0fd0-05e4-e99d8668e355.png">

# あとがき
以上で僕のプロジェクト管理についての解説を終わりたいと思います。

ここどうしてるの？とか聞きたいことがあれば気軽に質問してきてください。

皆さんも快適な機械学習プロジェクトライフを過ごしましょう！