うずまき2017 powered by Jun-Systems

耳管開放症, SAS, 統計解析, 人工知能, プログラミングそれに思考

*

続2・深層学習でirisの品種予測.ーパラメータによる予測性能の比較ー

   

続・ディープボルツマンマシンとかいうので遊んだからの続編です.(タイトル変えました)
今回はnn.train()での学習時のパラメータをいろいろ変えた時の結果の違いを一気に機械的に算出して比較します.

基本的な分析フローは前回のと同じなので,走らせたプログラムはもうまとめてここに貼っときます.データ整形後の#GeneralSettingsのところのパラメータをいじればそれに応じて動作が変わります.

###Data Format
library(deepnet)
dat<-iris[which(iris$Species != "virginica"),]
vars<-cbind(
  as.numeric(dat$Species)-1,
  dat$Sepal.Length,
  dat$Sepal.Width,
  dat$Petal.Length,
  dat$Petal.Width
)
n<-nrow(vars)

###GeneralSettings
niter<-100 #N of Iterations[i]
srate<-c(1:9)*0.1 #Sampling Rate[j]
nhidden<-c('c(10)','c(20)','c(10,3)','c(20,3)','c(10,6)','c(20,6)') #List of hidden layer[k]
actfun<-c("sigm","tanh") #List of ActivationFunction[m]

###Analysis
result.actfun<-array(NA,dim=c(length(srate),length(nhidden),length(actfun)))
for (m in 1:length(actfun)){
  result.hidden <- matrix(NA,ncol=length(nhidden),nrow=length(srate))
  for (k in 1:length(nhidden)){
    result.srate<-rep(NA,length(srate))
    for (j in 1:length(srate)){
      result.iter<-rep(NA,niter)
      for (i in 1:niter){ #loop_i
        sampled<-sample(n,(round(n*srate[j])),replace=F)
        dat.learn.y<-vars[sampled,1]
        dat.learn.x<-vars[sampled,-1]
        dat.pred.y<-vars[-sampled,1]
        dat.pred.x<-vars[-sampled,-1]
        
        nn<-nn.train(x=dat.learn.x,y=dat.learn.y, initW = NULL, initB = NULL,
                     hidden = eval(parse(text=paste(nhidden[k]))), activationfun = actfun[m],
                     learningrate = 0.8, momentum = 0.5, learningrate_scale = 1, output = "sigm",
                     numepochs = 3, batchsize = 100, hidden_dropout = 0, visible_dropout = 0)
        result.iter[i]<-nn.test(nn,x=dat.pred.x,y=dat.pred.y)
      } #loop_i
      result.srate[j]<-mean(result.iter)
    } #loop_j
    result.hidden[,k]<-result.srate
  } #loop_k
  result.actfun[,,m]<-result.hidden
} #loop_m

とりあえず結果を一覧で見ます.
RStudio
縦軸がホールドアウトサンプルのレートですね.学習に何割のデータを割り当てるかを指定してるので,下に行くほど学習の割合が大きくなります.
横軸は隠れ層(hidden layer)の数ですね.右に行くほど増えたり複雑化したりします.
三次元目は活性化関数(Activation Function)で,1枚目がsigm(シグモイド関数),2枚目がtanhで走らせた結果です.
そして各エラー率は100回ランダムサンプリングした結果の平均です.

これ見て思ったのは,サンプリングの割合変えてもエラー率はそう変わりませんね.大して変わらないので,見づらくて鬱陶しいので列ごとに平均とってまとめます.

result2<-matrix(NA,ncol=length(nhidden),nrow=length(actfun))
for (j in 1:length(actfun)){
  for (i in 1:length(nhidden)){
    result2[j,i]<-mean(result.actfun[,i,j])
  }
}
colnames(result2)<-nhidden
rownames(result2)<-actfun

RStudio
うん,見やすくなりました.
なかなか興味深いですねこれ.単純に隠れ層を増やせば結果が良くなるわけでもなく.

