Keras/TensorFlowを使えばRでもディープラーニングを行うことができます。しかも、とても簡単に。Keras/TensorFlowのインストールから、簡単な例題までを、はじめてディープラーニングにトライする方に向けてまとめています。
Rでディープラーニング
RはPythonと並んでデータサイエンスでよく使われる言語です。せっかくデータサイエンスを学ぶなら、ディープラーニングも試してみたい!と思いますよね。Rでディープラーニングに挑戦してみましょう。
Pythonでディープラーニングを行う際、よく使われるライブラリがKerasです。Kerasは、TensorFlow、CNTK、Theano上で動くニューラルネットワークライブラリです。RStudio社からkerasパッケージがリリースされ、RでもKerasを用いたディープラーニングを行えるようになりました。このパッケージもPython同様、バックエンドで、TensorFlow、CNTK、Theanoが動作します。今回は、よく使われるTensorFlowを導入します。
Kerasのインストール
Kerasのインストールは簡単です。
以下の3ステップでインストールができます。
- Keras Rパッケージをインストール
- Kerasライブラリの読み込み
- KerasのコアライブラリとTensorFlowをインストール
install.packages("keras") library(keras) install_keras()
NVIDIA GPUを搭載し、CUDAとcuDNNをインストールしている環境の場合、GPUベースのTensorFlowをバックエンドとして利用できます。この場合は、最後の一行を以下のように修正してください。
install_keras(tensorflow = "gpu")
実行例
Keras/TensorFlowが利用できる環境になったので、早速、ディープラーニングを試してみたいと思います。対象は、機械学習のHello Worldとしてよく知られるMNISTの分類です。MNISTは手書き数字画像のデータセットで、6万個の訓練データと1万個のテストデータからなっており、kerasライブラリから入手できます。
データの読み込み
MNISTのデータはdataset_mnist()を呼ぶことで入手できます。200MB以上のデータをネットワークからダウンロードするので、1-2分程度、時間がかかります。
library(keras) mnist <- dataset_mnist()
mnistの構造をみると以下のように、train(訓練データ)とtest(テストデータ)に分かれており、それぞれにx(画像データ)とy(ラベル)が、60000個、10000個含まれています。また、画像データは28×28のデータになっていることが分かります。
> str(mnist) List of 2 $ train:List of 2 ..$ x: int [1:60000, 1:28, 1:28] 0 0 0 0 0 0 0 0 0 0 ... ..$ y: int [1:60000(1d)] 5 0 4 1 9 2 1 3 1 4 ... $ test :List of 2 ..$ x: int [1:10000, 1:28, 1:28] 0 0 0 0 0 0 0 0 0 0 ... ..$ y: int [1:10000(1d)] 7 2 1 0 4 1 4 9 5 9 ...
データの準備
mnistのデータを訓練用の画像、ラベル、テスト用の画像、ラベルに分解します。
train_images <- mnist$train$x train_labels <- mnist$train$y test_images <- mnist$test$x test_labels <- mnist$test$y
画像データの準備
さらに、イメージデータを28×28の行列ではなく、1データあたり784(=28×28)要素のベクトルに変換します。実際には、nデータあるので(n = 60000 or 10000)、n×784の行列になります。
train_images <- array_reshape(train_images, c(60000, 28*28)) test_images <- array_reshape(test_images, c(10000, 28*28))
さらに、全てのデータの値が[0, 1]となるようにスケーリングをします。
train_images <- train_images / 255 test_images <- test_images / 255
これで、画像データの準備は完了です。
ラベルデータの準備
ラベルデータはto_categorical()関数を用いてone-hotベクトルに変換しておきます。
train_labels <- to_categorical(train_labels) test_labels <- to_categorical(test_labels)
ネットワークのアーキテクチャ
unit数512、活性化関数としてReLUを用いた全結合層の隠れ層が1つ、softmax関数を用いた全結合層の出力層が1つという単純なネットワーク構成とします。
network <- keras_model_sequential() %>% layer_dense(units = 512,activation = "relu",input_shape = c(28*28)) %>% layer_dense(units = 10, activation = "softmax")
ネットワークのコンパイル
optimizerとして、rmsprop最適化器を用い、損失関数として交差エントロピー(categorical_crossentropy)を用い、評価関数として正解率(accuracy)を使用することとします。
network %>% compile(optimizer = "rmsprop", loss = "categorical_crossentropy", metrics = c("accuracy") )
ネットワークの訓練
128サンプルずつのミニバッチに分けて、それを5回繰り返すこととします。
network %>% fit(train_images, train_labels, epochs = 5, batch_size = 128)
テストセットによる評価
訓練したネットワークを用いてテストセットを評価します。
network %>% evaluate(test_images, test_labels) loss accuracy 0.06321603 0.98159999
およそ、98%くらいの正答率になると思います。set.seed()でランダムシードを設定してみても、毎回、答えが変わります。どうやら、Rのランダムシードの設定だけでなく、Keras(Python?)のランダムシードも設定すれば良さそうなのですが、うまくできませんでした。
テストセットの始めの10個に対する予測
テストセットの始めの10個のデータに対する予測を行うと、以下のようになります。
network %>% predict(test_images[1:10, ]) %>% k_argmax() tf.Tensor([7 2 1 0 4 1 4 9 5 9], shape=(10,), dtype=int64)
testデータのラベルを確認すると、以下のように一致していることがわかります。
> mnist$test$y[1:10] [1] 7 2 1 0 4 1 4 9 5 9
まとめ
全部書いても、たかだか50行程度のコードで手書きの数字画像の読み取り正解率が約98%。たった2層のネットワークでこんなに高い正解率が得られるなんて驚きですよね。もっと複雑なネットワークを構成すれば、あんなことや、こんなことができたりしちゃいます。
あんなことや、こんなこと、って、こんなこと