R の MXNet で iris を分類
「MXNet で iris を分類」 と同様の処理を R言語で実装してみました。
ソースは http://github.com/fits/try_samples/tree/master/blog/20171212/
準備
今回は下記サイトの手順に従って MXNet R パッケージの CPU 版を Windows へインストールしました。
MXNet R パッケージの CPU 版を Windows へインストール
cran <- getOption("repos") cran["dmlc"] <- "https://apache-mxnet.s3-accelerate.dualstack.amazonaws.com/R/CRAN/" options(repos = cran) install.packages("mxnet")
インストールした mxnet のバージョンが少し古いようですが(現時点の MXNet 最新バージョンは 1.0)、今回はこれを使います。
バージョン確認
> packageVersion('mxnet') [1] ‘0.10.1’
学習と評価
MXNet には、階層型ニューラルネットワークの学習処理を簡単に実行するための関数 mx.mlp
が用意されているので、今回はこれを使います。
引数 | 備考 |
---|---|
hidden_node | 隠れ層のノード(ニューロン)数(デフォルトは 1) |
out_node | 出力ノード数(今回は分類数) |
num.round | 繰り返し回数(デフォルトは 10) |
array.batch.size | バッチサイズ(デフォルトは 128) |
learning.rate | 学習係数 |
activation | 活性化関数(デフォルトは tanh) |
hidden_node
にベクトル(例. c(6, 4)
)を設定すれば隠れ層が複数階層化されるようです。
iris のデータセットは R に用意されているものを使います。
mx.mlp の入力データには mx.io.DataIter か R の配列 / 行列を使う必要があるようなので(ラベルデータは配列のみ)、data.matrix
で行列化しています。
ラベルデータとする iris の種別 iris$Species
は因子型ですが、mxnet では因子型を扱えないようなので as.numeric
で数値化しています。
ここで as.numeric の結果は 1 ~ 3 の数値になりますが、mxnet で 3種類の分類を行うには 0 ~ 2 でなければならないようなので -1 しています。
一方、predict
の結果を max.col(t(<predictの結果>))
で処理すると 1 ~ 3 の数値になるため、評価用のラベルデータは -1 せずに正解率の算出に使っています。
また、array.layout = 'rowmajor'
は Warning message 抑制のために設定しています。
iris_hnn.R
library(mxnet) train_size = 0.7 n = nrow(iris) # 1 ~ n から無作為に n * train_size 個を抽出 perm = sample(n, size = round(n * train_size)) # 学習用データ train <- iris[perm, ] # 評価用データ test <-iris[-perm, ] # 学習用入力データ train.x <- data.matrix(train[1:4]) # 学習用ラベルデータ(0 ~ 2) train.y <- as.numeric(train$Species) - 1 # 評価用入力データ test.x <- data.matrix(test[1:4]) # 評価用ラベルデータ(1 ~ 3) test.y <- as.numeric(test$Species) mx.set.seed(0) # 学習 model <- mx.mlp(train.x, train.y, hidden_node = 5, out_node = 3, num.round = 100, learning.rate = 0.1, array.batch.size = 10, activation = 'relu', array.layout = 'rowmajor', eval.metric = mx.metric.accuracy) # 評価 pred <- predict(model, test.x, array.layout = 'rowmajor') # 評価用データの分類結果(1 ~ 3) pred.y <- max.col(t(pred)) # 評価データの正解率を算出 acc <- sum(pred.y == test.y) / length(pred.y) print(acc)
実行結果は以下の通り。
実行結果
・・・ > model <- mx.mlp(train.x, train.y, + hidden_node = 5, + out_node = 3, + num.round = 100, + learning.rate = 0.1, + array.batch.size = 10, + activation = 'relu', + array.layout = 'rowmajor', + eval.metric = mx.metric.accuracy) Start training with 1 devices [1] Train-accuracy=0.32 [2] Train-accuracy=0.281818181818182 ・・・ [99] Train-accuracy=0.954545454545455 [100] Train-accuracy=0.954545454545455 ・・・ > print(acc) [1] 0.9555556
備考
predict
の実行結果は以下のような内容となっています。
> pred [,1] [,2] [,3] [,4] [1,] 0.968931615 0.968931615 0.968931615 0.968931615 [2,] 0.029328469 0.029328469 0.029328469 0.029328469 [3,] 0.001739914 0.001739914 0.001739914 0.001739914 [,5] [,6] [,7] [,8] [1,] 0.968931615 0.968931615 0.968931615 0.968931615 [2,] 0.029328469 0.029328469 0.029328469 0.029328469 [3,] 0.001739914 0.001739914 0.001739914 0.001739914 ・・・ [,41] [,42] [,43] [,44] [1,] 1.762393e-08 7.670556e-06 5.799695e-06 9.349569e-12 [2,] 3.053433e-02 2.679898e-01 1.714197e-01 7.250102e-05 [3,] 9.694657e-01 7.320026e-01 8.285745e-01 9.999275e-01 [,45] [1,] 4.420018e-08 [2,] 8.569881e-03 [3,] 9.914301e-01
1 ~ 3 の中で最も数値の高いものが分類結果となりますので、上記を t
で転置して max.col
すると以下のようになります。
> max.col(t(pred)) [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 3 2 2 2 2 2 [30] 3 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3