並列化できる評価関数があり、その調節パラメータを並列にグリッドサーチしたい。単純に考えると親のソケットクラスタから子クラスタを生成すると良いのかな、と思うがもっといい方法ないものか。
評価関数は例えば、randomForestのようなアンサンブル学習でも良いし、遺伝的アルゴリズムのような最適化でも良いし、LOOみたいなcross-validationを考えても良い。Rで簡単に書ける。
require(foreach) require(doParallel) eval_parallel <- function(){ # 親ソケットクラスタ cl <- makeCluster(8) registerDoParallel(cl) on.exit(stopCluster(cl)) # 子クラスタの格納用 cl_i <-NULL # grid searchの条件組み合わせを列挙しておく conditions <- expand.grid(a=1:3, b=letters[2:7], c=c(1.1,1.7,1.9)) foreach(i=1:NROW(conditions), .packages = c("foreach", "doParallel"), .combine = rbind) %dopar%{ # 子クラスタ cl_i[[i]] <- makeCluster(11) registerDoParallel(cl_i[[i]]) on.exit(stopCluster(cl_i[[i]])) # ハイパーパラメータのセット parameters <- conditions[i,] # iteration_sizeは弱学習器の数だったり、CVのfolding数だったり、GAの個体数だったり foreach(j=1:iteration_size, .combine = c) %dopar% { # do something } } } eval_parallel()
この例では親が8いて子が11づつ作られるので、8*(1+11)=96並列。親子のバランスはボトルネックを見て配分すればよい。ときどき親の割り当てぶんの確保を忘れる。
.combineがrbindとcになってるのは、このあとでrowMeansすれば平均精度を見てベストなパラメータセットを探せるcross-validationのイメージ。
on.exit()使ってるのは下記の記事から。
R の foreach で並列処理するとき on.exit() が便利 #rstatsj - Qiita
もうちょっとうまいやり方がありそうだけど、思いつかないので今はこれで凌いでいる。