ゼロから始めるPyTorch DeepLearning環境構築 (Windows+WSL2+vscode+簡易実験管理)

「できる限り変わったことをしない(と言いつつ割と変なことをする)」「環境を汚さない」「なるべく手順を減らす」「Linux上(WSL2)でなるべく完結する」ことを目標とした初学者向け環境構築手法です。
Python仮想環境、vscodeによるWSL2上での開発、簡単な実験管理を紹介します。

※ GPUを使用する際に必要となるCUDA周辺の設定はとても大変なので、そちらができてない場合にはコンテナを使用した環境構築がおすすめです。ただし、コンンテナ関連の知識を身につける必要もあるため、今回は使用しません。
※ 2024年現在であればvenvではなくryeを選択しても良いと思います。

## 特徴
- この手順は深層学習モデルをとりあえず手元の環境で動かすためのものです
- WindowsでWSL2+vscode+venv+RemoteWSL環境を構築します
- シェルスクリプトでGPUの選択等を対話形式で行い、プログラムを実行します(WSL2でGPUを使う方法については解説しません)
- 実行時の時間やコメントを反映したディレクトリを作成し、ログの保存・実験管理を行います
- 対象読者としてはLinuxコマンドが少しわかっている程度の人(情報系の学部1~2年生あたり)を想定しています

## データ
データはMNIST(手書き文字データセット)を想定します。

http://yann.lecun.com/exdb/mnist/ 

60,000例のトレーニングセットと10,000例のテストセットで構成されています。
各例は、10クラスのラベルに関連付けられた28x28のグレースケール画像です 
わざわざ手動ダウンロードせずともPyTorchならば使えますが、他のデータセットでも流用できるように画像データを./data/mnist.zipに用意してあるので、後で解凍して使用します。
(vscodeではプロジェクト内に大規模データがあると.gitignoreに入れていても警告が出るため、本当はデータはプロジェクト外に置いたほうがよさそうです)

## 1. VSCode + WSL環境を作る
活発に開発されているので、Qiita等の記事だと情報が古い場合があります。
なるべくMicrosftのドキュメントを参考に環境を作ってください。Windows11だと簡単にインストールできると思います。

### 1.1 **WSL2をインストールする** 
以下のドキュメントを参考にインストールしてください。

https://docs.microsoft.com/ja-jp/windows/wsl/install  

以下、インストールの流れです。
    1. PowerShellを管理者として実行する
    2. `wsl --install`を実行する
    3. 再起動する
    4. (オプション)Microsoft Storeで「Windows Terminal」を探してインストールする。便利です。
    5. Microsoft Storeで「Ubuntu」をインストールする。(Win11であればWSLインストール時に自動でダウンロードされます)
    6. Ubuntuを起動する。
    7. ユーザーを作成する。
    7. `sudo apt update`を実行する(アップデートの内容を確認)
    7. `sudo apt upgrade`を実行する(アップデートを実行)

### 1.2 **WSL2とvscodeを連携させる**
以下のドキュメント等を参考にしてください。

https://docs.microsoft.com/ja-jp/windows/wsl/tutorials/wsl-vscode

vscodeの左側メニューにある、拡張機能から「WSL」を検索してインストールしてください。
    <img width="250" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336908/2d5d78c4-c644-87c6-2243-0af7fa2dcce4.png">
インストールしたらvscodeを再起動します。再起動後にvscodeの左下の緑のアイコンを押すと、vscode上部にメニューが出現するのでそのメニューから「New WSL Window」を選択します。これで新しいウィンドウが立ち上がればvscodeからWSL2を開けています。
    <img width="250" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336908/97610f7c-01fe-7cdd-b175-56f18c7fa200.png">
開いた後に、上部メニューの「ターミナル」>「新しいターミナル」を選択し、新しいターミナルを開いてください。Windows Terminal等を用いて作業してもらっても大丈夫ですが、vscodeでも開いておくと今後の作業で便利です。

