ディープラーニングが当たり前の技術になりつつある昨今ですが、
未だにディープラーニングを動かしてみたことのない私です。
一回は触っておかないといけないなと思いつつも、
触るだけのモチベーションで、環境整えるのも面倒でしょ?
と言い訳して避けてきました。
ところが、今ではパッケージも充実していて、
keras というパッケージを使うと、
本当に簡単にディープラーニングに触れたので、
その簡単な利用方法をまとめておきます。
ディープラーニングとは
まずは、ディープラーニングの簡単なイメージをおさらいしておきます。
ディープラーニングはザックリいうと、
入力と出力の対応を下の図のような形で学習するものです。
丸は一つの数値を表していて、
青丸は入力の特徴を数値として並べたものです。
数値は張られた線に沿って順に計算されていきますが、
どのような計算をするかは、線に割り当てられた重みによって変化します。
この線の重みを調整することで入力と出力の関係が変わるので、
望んだ通りの入力と出力の関係が得られるように、
重みを変更していくことが学習に相当します。
図では、線の数を端折って書いているのですが、
実際には非常に多くの線があり、
重みの絶妙な調整で、実に様々な入出力の関係を表現できます。
また、中間層を増やすことで、線の数を増やすことができ、
ほとんどどのような対応関係も表現することができます。
この柔軟な表現能力がディープラーニングの魅力ではありますが、
一方で、柔軟過ぎるがゆえに、
望み通りの入出力の関係を取り出すのに苦労することもあります。
上のようなディープラーニングのモデルを素直に記述していくと、
非常に多くの変数で煩雑になりかねませんが、
昨今のライブラリを使うと、
非常に簡単にモデルを記述することができるようになっています。
準備
Rを起動する前に、まずは、必要なライブラリをインストールしておきます。
sudo apt install python-pip sudo apt install python-virtualenv
keras のインストール
R 上で、keras をインストールします。
devtools::install_github("rstudio/keras") library(keras) install_keras()
これで、kerasのインストールが完了します。
実行手順
準備が整ったので、いよいよディープラーニングの実行です。
実行の手順は、
- データの準備
- モデルの準備
- モデルのフィッティング
- モデルの活用
のような流れになります。
1. データの準備
入力と出力の関係を覚えさせるためのデータを与えます。
入力と出力はどちらも同じ形式で、
一つのデータを行に並べた行列で与えます。
属性1 属性2 属性3 データ1 データ2 ・・・ データ3
このとき、入力と出力で、
同じ行のものが対応する入力と出力になるようにデータを用意します。
下では、二種類の二次元正規分布からデータを生成しています。
前半500個が(1,1)を中心とした正規分布、
後半500個が(-1,-1)を中心をした正規分布から生成されたデータです。
x = t(sapply(1:1000,function(i){ if(i <500){ rnorm(2,1) }else{ rnorm(2,-1) } })) y = c(rep(1,500),rep(0,500)) y = to_categorical(y,2) plot(x[,1],x[,2],col=y+2)
y は前半500個に1、後半500個に0のラベルを貼っていますが、
to_categorical
を使って、(1,0)と(0,1)の2次元の数値に変換しています。
2. モデルの準備
keras では、モデルの生成が非常に簡単です。
各層を順番に繋げていくという直観的な記述方法が使えます。
下では、中間層が2つのモデルを生成しています。
model = keras_model_sequential() model %>% layer_dense(units=16,activation="relu",input_shape = c(dim(x)[2])) %>% layer_dropout(rate=0.4) %>% layer_dense(units=8,activation="relu") %>% layer_dropout(rate=0.3) %>% layer_dense(units=2,activation = "softmax")
layer_dense
が一つの層を表していて、units
が層の中のノード数を表しています。
activation
は活性化関数と呼ばれるもので、一つ一つのノードで行う計算方法を決めています。
input_shape
は入力としてはいってくるデータの次元を指定します。
layer_dropout
はドロップアウトを設定するもので、
学習時に一定の割合で学習を抑えることで、
過学習と呼ばれるディープラーニングの問題を回避するためのものです。
モデルを記述したら、そのモデルをコンパイルしておきます。
model %>% compile( loss = "categorical_crossentropy", optimizer = optimizer_rmsprop(), metrics = c("accuracy") )
これで、モデルの準備が完了です。
3. モデルのフィッティング
このままでは、モデルの中の線の重みが定まっていない真っ新なモデルになっているので、
ここにデータを投入して、入出力の対応を覚えさせていきます。
モデルのフィッティングも非常に簡単で、
用意した入力データと出力データx,y
をそのままfit
関数に投入するだけです。
model %>% fit(x,y, epochs = 100,batch_size = 100,validation_split = 0.2)
重みの学習は段階的に行うので、
同じデータであっても複数回入力して学習することが効果的な場合があります。
epochs
は全データを使って学習を繰り返す回数を表しています。
一回の学習の中でも、データ1個ずつを学習するのと、
ある程度まとまった数をまとめて学習するのとで、結果が変わる可能性があります。
batch_size
では、いくつのデータをまとめて学習するかを決定します。
また、学習の際には、一部のデータを検証用に置いておき、
それ以外のデータで学習したあとに、検証用のデータと照らし合わせることで、
学習しながら、平行して精度の検証を行うことができます。
validation_split
では、検証用に用いるデータの割合を設定します。
RStudio を使っていると、fit
の実行時に、
学習の進行具合をグラフで分かりやすく示してくれます。
acc
は入出力の対応をどれだけ正確に再現できているかを表していて、
loss
は入出力のずれを表しています。
頭にval_
がついているものは、検証用のデータを使って精度を計ったもので、
何もついていないものは、学習に使ったデータを使って精度を計ったものになります。
val_acc
が上昇して、val_loss
が減少していると上手く学習が進んでいるということになります。
4. モデルを活用する
モデルの学習が済んだら、モデルを使って未知の入力から出力を予測したりすることができます。
下では、一様分布に従って新しくランダムに生成した入力をモデルに与えて、
それが赤、緑のどちらのグループに属するかを予測させています。
x = t(sapply(1:1000,function(i){ runif(2,min=-2,max=2) })) y = model %>% predict(x) plot(x[,1],x[,2],col=apply(y,1,which.min)+1)
図を見ると、右上は赤、左下は緑という風に分けられていて、
初めに与えたデータからなんとなく、右上は赤で、左下は緑だろうということが、
学習されていることが分かります。