h2o(H2O のR用インターフェース)をつかってみる
※ つかってみるだけであって、以下のような状況に最適なツールだといっているわけではない
※ そもそも画像認識の知識がない
環境準備
データ準備
- 学習用、テスト用データを用意する(画像:全てガールズ&パンツァー公式サイトより)
顔範囲の認識は今回は手動でいい加減に行う - GIMPでリサイズ(今回は 90×90 ピクセル)し、RAWデータとしてエクスポートする
- bincsvでRAWデータをCSVに書き出す(10進数にする)
- このツールでは出力にシングルクオテーションが混じるようなので置換で取り除いておく
学習
- R で各CSVを読み込んでグレースケール化し 8100 次元のベクトルにする(参考文献1)
- 事前知識としてグレースケールの手書き数字の分類を知っているくらいでカラー画像の取り扱いを知らないため
- グレースケール化せずにRGBの3倍の長さのベクトルにしてみても結果に大して変わりはなかった
- h2o.deeplearning に学習用データを渡し分類器を学習させ、テスト用データの判定をみる(参考文献2)
結果
テストデータ | |||||
---|---|---|---|---|---|
正解 | anzu | maho | miho | saori | yukari |
分類器による判定 | anzu | maho | yukari | saori | yukari |
設定によっても正誤は変わるが、下のコードで多少試した範囲では、全員合うケース、みほが正しく判定されるケースはなかった
この少なすぎるデータ数でどうもこうもないけどみほのテストデータの何かが他のキャラっぽいのか
確率分布がどの活性化関数にしてもほぼ 1 or 0 だった
コード
library("h2o", lib.loc="C:/banana/libs") # 普通のインストールが上手くいかなかったので .zip からここにインストール GetVectorFromCsv <- function(csv.path) { # bincsv の出力ファイルに # が含まれるのでコメント文字を何か別の文字に回避 x <- read.table(csv.path, header=T, skip=1, sep=",", comment.char="%") # h03, h07, h0B, h0F 列は透明度なので使用しない vec.r <- as.vector(t(x[,c("h00", "h04", "h08", "h0C")])) vec.g <- as.vector(t(x[,c("h01", "h05", "h09", "h0D")])) vec.b <- as.vector(t(x[,c("h02", "h06", "h0A", "h0E")])) vec <- 2.0 * vec.r + 4.0 * vec.g + vec.b # グレースケール化 (NTSC 参考文献参照) # vec <- c(vec.r, vec.g, vec.b) # グレースケール化せずRGBのベクトルを全て使用 return(vec) } # データ読み込み data <- NULL characters <- c("anzu", "maho", "miho", "saori", "yukari") for (character in characters) { for (i.img in 1:4) { csv.path <- paste0("img/", character, i.img, ".csv") vec <- GetVectorFromCsv(csv.path) data <- rbind(data, vec) } } data <- as.data.frame(data) dim.input <- ncol(data) data$label <- rep(characters, each=4) # 学習用データとテスト用データにふり分け test.index <- seq(4, 20, by=4) train.data <- data[-test.index,] test.data <- data[test.index,] # テスト用データにゆきぽを追加する場合 vec <- GetVectorFromCsv("img/yukiho.csv") test.data[nrow(test.data)+1,] <- c(vec, "yukiho") # 学習(ほとんど参考文献と同じ) write.csv(train.data, file="train.csv", row.names=FALSE, quote=FALSE) write.csv(test.data, file="test.csv", row.names=FALSE, quote=FALSE) localH2O <- h2o.init(ip="localhost", port=54321, startH2O=TRUE, nthreads=-1) train.data <- h2o.importFile(path="train.csv") test.data <- h2o.importFile(path="test.csv") result <- h2o.deeplearning(x=1:dim.input, y=dim.input + 1, training_frame=train.data, activation="Tanh", # "Maxout" "RectifierWithDropout" # 適当 hidden=c(100, 100), # 適当 epochs=200) # 適当 predict <- h2o.predict(object=result, newdata=test.data[,-(dim.input + 1)]) predict <- as.data.frame(predict)