### 1.3 **vscodeの拡張機能を導入する** 
Pythonのコーディング支援をしてくれる拡張機能をインストールします。
拡張機能は基本的にWSL2側に入れてください。「Python」「Pylance」の2つは必ず必要になると思うので、左側メニューの「拡張機能」から検索して入れておいてください(「Python」を導入すると自動的にPylanceも導入されるはずです)。
他にも必要なものがあれば導入してください。

## 2. サンプルをGitからCloneする 
サンプルを手元のPC(WSL2の中)にダウンロードしたいので、Gitからcloneします。
カレントディレクトリにダウンロードされるため、格納先のディレクトリを作成して移動しておいてください。
自分は~/vscodeというディレクトリを作っています。

```
# 新しくディレクトリを作る場合
$ cd                    <- ユーザーホームに移動
$ mkdir vscode          <- vscodeというディレクトリを作成

# gitからリポジトリをcloneする
$ cd ~/vscode           <- 作成したvscodeディレクトリに移動
$ git clone https://gitlab.com/tmuromachi/ml-pytorch-template.git
```


## 3. Python環境構築 
Linux上のPythonはシステムが使用しているため、基本的にはそのPythonを使いません。仮想環境やDockerを使うべきです。仮想環境は様々なものがありますが、本稿ではPythonに標準で入っているvenvで仮想環境の作成を行います。
Pythonは3系であればバージョントラブルはあまりありません。どちらかというとバージョンを上げすぎると対応していないパッケージが出てくるので少し古めのほうがよいです。そういった事情も踏まえてQiita等でよく紹介されているpyenv+venv環境は基本的には不要だと考えています。
venvで仮想環境を作る際に違うバージョンのpythonを使えばpyenvなしでも複数バージョンのPythonを使用できます。

以下の手順はpython.jpの仮想環境構築手順を参考にしています。

https://www.python.jp/install/ubuntu/virtualenv.html

### 3.1 **ビルドツール・ライブラリのインストール** 
以下のコマンドで、ビルドに必要なツール類をダウンロードします。

    ```
    $ sudo apt update
    $ sudo apt install build-essential libbz2-dev libdb-dev \
      libreadline-dev libffi-dev libgdbm-dev liblzma-dev \
      libncursesw5-dev libsqlite3-dev libssl-dev \
      zlib1g-dev uuid-dev tk-dev
    ```

### 3.2 **pyenvによるビルド** 
pyenvのpython-buildを利用してPythonソースコードのダウンロードからインストールまで行います。(pyenvはpython-buildを使うためだけに入れています)

    ```Python3.10インストール例：
    # 特にこだわりがなければユーザーホーム直下で実行するといいと思います
    $ git clone https://github.com/pyenv/pyenv.git
    $ pyenv/plugins/python-build/bin/python-build 3.10.4 ~/python3.10
    ```

### 3.3 **仮想環境の作成をする** 
インストールしたpythonのバージョンを指定した仮想環境の作成をします。まず、このプロジェクトをクローンしたディレクトリに移動してください。
(`$ cd  ~/vscode/ml-pytorch-template`といったようなコマンドで移動します。)
次に、手順1で作成したディレクトリの下にbin/python3があるため、それを指定して仮想環境を作ります。
以下のコマンドの場合だと、`.venv`というディレクトリに仮想環境が作られます。
`$ ~/python3.10/bin/python3 -m venv .venv`  


### 3.4 **仮想環境の有効化**
仮想環境の作成が完了した後に仮想環境をアクティブにします。 
`$ . .venv/bin/activate`
ターミナルのプロンプトの前に(.venv)という表示が出たら成功です。
`$ python3`と入力するとPythonのバージョンも確認できます。
仮想環境を終了したい場合には`$ deactivate`と入力することで終了します。

## 4. PyTorchサンプルを動かす
今回動かすサンプルは単純なCNNを使用したものです。以下の記事を参考に作成しており、一部修正しています。

https://qiita.com/takubb/items/7d45ae701390912c7629

