統計コンサルの議事メモ

統計や機械学習の話題を中心に、思うがままに

Keras for R

RstudioがR上でKerasによるディープラーニングのモデルを構築するためのライブラリ{keras}を公開した。

R Interface to Keras • keras

以前から{tensorflow}を使えばtensorflow::import(module = "keras")でKerasを導入することができたようだが、{keras}を先にインストールすることでpythonさえ入っていればtensorflowのインストールもできるらしい。随分と楽にtensorflowを動かせることができそうなので早速試してみた。なお類似のプロジェクトがRstudio以外でも行われているようで、以下でもKerasをRから動かすためのライブラリを提供している。

github.com


実行環境はAWS上のWindowsマシン。Rのバージョンは3.3.2だけれど、Microsoft R Clientがインストールされている。

実行したスクリプトは上で紹介したページの内容なのだけれど、サンプルデータであるx_trainやx_testなどは自前で用意する必要があったのでirisを使って適当に作成した。なおこちらのページはKerasの公式ドキュメントをR用に書き換えただけの様子。

Keras Documentation

{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ユーザーが増えると良いな。