Keras for R
RstudioがR上でKerasによるディープラーニングのモデルを構築するためのライブラリ{keras}を公開した。
以前から{tensorflow}を使えばtensorflow::import(module = "keras")でKerasを導入することができたようだが、{keras}を先にインストールすることでpythonさえ入っていればtensorflowのインストールもできるらしい。随分と楽にtensorflowを動かせることができそうなので早速試してみた。なお類似のプロジェクトがRstudio以外でも行われているようで、以下でもKerasをRから動かすためのライブラリを提供している。
実行環境はAWS上のWindowsマシン。Rのバージョンは3.3.2だけれど、Microsoft R Clientがインストールされている。
実行したスクリプトは上で紹介したページの内容なのだけれど、サンプルデータであるx_trainやx_testなどは自前で用意する必要があったのでirisを使って適当に作成した。なおこちらのページはKerasの公式ドキュメントをR用に書き換えただけの様子。
{Keras}のインストール
早速{keras}のインストールとtensorflowのインストールを実行してみる。なお私の環境では{keras}のインストールの際に{reticulate}が一緒に入らず、{keras}のインストールに失敗したため{reticulate}だけ先にインストールしている。
## library install & load devtools::install_github("rstudio/reticulate") devtools::install_github("rstudio/keras") library(keras) library(dplyr) # for data handling ## install tensorflow install_tensorflow() Error: Installing TensorFlow requires a 64-bit version of Python 3.5 Please install 64-bit Python 3.5 to continue, supported versions include: - Anaconda Python (Recommended): https://www.continuum.io/downloads#windows - Python Software Foundation : https://www.python.org/downloads/release/python-353/ Note that if you install from Python Software Foundation you must install exactly Python 3.5 (as opposed to 3.6 or higher).
{keras}のインストールがうまくいけばinstall_tensorflow()という関数一つでtensorflowをインストールすることができる。とはいえpythonのインストールまではやってくれないようで私の環境ではエラーが出てしまった。指示に従い、Anaconda経由でpythonをインストールする。なお現時点でのpythonのバージョンは3.6だった。
Anacondaのインストールが済んだので再度tensorflowのインストールを試してみる。
## install tensorflow install_tensorflow()
今度はうまくいった。
サンプルデータの作成
サンプルスクリプトでは分析用のデータが提供されていなかったため、irisを使ってサンプルデータを作成する。特別なことはしておらず、sampleによって乱数を振った上で学習用とテスト用にデータを分割した。なおデータはmatrixにする必要がある。
set.seed(123) learn_id <- sample(1:nrow(iris), 100, replace = FALSE) train_data <- iris %>% filter(row.names(.) %in% learn_id) test_data <- iris %>% filter(!row.names(.) %in% learn_id) ## training data x_train <- train_data %>% select(-Species) %>% as.matrix() y_train <- as.matrix(model.matrix(~ train_data$Species - 1)) ## test data x_test <- test_data %>% select(-Species) %>% as.matrix() y_test <- as.matrix(model.matrix(~ test_data$Species - 1))
Kerasによるmodelオブジェクトの生成
サンプルデータが出来上がったので、{keras}によるフィッティングを行う。まずはmodelオブジェクトの生成から。
## generate model object model <- keras_model_sequential() > Model Model _______________________________________________________________________________ Layer (type) Output Shape Param # =============================================================================== Total params: 0 Trainable params: 0 Non-trainable params: 0 _______________________________________________________________________________
入力層 → 隠れ層 → 出力層という簡単なニューラルネットワークを構築する。layer_denseで簡単にレイヤーを積み上げることができるようで、入力層のみinput_shapeを指定する必要がある。これはpython上でKerasを実行する際のmodel.addに相当するものと思われる。
model %>% layer_dense(units = 10, input_shape = 4) %>% # Output & Input dimension layer_activation(activation = 'relu') %>% layer_dense(units = 3) %>% layer_activation(activation = 'softmax') > model Model _______________________________________________________________________________ Layer (type) Output Shape Param # =============================================================================== dense_3 (Dense) (None, 10) 50 _______________________________________________________________________________ activation_3 (Activation) (None, 10) 0 _______________________________________________________________________________ dense_4 (Dense) (None, 3) 33 _______________________________________________________________________________ activation_4 (Activation) (None, 3) 0 =============================================================================== Total params: 83.0 Trainable params: 83.0 Non-trainable params: 0.0 _______________________________________________________________________________
パラメータの数は層ごとに(入力データの次元数+1) * 出力データの次元で決まる。+1は切片。
ここで出来上がったmodelオブジェクトの属性や構造などを見てみようとstrを実行してみたのだが、print(model)と結果は変わらなかった。やはりR的なオブジェクトではない様子。
ニューラルネットワークの構造が決まれば、最適化の際の条件を指定する。
## model parameter model %>% compile( loss = 'categorical_crossentropy', optimizer = optimizer_sgd(lr = 0.02), metrics = c('accuracy'))
フィッティング
以上で準備が整ったため、フィッティングを行う。
## fitting model %>% fit(x_train, y_train, epochs = 1000, batch_size = 32) ## 省略 # Epoch 990/1000 # 100/100 [==============================] - 0s - loss: 0.0432 - acc: 0.9800 # Epoch 991/1000 # 100/100 [==============================] - 0s - loss: 0.0442 - acc: 0.9800 # Epoch 992/1000 # 100/100 [==============================] - 0s - loss: 0.0455 - acc: 0.9800 # Epoch 993/1000 # 100/100 [==============================] - 0s - loss: 0.0508 - acc: 0.9800 # Epoch 994/1000 # 100/100 [==============================] - 0s - loss: 0.0602 - acc: 0.9800 # Epoch 995/1000 # 100/100 [==============================] - 0s - loss: 0.0437 - acc: 0.9800 # Epoch 996/1000 # 100/100 [==============================] - 0s - loss: 0.0433 - acc: 0.9800 # Epoch 997/1000 # 100/100 [==============================] - 0s - loss: 0.0432 - acc: 0.9800 # Epoch 998/1000 # 100/100 [==============================] - 0s - loss: 0.1129 - acc: 0.9600 # Epoch 999/1000 # 100/100 [==============================] - 0s - loss: 0.0529 - acc: 0.9700 # Epoch 1000/1000 # 100/100 [==============================] - 0s - loss: 0.0647 - acc: 0.9600
サンプルデータがものの100行程度しかないため一瞬で終わる。Accuracyが0.96とまずまず。続いてこちらのモデルを用いて、テストデータに対する精度評価を実行する。
## test loss_and_metrics <- model %>% evaluate(x_test, y_test, batch_size = 128) > loss_and_metrics [[1]] [1] 0.1853937 [[2]] [1] 0.96
テストデータに対しても精度が0.96と高く、過学習を起こしている様子はない。
テストデータに対するラベルの予測は以下のように実行する。
## predict classes <- model %>% predict(x_test, batch_size = 128) > classes [,1] [,2] [,3] [1,] 9.983064e-01 1.693639e-03 6.461022e-20 [2,] 9.971897e-01 2.810343e-03 7.951551e-19 [3,] 9.983315e-01 1.668578e-03 3.816257e-20 [4,] 9.984826e-01 1.517428e-03 4.521292e-20 [5,] 9.994913e-01 5.087039e-04 3.988174e-23 ## 省略
サンプルスクリプトは以上である。
注意点として、パイプ演算子(%>%)が使えるからといってdplyrが読み込まれている訳ではないので、データ加工を行うのであれば別途読み込む必要がある。
Rでディープラーニングを簡単に実行できる環境が整ってきているので、これを機会にRユーザーが増えると良いな。