ゼロから作るディープラーニング（物理）

# 本記事の概要
ぱそこん初心者が自作PCを組み立てUbuntuを入れ、PyTorch+CUDAでMNISTするまでの軌跡です。
主に自分が詰まった部分についてまとめた内容です。間違っている部分や、より良い部分があればぜひ教えていただきたいです。
`2019/01/14`時点での情報となります。

# 著者の知識レベル
* PCをつくるのははじめて。普段は会社でも自宅でもMacを使っている。
* 所謂データ分析を仕事にしており、普段はSQL、Python、Tableauとかで仕事している。
* 前職ではRandomForestとかLightGBMを使った機械学習システムを構築・運用したりしてた。
* 業務上サーバの運用のためにLinuxをいじいじしたりshを書いたりするが、大したことはできない。`ls`はできる。
* 最近、[ゼロから作るディープラーニング](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8BDeep-Learning-%E2%80%95%E8%87%AA%E7%84%B6%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86%E7%B7%A8-%E6%96%8E%E8%97%A4-%E5%BA%B7%E6%AF%85/dp/4873118360)を読んでディープラーニングで遊びたくなり、自前のMacBook Airに絶望したがAWSとかGCPのGPUインスタンスはずっと使おうと思ったら高いし、Google Colaboratoryは重いファイルのuploadが重くて取り回しずらそうだった。そこで、オンプレでGPUマシン持てば実質無料で遊べちまうんだでは？と思い立ち作ることにした。

# 1. PCに必要な部品を揃える
何もわからないが、PyTorchでCUDAを使うには謎の半導体メーカーnVIDIAのGPUが必要らしい。色々ぐぐると最近は `GeForce GTX10XX`(1060~1080Ti)でやってる人が多そうだったので、それが欲しいという気持ちを胸に秋葉原に向かった。
そこで、ツクモの店員さんと相談しつつ以下のパーツを揃えた。

