そういえばMNISTコンペが気が付いたらまた1年延長されたみたいですが。
これ以上順位上げるのは面倒で仕方ないのでほっといて、もうちょっと自分の勉強しようかと思います。今気になってるのが、隠れ層における特徴量の表現状態。どちらかというとConvNetの利点として紹介されることが多いのですが、Deep Belief Networkたる{h2o}にもh2o.deepfeaturesという関数があってやはり隠れ層における表現を抽出してくることができます。
で、その関数の概要をヘルプで見るとこんなことが書いてあります。
Feature Generation via H2O Deep Learning Model
Description
Extract the non-linear features from a H2O dataset using a H2O deep learning model.
Usage
h2o.deepfeatures(data, model, key = "", layer = -1)
Arguments
data
An H2OParsedData object.model
An H2ODeepLearningModel object that represents the deeplearning model to be used for feature extraction.key
(Optional) The unique hex key assigned to the resulting dataset. If none is given, a key will automatically be generated.layer
(Optional) Index of the hidden layer to extract. If none is given, the last hidden layer is chosen.)Value
Returns an H2OParsedData object with as many features as the number of units in the hidden layer of specified index. If the model is supervised, and the data object has a column of the same name as the response with which the model was trained, then the response column will be prepended to the output frame.
See Also
H2OParsedData, H2ODeepLearningModel, h2o.deeplearning
Examples
library(h2o) localH2O = h2o.init() prosPath = system.file("extdata", "prostate.csv", package = "h2o") prostate.hex = h2o.importFile(localH2O, path = prosPath) prostate.dl = h2o.deeplearning(x = 3:9, y = 2, data = prostate.hex, hidden = c(100, 200), epochs = 5) prostate.deepfeatures_layer1 = h2o.deepfeatures(prostate.hex, prostate.dl, layer = 1) prostate.deepfeatures_layer2 = h2o.deepfeatures(prostate.hex, prostate.dl, layer = 2) head(prostate.deepfeatures_layer1) head(prostate.deepfeatures_layer2)
ちなみに同一H2Oインスタンスから生成されたparsed data / model同士でないとh2o.deepfeatures関数自体が走らないので要注意*1。その都度フレッシュなh2o.deeplearning関数が推定したモデルを使って、特徴量を抽出する必要があります。
で、使い方を調べようと思ったんですがH2O World Trainingを見ても特に記述がない。。。orz
http://learn.h2o.ai/content/hands-on_training/deep_learning.html
ということで、適当に触ってみます。まずはフレッシュなh2o.deeplearning推定モデルを作ります。train.csvはKaggle MNISTコンペのデータとして、以下のように手早くモデルを推定します。
> library(h2o) > localH2O <- h2o.init(ip = "localhost", port = 54321, startH2O = TRUE, nthreads=7) > trData<-h2o.importFile(localH2O,path="data/train_noheader.csv") > res.dl <- h2o.deeplearning(x = 2:785, y = 1, data = trData, activation = "RectifierWithDropout", hidden=c(1024,1024,2048),epochs = 10, adaptive_rate = FALSE, rate=0.01, rate_annealing = 1.0e-6, rate_decay = 1.0, momentum_start = 0.5,momentum_ramp = 42000*0.6, momentum_stable = 0.99, input_dropout_ratio = 0.2, l1 = 1.0e-5,l2 = 0.0,max_w2 = 15.0, initial_weight_distribution = "Normal",initial_weight_scale = 0.01,nesterov_accelerated_gradient = T, loss = "CrossEntropy", fast_mode = T, diagnostics = T, ignore_const_cols = T, force_load_balance = T, autoencoder = F) > res_layer1<-h2o.deepfeatures(trData,res.dl,layer=1) > res_layer2<-h2o.deepfeatures(trData,res.dl,layer=2) > res_layer3<-h2o.deepfeatures(trData,res.dl,layer=3)
epochs = 10なのでかなり粗いモデルですが、それでも正答率は0.97014と言うほど悪くもないです*2。で、deepfeaturesを描画してみたらどうなるんでしょうか? Web上には↓↓こんな例があるようですが。。。
これに従ってちょろちょろimage関数を使って描画してみたらこんなのできました。
> train<-read.delim('train.csv',header=T,sep=',') > idx<-which(as.matrix(res_layer1$label)[1:100]==4) # 「4」を例にとる > par(mfrow=c(5,4)) > for (i in 1:5){ + image(t(apply(matrix(as.vector(as.matrix(train[idx[i],-1])),ncol=28,nrow=28,byrow=T),2,rev)),col=grey(seq(0,1,length.out=256))) + image(t(apply(matrix(as.vector(as.matrix(res_layer1[idx[i],-1])),ncol=32,nrow=32,byrow=T),2,rev)),col=grey(seq(0,1,length.out=256))) + image(t(apply(matrix(as.vector(as.matrix(res_layer2[idx[i],-1])),ncol=32,nrow=32,byrow=T),2,rev)),col=grey(seq(0,1,length.out=256))) + image(t(apply(matrix(as.vector(as.matrix(res_layer3[idx[i],-1])),ncol=64,nrow=32,byrow=T),2,rev)),col=grey(seq(0,1,length.out=256))) + }
訳分からんorz これ、よくよく考えたら「分類モデル側のカラムの並びが学習データ側のカラムの並びと一致するとは限らない」ので、本当は並べ替えなきゃいけないんですよね。。。同様に「3」「9」でやってみるとこうなります。
やっぱり見ていてもよく分からないorz 教えて、えらい人!