TensorFlow-Kerasを用いたニューラルネットワークによるmake_moonデータの学習

TensorFlow-Kerasを用いたニューラルネットワークによるmake_moonデータの学習

概要

TensorFlow-Kerasを用いて、make_moonデータ(scikit-learn)をニューラルネットワークで学習させる。

環境

Python 3.6.3
TensorFlow 1.12.0
Keras 2.2.4
scikit-learn 0.20.2

make_moonデータの学習

[パラメーター]

  • 入力層 : 2次元
  • 隠れ層 : 5次元(1層)、活性化関数tanh()
  • 出力層 : 2次元
  • エポック数 : 1000
import numpy as np
import matplotlib.pyplot as plt

import sklearn.datasets

import keras
from keras.models import Sequential
from keras.layers import Dense,Activation

# 定数設定
EPOCH = 1000 # Epoch数

def build_model():
    """
    ニューラルネットワークモデルを構成します。
    """
    model = Sequential() # Sequentialモデルの生成

    model.add(Dense(input_dim=2, units=5)) # レイヤーの追加(入力2次元、出力5次元)
    model.add(Activation('tanh')) # 出力に活性化関数を適用(tanh(x))
    model.add(Dense(units=2)) # レイヤーの追加(出力2次元)
    # 補足 : 活性化関数を指定しない場合は、線形(恒等写像)となる(x)

    model.compile(optimizer='Adam', loss='mse') # モデルのコンパイル(訓練課程の設定:最適化、損失関数)

    return model

def get_modeloutput(model, x_data):
    """
    ニューラルネットワーク出力取得用の関数です。

    Parameters
    ----------
    model
        ニューラルネットワークモデル
    x_data
        入力データ

    Returns
    ------
    ニューラルネットワーク出力(2クラス)
    """
    y = model.predict(x_data) # 入力データに対するニューラルネットワーク出力を演算

    return np.argmax(y.data, axis=1) # 最大値となるインデックスを取得
    # 補足 : ニューラルネットワーク出力(2次元)に対し、大きいほうのインデックスを取得する
    # (make_moonデータ(2クラス)の、どちらのクラスなのかを取得する)
    # 例:y = (0.2,0.1)のとき、この関数の戻り値は0
    # 例:y = (0.1,0.2)のとき、この関数の戻り値は1

def plot_decision_boundary(X, y, pred_func):
    """
    結果のグラフ表示を行います。

    Parameters
    ----------
    X
        訓練用データ
    y
        訓練用ラベル
    pred_func
        ニューラルネットワークの出力値を計算する関数
    """
    # 最大値/最小値の決定(パディング付き)
    padding = 0.5
    x_min, x_max = X[:, 0].min() - padding, X[:, 0].max() + padding
    y_min, y_max = X[:, 1].min() - padding, X[:, 1].max() + padding

    # グリッドの生成
    h = 0.01 # グリッド幅
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))

    # グリッドの各点について、ニューラルネットワークの出力値を計算
    Z = pred_func(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)

    # 訓練用データと、ニューラルネットワークの出力値をプロット
    plt.figure()
    plt.contourf(xx, yy, Z, alpha=0.2)
    plt.scatter(X[:, 0], X[:, 1], c=y)
    plt.show()

def main():
    # 入力データの生成
    np.random.seed(seed=0) # 乱数のシードを設定(発生させる乱数を固定)
    X, y = sklearn.datasets.make_moons( # make_moonデータの生成
        n_samples=200, # 生成する点の数
        noise=0.2 # 標準偏差
        )

    # ニューラルネットワークモデルの構築
    model = build_model()

    # ニューラルネットワークモデルの学習
    X_train = X
    y_train = keras.utils.np_utils.to_categorical( # クラスベクトルをクラス行列に変換
        y, # 行列に変換するクラスベクトル
        num_classes=2 # 総クラス数
        )
    model.fit( # モデルのトレーニングの実行
        x=X_train, # 訓練データ
        y=y_train, # ラベルデータ
        epochs=EPOCH # エポック数
        )

    # 結果の表示
    plot_decision_boundary(X, y, lambda x: get_modeloutput(model, x))

if __name__ == "__main__":
    main()

学習結果

f:id:storikai:20190224233326p:plain