| 種別       |       製品名 |
|:-----------------|------------------:|　
| PCケース             |  Thermaltake Versa H26 Black|
| CPU           | intel Corei7 8700|
| CPUクーラー             |  虎徹MarkⅡ|
| GPU         |  nVIDIA GeForce RTX-2070 |
| メモリ             | crucial DDR4 16GB×2|
| SSD          |  crucial MX500 500GB 2.5inch |
| 電源  |  Seasonic FOCUS 750W |
| マザーボード | [ASUS TUF H370-PRO GAMING(Wi-Fi)](https://www.amazon.co.jp/H370%E6%90%AD%E8%BC%89-LGA1151%E5%AF%BE%E5%BF%9C-TUF-H370-PRO-GAMING/dp/B07BP9QHF1/ref=sr_1_1?s=computers&ie=UTF8&qid=1547480027&sr=1-1&keywords=TUF%2BGAMING%2Bh370%2Bpro&th=1)  |

ちなみに、モニタ・キーボード・マウスは既に持っていたものを流用したため新規購入はなし。（のはずだった）
GTXではなくRTXにしたのは、なんか店員さんにコスパを考えたらRTXのがいいんじゃない？って言われたので素直に従った結果です。
また、自分の部屋のルータと机の位置的に有線LANを敷くのは厳しかったので無線LANが入ってるマザボになった。後付けのやつでも良かったんだけど、結局マザボに入ってるやつのほうが安くなった。
![IMG_2571.JPG](https://qiita-image-store.s3.amazonaws.com/0/203205/21b7edf1-d799-4b97-9cbb-7c9d23de2d7e.jpeg)

# 2. PCを組み立てる
ここは、各製品の説明書を見ながら色々ググりながらやればそこまで苦労しなかった（5時間くらいかかったが）のであまり書くことがない。インターネットは便利だ。
ただ、配線はなんか難しかった。何がSATAケーブルなのかとか見てもよくわかんないよね。結局は、だれにでも分かるように挿すピンの数が6個とか8個とか9個とかバラバラになってるのでそれを目安に挿していった。
なんやかんやで無事起動に成功。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ここまできた！hdmiケーブル挿すところがケースのカバーに干渉しててグッ！てしないとつかへんねんけど、引きちぎっていいかな <a href="https://t.co/1b1dHRYzNc">pic.twitter.com/1b1dHRYzNc</a></p>&mdash; nekoumei (@nekoumei) <a href="https://twitter.com/nekoumei/status/1084353682282442753?ref_src=twsrc%5Etfw">2019年1月13日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 3. Ubuntuを入れる
新しい方がええやろということで、Ubuntu 18.04 LTS を入れる。LiveUSBからいれた。
MacでのLiveUSBのつくりかたは[この記事](https://qiita.com/mzntaka0/items/f25707e4d837bd081db5)を参照した。
LiveUSBを刺してから起動して、BIOS画面で色々触ってたら、Ubuntuが立ち上がったのでInstallっぽいやつをダブルクリックして色々勧めていく。[詳細はググってほしい](https://www.google.com/search?client=ubuntu&channel=fs&q=ubuntu18.04+%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB&ie=utf-8&oe=utf-8)
ただ、ネットには古い情報も多く残っており、「バグが出るからやるな！」って書いてあることはとっくに修正済だったりするのであまり神経質にやらなくていいと思う。
30, 40分くらいかかった気がするけど、サードパーティのソフトウェアを入れるかどうかで大きく時間は変わる気がした。

# 4. セットアップ・準備
## 4.1. nVIDIAのドライバを入れる
なんか解像度がモニタとあってなくて、なんやこれと調べてたら、どうやらnVIDIAのドライバが必要らしいということがわかった。
ここでめちゃめちゃ詰まった。ググってもあんま情報出てこないしで困った。
[公式サイト](https://www.nvidia.co.jp/Download/index.aspx?lang=jp)のドライバを指示どおりダウンロードしてインストールしようとしても全然うまくいかなくて、色々ゴチャゴチャやってたら無限ループが起き出してどうしようもなくなったので一旦Ubuntuを入れ直した。
ここで、Blutoothキーボードしか持ってなくてBIOSに入れずAmazonで安い有線キーボードをポチるなどして、時間がかかってしまった。
最終的に、自分の場合は正解は[この記事](https://qiita.com/shino396/items/111c2496a360601b1d5a)だった。`build-essential` が必要とか公式に書いてなくない？なんにせよこれでなんとかドライバのインストールには成功した。
バージョンは下記のとおり。

| バージョン: | 410.93 |
|:--|:--|
| リリース日: | 2019.1.3 |
| オペレーティングシステム: | Linux 64-bit |
| 言語: | Japanese |
| ファイルサイズ: | 102.29 MB |

この時点で、なぜかCUDA10.0もはいったぽくて、良かった。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">やっと入った<br>これもうcudaもはいってんのかな？ <a href="https://t.co/7UE9jEiXfi">pic.twitter.com/7UE9jEiXfi</a></p>&mdash; nekoumei (@nekoumei) <a href="https://twitter.com/nekoumei/status/1084726357777502208?ref_src=twsrc%5Etfw">2019年1月14日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 4.3. 諸々のアップデート
[このサイト](https://linuxfan.info/ubuntu-18-04-basic-settings)がわかりやすくてよかった。
僕は最初の方の`sudo apt update` 、`sudo apt upgrade -y`でパッケージのアップグレードと言語設定のとこだけやった。
そうするとなぜかnVIDIAドライバが再びダメになってしまった。どうやら `sudo apt update`したあとドライバがダメになる現象があるらしい。
ただ、これはドライバをもっかい`sudo ./hoge.run`すると治ったので即解決した。
その他色々やった気がするが、重要なことではない。（たぶん）

## 4.2. Python環境整備
とりあえず[Anaconda](https://www.anaconda.com/download/#linux)と[PyTorch](https://pytorch.org/get-started/locally/)
Anacondaはダウンロードしたあと `bash Anacondahogehoge.sh`して`source .bashrc`すればおｋ。
途中でいろいろ出てくるのはちゃんと読んでyes/no判断すれば大丈夫。
pytorchはインストールかなりかんたんなので大丈夫だった。
`conda install pytorch torchvision cuda100 -c pytorch` するだけ。

# 5. MNISTの実行
あくまで今回はちゃんとGPUが使えるかの確認なので、MNISTを適当なネットワークでやってみた。
ソースコードはほぼPyTorchのチュートリアル。GPUを使う部分だけ抜き出すと、下記みたいになる。
ソース全文はGitHubにNotebookをあげておいたのでそちらを参照してください。
[ソース全文](https://github.com/nekoumei/pytorch-test/blob/master/gpu_test.ipynb)

```Python
net = Net()
net = net.to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

start = time.time()
for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # get the inputs
        inputs, labels = data
        inputs, labels = inputs.to(device), labels.to(device)

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 100 == 0:
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 100))
            running_loss = 0.0

print(f'Finished Training. Elapsed TIme is {time.time() - start}')
```
`net.to(device)`と、`inputs, labels = inputs.to(device), labels.to(device)`が、PyTorchでGPU使いたいときに必要なやつ。
`device`はPyTorchのTutorialにしたがい `device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')`で作っている。
思った以上にかんたんでよかった。
処理速度としては、CPUの場合150.4秒かかっていた計算がGPUだと5.9秒になった。すごい。

# おわりに
これで、色々自由に遊べるGPU環境が手に入ったのでよかった。
現状認識している課題として、キー配置問題がある。
UbuntuのSuperコマンドが嫌なのでCtrlと入れ替えたことで概ね満足なんだが、普段Macだと左Commandで日本語、右Commandで英語、ってやってるのが再現できなくて結構めんどくさい。誰かこれをUbuntuで再現する方法教えてください。
まあJupyter Notebook立ち上げでMacからアクセスする使い方が中心になりそうだからそこまで気にしてない。。。今は試しにUbuntuローカルで記事を書いてみたけど、やっぱ日本語英語切り替えがネックだなあ。
あとWi-Fiが遅い。MacやiPhoneだと調子良いと下り300Mbpsくらい出るんだけどこれはだいたい50-60Mbpsくらい。なのでパッケージのインストールとかgit cloneとかやたら時間かかるのが気になる。改善したい。これも誰かに助けてほしい。

本記事のような情報は、すぐ陳腐化してしまうことも多いけど、ディープラーニングのためにGPUマシンつくりたい！ってなった方の参考になれば幸いです。
ありがとうございました。

## 余談

買ったケースがクリアケースで、且つマザボもケースファンも光るタイプだったので「THE・オタク」みたいになってしまった。好き。
![IMG_2579.JPG](https://qiita-image-store.s3.amazonaws.com/0/203205/72a3c5f0-0ae7-9c14-c374-9d620d9c2d8e.jpeg)