KubeflowのNotebook Serverを使って機械学習モデルを開発

# はじめに

本記事では、KubeflowのNotebook Serverを使って、Tensorflowによる機械学習モデルの開発を試します。また、クラスタ内の空いているGPUが自動的に割り当てられるか確認します。
Kubeflowの導入手順は[こちらの記事](https://qiita.com/shingonagai/items/fee5105613bb83dcaf3f)をご参照下さい。

# 目次

1. [検証環境](#検証環境)
1. [前提条件](#前提条件)
1. [Notebook Serverの起動](#notebook-serverの起動)
1. [Notebookでのモデル開発](#notebookでのモデル開発)
1. [まとめ](#まとめ)
1. [参考文献](#参考文献)

# 検証環境

以下のKubeflowがデプロイされたKubernetesクラスタにおいて、Notebook Serverを起動します。
![k8s-env.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1936643/63351ab9-8f9b-a4bd-130c-2cd01413d4e7.png)

# 前提条件

以下の作業が完了していることを想定しています。

- Kubernetesクラスタが構築済み
- Kubeflowがデプロイ済み

# Notebook Serverの起動

ブラウザでKubeflowのGUIへログイン後、左側メニューの**Notebook**を選択し、右上の**New Notebook**ボタンをクリック
![notebook-menu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1936643/f1fab1ee-6c3b-09b7-345d-004438d874b0.png)

New notebookの項目に入力して、**LAUNCH**ボタンでNotebook Server起動します。
- Name: Notebook Serverの名前
- Docker Image: イメージを選択するか、カスタムイメージの取得先を入力
- CPU/RAM: 必要なリソースを指定
- GPUｓ: 必要なGPU数とVendorを指定
- Workspace Volume: 必要なVolume容量を指定
![notebook-launch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1936643/703fbf23-a164-36ed-25f2-822d37d4866c.png)

正常に起動したか確認します。 (緑のチェックがついたら正常に起動しています)
![notebook-launched.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1936643/397f821b-2d18-5e39-1fb7-b83e45c4f238.png)

(*) Notebook Serverが起動したら、GPU使用状況確認のため、同様にもう1つ別のServerも起動してみます。

# Notebookでのモデル開発

Notebooks画面で、起動済みのServerの**CONNECT**をクリックします。
![notebook-connect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1936643/3dfc53c8-734e-9c64-60f2-e294af9feb61.png)

Notebookを開き、コードを入力して実行します。 (動作確認用に、簡単なNeural Networkの学習を実行します)

必要なライブラリをimportします。
```example.ipynb
import tensorflow
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, InputLayer
from tensorflow.keras.optimizers import RMSprop
```
MNISTのデータセットを読み込み、前処理を実行します。
```example.ipynb
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train  = x_train.reshape(60000, 784)
x_test   = x_test.reshape(10000, 784)
x_train  = x_train.astype('float32')
x_test   = x_test.astype('float32')
x_train /= 255
x_test  /= 255
y_train  = tensorflow.keras.utils.to_categorical(y_train, 10)
y_test   = tensorflow.keras.utils.to_categorical(y_test, 10)
```
Neural Networkによる学習を実行します。
```example.ipynb
model = Sequential()
model.add(InputLayer(input_shape=(784,)))
model.add(Dense(10, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
epochs = 20
batch_size = 128
history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(x_test, y_test))
```
(*) 2つ起動しているNotebook Server、それぞれに対して、connectし、notebookでこの学習のコードを実行したところ、クラスタ内の2つノード上でGPUが使用されていることが確認できました。

精度結果を表示します。
```example.ipynb
score = model.evaluate(x_test, y_test, verbose=1)
print()
print('Test loss:', score[0])
print('Test accuracy:', score[1])
```

# まとめ

今回はKubeflowのNotebook Serverを使って、Tensorflowによるモデル開発を行いました。クラスタ内の2ノードそれぞれに搭載されているGPUがサーバ起動時に自動で割り当てられ、学習や推論時にGPUが使用されていることが確認できました。

# 参考文献
- [Using Jupyter notebooks in Kubeflow](https://v0-7.kubeflow.org/docs/notebooks/)