コードは`./src`以下に格納しています。今回は実行時に実験管理まで行いたいので、シェルスクリプト経由でmain.pyを実行します。
また、モジュール化しておらず、実行時にシェルスクリプトも不要で全体の流れが分かりやすいPyTorchサンプルコードが`./template/main.py`に格納されています。コードの中身を理解したい場合はこちらを先にみるといいかもしれません。コマンドから実行する場合は`./template`に移動してから`python3 main.py`を行う必要があります。

### 4.1 **必要なパッケージのインストール**
サンプルを動かすために必要なパッケージ等(PyTotrch, numpy等)をインストールします。
必要なパッケージの一覧は`requirements.txt`に記載されており、Pythonのパッケージ管理システムであるpipにrequirements.txtを渡すことでインストールできます。
仮想環境を作成したばかりだと、pipのバージョンが低い場合があるので必要なパッケージをインストールする前に仮想環境を有効化した状態で、pipのアップデートを行います。
`$ pip install --upgrade pip`
アップデート後に以下のコマンドを実行することでrequirements.txtに記載されたパッケージがインストールされます。
`$ pip install -r requirements.txt`

### 4.2 **データ準備**
加工済みMNISTデータを解凍します。(unzipコマンドはデフォルトで入っていないはずなので、無い場合は`$ sudo apt install unzip`で入手してください。)
`$ cd ml-pytorch-template` (プロジェクトのルートディレクトリに移動します)
`$ unzip data/mnist.zip -d ./data/` (解凍します)

### 4.3 **学習の設定**
データセットのパスやエポック数やバッチサイズ等は`config.yaml`で設定してあります
変更したい場合はこのファイルを書き換えると学習の設定を変更ができます。

    ```config.yaml
    config:
      train_path: "./data/mnist/train/"    # <-Trainデータが保存されているパス
      test_path: "./data/mnist/test/"      # <-Testデータが保存されているパス
      model_path: "./model"                # <-modeデータを保存するパス
      classes: 10                          # <-分類するクラス数(MNISTなら10クラス)
      epoch: 3                             # <-エポック数
      batch_size: 64                       # <-バッチサイズ
    ```

### 4.4 **実行**
PyTorchサンプル実行します。
`source run.sh`というコマンドをプロジェクトルートで実行すると、まずCUDAデバイス番号を聞いてきます。
`nvtop`等を使用して、空いているGPUを確認し、番号を入力しましょう。
機械学習用やゲーム用のGPUがない場合は番号入力時にエンターを押してスキップしてください。
スキップした場合は0番のデバイスか、CPUで計算します。
数字を入力してエンターすると、実験時のコメントを入力できます。必要なければそのままエンターを押してください。
コメント入力まで終わるとサンプルが実行されます。

### 4.5 **結果(実験管理)**
実行が終了すると実行結果は./log/[実行時刻]ディレクトリ内に保存されます。

###  注意事項等
- 今回はTrain/Testしか作っていません。注意してください
- 実行用シェルスクリプトでは対話形式で聞いたことを変数に格納し、仮想環境をアクティベートしてから、実行結果を保存するディレクトリを作成し、プログラムを実行します。最後に生成物をログディレクトリに移すという処理まで行っています
このシェルスクリプトにgit pull等を追加して、実行時に自動でコードを更新するようにするなどの工夫をすると更に使いやすくなると思います
- 今回やった実験管理は簡単なもの(ただし普通ではない)ですが、TensorboardやMLflowなど他にも色々とやり方はあると思うので好きな方法を探してください

## 終わりに
はじめて記事を書いたため、誤りやおかしな点がありましたら気軽に報告していただけると嬉しいです。

## 参考文献
Python環境構築ガイド
https://www.python.jp/install/ubuntu/index.html

MNIST-JPG
https://github.com/teavanist/MNIST-JPG
(./data/mnist.zipに使用したものです。)

Pytorch Template 個人的ベストプラクティス（解説付き）
https://qiita.com/takubb/items/7d45ae701390912c7629

PyTorchでDatasetの読み込みを実装してみた
https://qiita.com/kumonk/items/0f3cad018cc9aec67a63

PyTorch Examples：Image classification (MNIST) using Convnets
https://github.com/pytorch/examples/tree/master/mnist