メインコンテンツへスキップ

Keras入門 ニューラルネットワークによる正弦波の回帰

·1246 文字·3 分
目次

はじめに
#

以前、Chainerの入門記事を書いたが、実装が容易なKerasを試してみた。ニューラルネットワーク (NN) による回帰の実装例として、正弦波を学習させる。KerasのバックエンドにはTensorFlowを使う。

環境
#

ソフトウェアのバージョンは以下の通り。

ソフトウェア バージョン
Anaconda3 5.2.0
Python 3.6.5
TensorFlow 1.12.0
Keras 2.2.4
NumPy 1.14.3
matplotlib 2.2.2

Anaconda Promptにて以下の通りインストールする。

conda install tensorflow
conda install keras

次に、Pythonで以下の通りライブラリをインポートする。

import numpy as np
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense

学習データ
#

x=-5~5の範囲で正弦波を生成する。データ数は10,000点である。 なお、学習を高速化するためには扱う変数を全て標準化する必要があるが、簡単のため今回はそのままの値を用いる。

x = np.arange(-5, 5, 0.001).astype(np.float32)
y = np.sin(x)

fig, ax = plt.subplots()
ax.plot(x, y)
plt.show()

出力

keras_sin
keras_sin

Kerasによる学習
#

NNモデル
#

説明変数と目的変数の次元はともに1なので、入力層と出力層のノード数は1となる。 隠れ層の数は4、ノード数は全て20とした。また、活性化関数はtanhとする。

actfunc = "tanh"

model = Sequential()
model.add(Dense(20, activation=actfunc, input_dim=1))
model.add(Dense(20, activation=actfunc))
model.add(Dense(20, activation=actfunc))
model.add(Dense(20, activation=actfunc))
model.add(Dense(1))

以上の様に、Sequentialインスタンスを作成し、addメソッドで層を追加していく。なお、Denseは全結合層である。

学習の実行
#

modelcomplieメソッドで最適化手法と損失関数を指定する。 最適化手法にはSGD (Stochastic Gradient Descent, 確率的勾配降下法) を用い、損失関数は予測値と真値の二乗平均誤差 (mean squared error) とする。

次に、fitメソッドで学習を実行する。 学習データx, yを与え、バッチサイズ、エポック数を指定する。 verbose引数は、下表の通り学習の進行状況の表示に関するオプション。

verbose ログの表示
0 出力しない
1 プログレスバーで出力
2 損失関数のみの簡易表示

また、historyには学習時のログが格納される。

model.compile(optimizer='sgd',
              loss='mean_squared_error')

history = model.fit(x, y,
                    batch_size=100,
                    epochs=50,
                    verbose=1)

出力

実行すると、以下の通り学習の進行状況が表示される。 PCの性能によるが、数秒程度で学習は終了する。

Epoch 1/50
10000/10000 [==============================] - 1s 109us/step - loss: 0.2431
Epoch 2/50
10000/10000 [==============================] - 0s 9us/step - loss: 0.0159
Epoch 3/50
10000/10000 [==============================] - 0s 8us/step - loss: 0.0104
Epoch 4/50
10000/10000 [==============================] - 0s 8us/step - loss: 0.0091
Epoch 5/50
10000/10000 [==============================] - 0s 8us/step - loss: 0.0087

Epoch 50/50
10000/10000 [==============================] - 0s 8us/step - loss: 0.0032

学習モデルの評価
#

evaluateメソッドで検証用データに対する損失関数の値を出力する。 本来は学習データと検証データを分ける必要があるが、簡単のため同じデータとしている。

score = model.evaluate(x, y)
print(score)

出力 学習データと検証データが同じため、学習の最終エポックの損失関数に近い値が表示されるはずである。

10000/10000 [==============================] - 0s 13us/step
0.0034303181435687293

また、predictメソッドで説明変数に対する予測値を出力する。

pred = model.predict(x)

fig, ax = plt.subplots()
ax.plot(x, y)
ax.plot(x, pred)
plt.show()

出力 青が学習データ、黄色がNNの出力である。xが-5や5に近い領域でやや異なる値となっているが、概ね正弦波の形状を学習できている。

keras_sin_learn
keras_sin_learn

また、学習中の損失関数の推移は、以下のように取得できる。

loss = history.history["loss"]

fig, ax = plt.subplots()
ax.plot(loss)
plt.show()

出力 横軸がエポック数、縦軸が(学習データに対する)損失関数である。最初の1~2エポックで急激に損失関数が減少し、その後は緩やかに単調減少していることが分かる。

keras_loss
keras_loss

参考
#

Home - Keras Documentation

Helve
著者
Helve
関西在住、電機メーカ勤務のエンジニア。X(旧Twitter)で新着記事を配信中です

関連記事

Scikit-learnでデータをスケール変換する
··4596 文字·10 分
Pythonの機械学習用ライブラリScikit-learnに実装されている、スケール変換について調べた。
NumPyのemptyで空(長さ0)の配列を作る
·1419 文字·3 分
NumPyのempty関数を用いて、空の(要素を持たない)任意の次元の配列を作成できる。本記事では、空の配列の作り方、使い方について簡単に考察する。
Matplotlib スタイルによるグラフの見た目の変更
·990 文字·2 分
matplotlibにはスタイルと呼ばれる、グラフの見た目を変更できるプリセットが用意されている。スタイルを活用することで、グラフの見た目を簡単に変更できる。
Matplotlibのオブジェクト指向な対数軸プロット
·1012 文字·3 分
matplotlibライブラリで作成したグラフの軸を、オブジェクト指向スタイルで対数に変更する。
PandasのSeriesとDataFrameの作成
·1427 文字·3 分
Pandasの基本データ構造であるSeriesとDataFrameの作成方法について述べる。
Pythonのmultiprocessingを使った並列計算
·456 文字·1 分
Pythonの標準ライブラリmultiprocessingを使って並列計算を行う。