nprogram’s blog

気ままに、プログラミングのトピックについて書いていきます

Keras学習入門

はじめに

公式ドキュメントを読みましょう。

Home - Keras Documentation

サンプルもあります。

https://github.com/keras-team/keras/tree/master/examples

参考にした記事

無から始めるKeras - Qiita

作りたいもの

適当な5次元のデータ配列を入力すると、その和が2.5より大きい場合に、1と教えてくれるニュートラルネットワークを作成します。

データセットを作る

適当なデータセットを作ります。以下は1000行、5列の2次元のデータを作成する。

random.randの1つ目の引数に行数、2つ目の引数に列数を指定します。

ここで、1つの行について考えると、列は5つあるため、1000個の5次元のデータを作成したと考えることもできます。

data = np.randam.rand(1000, 5)
array([[0.3940429 , 0.79998594, 0.58371434, 0.4746385 , 0.57960131],
       [0.48199409, 0.29579691, 0.6393789 , 0.79172043, 0.35938036],
       [0.32953348, 0.44838049, 0.60369065, 0.96091877, 0.61703259],
       ...,
       [0.40231469, 0.69186734, 0.09979942, 0.57616445, 0.99702868],
       [0.41718706, 0.92310164, 0.66852297, 0.69960452, 0.15955488],
       [0.25724677, 0.94933856, 0.18957415, 0.22025431, 0.52682667]])
import numpy as np
from keras.utils import np_utils

# dataは5次元のデータ
data = np.random.rand(1000, 5)

# sum_dataは1次元のデータ
sum_data = (np.sum(data, axis=1) > 2.5) * 1

データセットを整形する

one-hotなラベルを作成します。

one-hot(ワン・ホット)は1つだけHigh(1)であり、他はLow(0)であるようなデータのことです。

from keras.utils import np_utils
sum_data = (np.sum(data, axis=1) > 2.5) * 1
labels = np_utils.to_categorical(sum_data)
array([[0., 1.],
       [1., 0.],
       [1., 0.],
       ...,
       [0., 1.],
       [1., 0.],
       [0., 1.]], dtype=float32)

ニュートラルネットワークを作る

Sequentialは層を積み上げるだけのモデル。

今回は中間層(入力層・隠れ層・出力層)とする

入力5個、出力2個のニュートラルネットワークを作成します。

f:id:nprogram:20190414190509p:plain

from keras.models import Sequential
from keras.layers import Dense, Activation
model = Sequential()

Denseというレイヤー(通常の全結合ニューラルネットワークレイヤー)を使用する。

5個のノートから、それぞれ10本矢印が出てきて、次の層のノードが10個であることを示す。 ノード数は入力データの次元数と一致する必要がある。

model.add(Dense(10, input_dim=5))

出力に活性化関数を適用します。'relu'はランプ関数です。

活性化関数は、入力信号の総和がどのように活性化するかを決定する役割を持ちます。

これは、次の層に渡す値を整えるような役割をします。

model.add(Activation('relu'))

次は隠れ層―出力層。10個のノードから(活性化関数が適用されたあと)それぞれ値がやってくる。出力は2次元で、ノードにやってきた10個の値に対して重み付き和とソフトマックス関数を使用します。

ソフトマックス関数は、活性化関数の1つで、出力層で使われる関数です。

model.add(Dense(2, activation='softmax'))
model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

コンパイル

学習の前にコンパイルを行います。

1つめは最適化関数、2つめは損失関数、3つめは評価指標のリスト。

model.compile('rmsprop', 'categorical_crossentropy', metrics=['accuracy'])

学習

nb_epoch は回数。validation_split は検証に使うデータの割合(全体のデータを学習に使わず、8割のみを学習に使って、残りの2割を評価に使う)。

model.fit(data, labels, nb_epoch=300, validation_split=0.2)

未知データ予測

予測精度を判別します。

test = np.random.rand(1000, 5)

## 予測配列
predict = np.argmax(model.predict(test), axis=1)

## 正解配列
real = (np.sum(test, axis=1) > 2.5) * 1
sum(predict == real) / 1000.0

コード例

from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense, Activation
import numpy as np

data = np.random.rand(1000,5)
data_sum = (np.sum(data, axis=1) > 2.5) * 1
labels = np_utils.to_categorical(data_sum)
model = Sequential([Dense(10, input_dim=5), Activation('relu'), Dense(2, activation='softmax')])
model.compile('rmsprop', 'categorical_crossentropy', metrics=['accuracy'])
model.fit(data, labels, nb_epoch=100, validation_split=0.2)

test = np.random.rand(1000, 5)
predict = np.argmax(model.predict(test), axis=1)
real = (np.sum(test, axis=1) > 2.5) * 1
print(sum(predict == real) / 1000.0)
0.979

参考リンク