Splunk DLTK : Pytorch + CUDAのサンプルコードを実行してみる


# はじめに

Splunk DLTKのサンプルコードを実行してみるシリーズです。
今回は Pytorch + CUDAのサンプルコードを実行しながら使い方について勉強してみたいと思います。
ただし、私の環境ではGPUは利用できないのでコードを眺めながらも実際はCPUで実行しております（いつの日かGPU環境を使って試してみたいなー）

**Pytorchとは?**
Facebookが開発を主導した機械学習ライブラリで、他のライブラリと比べて以下のような特徴があります。
1. 直感的にコードを書ける
2. 参照リソースが豊富
3. define by run (動的フレームワーク。データを流しながら計算グラフを構築してくれる）
4. device(CPU/GPU) の切替えが簡単にできる

4番の特徴のおかげで、今回のコードも簡単にCPU / GPUで実行&切替が可能になります。

**CUDAとは?**
NVIDIAが提供しているGPU向けのプログラミングモデルで、コンパイラーやライブラリを提供してます。
https://ja.wikipedia.org/wiki/CUDA

これらのライブラリーを使うことでデータをGPU上に送って計算することができるようになります。PytorchからこのCUDAのライブラリーを呼び出すことで、GPU上で機械学習ができるようになります。

# サンプルコードを見てみる

それでは、早速DLTKのサンプルコードを見てみたいと思います。ノートブックには以下の２つが用意されてます。
- pytorch_logistic_regression.ipynb
- pytorch_nn.ipynb

今回は２つ目の pytorch_nn.ipynb をチェックしてみたいと思います。

最初はライブラリーのインポートです。まだ CUDAに関してはtorchに含まれております。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/946cd4c1-dcfd-418d-b59f-c4ac9c1243ff.png)


### Stage1: データ取り込み

Splunk DLTKではデータ取り込みは Splunkから行います。そのためSplunk側でSPLを実行して取り込むデータをコンテナに送ってあげます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/201374c9-c1de-7c2c-8fdb-efca59740cc5.png)

下の図はSplunk側での実行画面です。今回は irisのデータセットを使ってますね。ちなみに irisのデータセットはSplunkのMLTKに最初から入っているので、このまま利用できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/3cad5306-4f65-e469-7554-885166951c49.png)

### Stage2: 初期化

次に学習前の初期化を行います。少し量が多いので少しずつ解説していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/d2e083c7-8c44-3420-2094-129884bd4398.png)

最初に先ほど取り込んだデータから目的変数(Y)と説明変数(X)を代入します。またデータサイズとクラスの数を同じくデータから計算して代入します。NNで利用する学習率を指定して、YのSpeciesの種類を数字に変換するためにマッピングを作ります。

次にNNモデルのパラメータをここでセットします。

次にGPUが利用できる場合、device変数に "cuda"をセットします。なければ "cpu" になります。コードを書き直さなくても利用できるようになってますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/97fbf2c1-ee21-f8e7-1898-95e78767ba84.png)

先ほどの続きです。Splunk側でオプションが指定されているかチェックします。指定できるオプションは "epochs", "batch_size", "hidden_layers" の３つのようです。必要に応じてこちらを編集すればオプションを追加できます。

次にメインである、NNモデルを作成して、インスタンスを立ち上げます。nn.Linearは全結合層になります。nn.ReLUは活性化関数になります。最後に to(model['device']) で学習するデバイスを指定しているのがポイントです。

最後に損失関数(loss)や 最適化(Optimizer)を指定します。この辺りはNNの範囲です。



これで初期化は終了です。

### Stage2: 学習(Fit) 

学習ステージも少し長いのですが、前半は先ほどの初期化と同じ内容です。（両方に記載する理由はわかってません・・・）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/8203b584-1eb8-28eb-7dd6-d8f82ee48cb2.png)

真ん中あたりに、inputs, targets にデータを代入しておりますが、その際にデバイス指定しております。この辺もCUDA連携のポイントです。

後半の for文の中で NNを実行します。model.step()の箇所ですね。

最後に epochs, batch_size, loss値 をリターンします。 

### Stage3: 適用(Apply) 

次に適用ステージ設定です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/8feb1b81-f613-b7e4-0787-6f43c07414f2.png)

取得したデータをXに代入して、学習時に作ったモデルから目的変数の種類と番号をclassesに代入します。

inputを設定されたデバイス(CPU or GPU)に入れて、学習済みのモデルに適用します。softmax法と同じく一番予想が高いクラスをpredicted に代入します。 .cpu()というのは CPUで計算すると指定しております。

最後に予測値が数字で表現されているので、マッピングされるspeciesの値に変換してリターンします。


### その他ステージ

残りはこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/40be2bd4-e3ef-c2ba-b34f-0c24af9d3961.png)


# Splunkから実行してみる

fitで学習モデルを作ります。リターンはApplyの結果が返ってきますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/f22bd869-4600-8c81-96b5-59a348a01176.png)

applyも同じ結果です。（同じデータを使っているため）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/2afe7942-5d09-6608-f8cb-50cba6c55464.png)

# サンプルダッシュボード

Splunk DLTKにはサンプルダッシュボードが用意されております。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/dbabbcf2-cb66-4782-c60a-ffdcbd9e5911.png)

Epoch数をあげると精度が上がっていきます。今回はGPUがないため100回で実行した結果のため低くなっておりました。

# 最後に

本来ならGPUを使って、学習時間の比較をしたかったですが、これは今度にしたいと思います。
コードがそのまま再利用できるのはうれしいです😊