RとKeras(TensorFlow)でディープラーニング

R

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ステップでインストールができます。

  1. Keras Rパッケージをインストール
  2. Kerasライブラリの読み込み
  3. 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層のネットワークでこんなに高い正解率が得られるなんて驚きですよね。もっと複雑なネットワークを構成すれば、あんなことや、こんなことができたりしちゃいます。

あんなことや、こんなこと、って、こんなこと

競馬 過去データcsvをnetkeibaから無料で入手する方法
JRA-VANを無料で使えるのはお試し期間のみ。競馬のデータ分析を継続して行うには、どうしても過去の競馬レース結果データを自前で収集する必要があります。netkeibaからのスクレイピング方法やデータをcsv 形式で保存する方法について記述しています。
競馬予想AIの作り方 〜 Rでスピード指数をスクレイピング
スピード指数データは「無料」「スピード指数」で検索して、トップに出てくる下記のサイトからを入手させていただくことにしました。 競馬新聞&スピード指数(無料)