WindowsでCUDA+PyTorchのサンプル実行するまでのメモ

CUDA + PyTorch + IntelliJ IDEA を使って[PyTorchのVAEのサンプル](https://github.com/pytorch/examples/tree/master/vae)を動かすとこまでのメモです。

[PyTorchの環境作ってIntelliJ IDEAで動かすところまで](https://qiita.com/stkdev/items/069bc0cbfb30c060e060)の番外編というか、むしろこっちが本編です。
↑の記事との違いは、GPUを使うためにCUDAを入れるところ、Anacondaを使わずにできるだけ最小限のライブラリインストールで済ませているところです。

2018/7月版。

# 前提
- Windows10、GTX1080環境での手順です
- Mac（CUDA抜き）でも同様の手順で動作を確認

# 環境構築
## Visual Studioを先に入れる

CUDAインストール時にVisual Studio入れてね、と言われるので先に入れておきます。
C++のコンパイラ使ってるみたいです。
Visual Studio Communityで大丈夫です。
[Visual Studio](https://visualstudio.microsoft.com/ja/vs/)

## CUDA入れる

nVIDIAのGPUを計算処理に使うためのツールキットCUDAをインストールします。
現時点で9.2が最新バージョンですが、ライブラリ側が対応していないことが多いため、9.0を入れておくと良いと思います。
（あと、自分の環境では9.1がエラーでうまくインストールされませんでした。）
[CUDA Toolkit](https://developer.nvidia.com/cuda-90-download-archive)

## PyTorch入れる
インストール方法は公式サイトを参考に。バージョン等をぽちぽち選択すると、１〜２行のインストールコマンドが出てきます。
https://pytorch.org/
python3.6ならこんな感じ。

```sh:pythonインストール
pip3 install http://download.pytorch.org/whl/cu90/torch-0.4.0-cp36-cp36m-win_amd64.whl 
pip3 install torchvision
```
## Python環境作る
venvの機能を使って仮想環境を作っておきます。プロジェクトごとにライブラリの管理などができ、便利です。

```sh:venv
python -m venv dir_name
```
とすると、dir_nameディレクトリが作成され、その中は仮想環境になっています。
以下のようにすることで有効化できます。（bashの場合）

```bash:venv
cd dir_name
source bin/activate
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/bf505cd0-f1ce-6983-58f5-bf06296ba9dc.png)
シェル別有効化方法はこちら。
引用＆参考：[venv - 仮想環境の作成](https://docs.python.jp/3/library/venv.html)

無効化するときは`deactivate`


# サンプル実行
サンプルとしてpytorch-exampleの[VAEのソース](https://github.com/pytorch/examples/tree/master/vae)を持ってきて動かしてみます。

```
git clone https://github.com/pytorch/examples.git
cd examples/vae/
python main.py
```

ここでwindows環境では`Multiprocessing error without if-clause protection`という実行エラーが出ました。

```
RuntimeError:
    An attempt has been made to start a new process before the
    current process has finished its bootstrapping phase.

   This probably means that you are not using fork to start your
   child processes and you have forgotten to use the proper idiom
   in the main module:

       if __name__ == '__main__':
           freeze_support()
           ...

   The "freeze_support()" line can be omitted if the program
   is not going to be frozen to produce an executable.
```

この場合、エラーメッセージのように実行するコードを関数化して`f __name__ == '__main__':`から呼び出すことで回避できます。
サンプルコードの下部、forループの部分を以下のように雑に変更しました。（全体を囲ってしまってもよいですけどね）

```python:windows用
def main():
    for epoch in range(1, args.epochs + 1):
        train(epoch)
        test(epoch)
        with torch.no_grad():
            s = torch.randn(64,2)
            for i in range(0,64):
                i
                s[i] = epoch / 4 + 2/1024*i + (torch.range(1,2) / 1024) - 5

            sample = s.to(device)
            sample = model.decode(sample).cpu()
            save_image(sample.view(64, 1, 28, 28),
                       'results/sample_' + str(epoch) + '.png')

if __name__ == '__main__':
    main()
```


他にもwindowsで起こりがちなエラーは以下のページに解決策が載っていることもあるので、困ったら確認しましょう。
https://pytorch.org/docs/stable/notes/windows.html

これで計算結果がズラーっと出てくれば動作OKです。

また、この時代表的な引数として以下を指定できるようです。



| 指定 | デフォルト値 |
|:------:|:-------:|
|--batch-size|128|
|--epochs|10| 
|--no-cuda|False|
|--seed|1|
|--log-interval|10|


## Intellij IDEA設定する
IDEから先ほど作成したvenv環境にアクセスできるようにします。（もちろんIDE側で新規作成しても良い）
importプロジェクトでVAEのプロジェクトを指定します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/fb1802b2-11ae-e782-87d3-4f67642439df.png)
この時、途中でSDKの選択が出てくるのでvenvで作成した環境の物を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/2482f08e-7c17-e10f-db04-e21ed2a245cf.png)
左上の+ボタンからSDKを追加できるので・・・
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/b4a25931-db7a-281b-9d12-8452a3dee491.png)
Base interpreterに、作成した仮想環境以下のbin/pythonを指定

これで、開発環境もOK

※キャプチャ画面がWindowsだったりMacだったりになっていますが、WindowsとMac両方で試してたからです。念のため。

# おまけ　速度比較
cudaありなしでどの程度速度に差が出るかを試してみました。

- cudaなし
![vae_no_cuda.gif](https://qiita-image-store.s3.amazonaws.com/0/83530/09f571b8-1056-dcb1-4f1f-f954fbe5ba49.gif)

- cudaあり
![vae_cuda.gif](https://qiita-image-store.s3.amazonaws.com/0/83530/4a11604a-9b7c-c64e-052b-2abd6efab3d2.gif)


結論：GPUすごい。