他のサンプルではどうなのか

今回はvirginicaを落としましたが,他のものを落とした予測モデルでも同じような結果なんでしょうか.試しました.
少しでも普遍的な性能が見たいですがデータ変えるのは面倒なのでとりあえずこれで.
今までやったことを3品種それぞれを順番に落として試行するので,そのまま走らせると32400回(100試行*9サンプリングレート*6隠れ層*2活性化関数*3品種)まわります.大したサンプル数じゃないので大丈夫だとは思いますが,PCのスペックにはお気をつけて.ちなみにぼくの環境ではMacBook Pro上のRStudioで1分かかりませんでした.

library(deepnet)

###Data Format
species<-c("setosa","versicolor","virginica")
result3<-array(NA,dim=c(length(actfun),length(nhidden),length(species)))
for (q in 1:length(species)){
    dat<-iris[which(iris$Species != species[q]),]
    vars<-cbind(
      as.numeric(dat$Species)-1,
      dat$Sepal.Length,
      dat$Sepal.Width,
      dat$Petal.Length,
      dat$Petal.Width
    )
    n<-nrow(vars)

    ###General Settings
    niter<-100 #N of Iterations[i]
    srate<-c(1:9)*0.1 #Sampling Rate[j]
    nhidden<-c('c(10)','c(20)','c(10,3)','c(20,3)','c(10,6)','c(20,6)') #List of hidden layer[k]
    actfun<-c("sigm","tanh") #List of ActivationFunction[m]
    
    result.actfun<-array(NA,dim=c(length(srate),length(nhidden),length(actfun)))
    for (m in 1:length(actfun)){
      result.hidden <- matrix(NA,ncol=length(nhidden),nrow=length(srate))
      for (k in 1:length(nhidden)){
        result.srate<-rep(NA,length(srate))
        for (j in 1:length(srate)){
          result.iter<-rep(NA,niter)
          for (i in 1:niter){ #loop_i
            sampled<-sample(n,(round(n*srate[j])),replace=F)
            dat.learn.y<-vars[sampled,1]
            dat.learn.x<-vars[sampled,-1]
            dat.pred.y<-vars[-sampled,1]
            dat.pred.x<-vars[-sampled,-1]
            
            nn<-nn.train(x=dat.learn.x,y=dat.learn.y, initW = NULL, initB = NULL,
                         hidden = eval(parse(text=paste(nhidden[k]))), activationfun = actfun[m],
                         learningrate = 0.8, momentum = 0.5, learningrate_scale = 1, output = "sigm",
                         numepochs = 3, batchsize = 100, hidden_dropout = 0, visible_dropout = 0)
            result.iter[i]<-nn.test(nn,x=dat.pred.x,y=dat.pred.y)
          } #loop_i
          result.srate[j]<-mean(result.iter)
        } #loop_j
        result.hidden[,k]<-result.srate
      } #loop_k
      result.actfun[,,m]<-result.hidden
    } #loop_m
    
    result2<-matrix(NA,ncol=length(nhidden),nrow=length(actfun))
    for (j in 1:length(actfun)){
      for (i in 1:length(nhidden)){
        result2[j,i]<-mean(result.actfun[,i,j])
      }
    }
    colnames(result2)<-nhidden
    rownames(result2)<-actfun
    result3[,,q]<-result2
}
dimnames(result3)<-list(
  actfun,
  nhidden,
  species
  )

んで結果が…
RStudio
予想通りバラつきますね.というのも,品種の組み合わせによってはお互いに似通っているものがあるので,エラー率がぐっとあがってきたんじゃないですかね.まあ同じ数の2品種の分類でエラー率50%だと全く使いものにならないような気がしますが…ぼくのチューニングが糞だったということにしておきましょう.

あと数回にわたって,もうちょっと発展的なことまでやっていくつもりですが,とりあえず今回はここまで.
 


 - 分析例 , , , ,

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

  関連記事