- 投稿日:2020-10-14T15:12:42+09:00
アプリでまなぶNN:Kerasでテンソルフロープレイグラウンドを理解する
テンソルフロープレイグラウンド(Neural Network Playground)はブラウザー上で動うニューラルネットワークの学習用アプリケーションです。これを使えば誰でも簡単に短期間でニューラルネットワークを理解することができます。
アプリでまなぶNN:動かす人工知能ーテンソルフロープレイグラウンドを参照してみてください。
しかし、より詳細にその内容を理解するためには同じものを別のプログラミング言語で作ってみるのも一つの手です。本記事ではこれをkerasを用いて行います。サークル
上述の画像はテンソルフロープレイグラウンドの初期画面です。出力データにサークルが選択され、入力データにX1とX2が選ばれています。実行してみます。
これが何を行っているかを正確に理解するために、同じ動きをKerasで実現してみるのも一つの手です。そこでつぎのようなプログラムを作ってみました。
# 初期化 %matplotlib inline import pandas_datareader.data as web import matplotlib.pyplot as plt import numpy as np import pandas as pd import datetime import keras from keras.models import Sequential from keras.layers import Dense, Activation from keras.optimizers import SGD from keras import models from keras import layers from keras import regularizers from sklearn.metrics import mean_squared_error from sklearn.model_selection import train_test_splitデータの構築
n=250 theta=np.random.uniform(0, 360, n) x1=np.sin(theta)*np.random.uniform(3,5, n) x2=np.cos(theta)*np.random.uniform(3,5, n) y=np.ones(n) plt.figure(figsize=(4, 4), dpi=50) plt.scatter(x1,x2) theta=np.random.uniform(0, 360, n) x11=np.sin(theta)*np.random.uniform(-0, 2, n) x22=np.cos(theta)*np.random.uniform(-0,2, n) yy=np.zeros(n) plt.scatter(x11,x22)# 訓練データ、テストデータの作成 x1=np.concatenate([x1,x11],axis=0) x2=np.concatenate([x2,x22],axis=0) y=np.concatenate([y,yy],axis=0) X=np.stack([x1,x2],1)#.reshape(-1,2) X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.5, random_state=42)ネットワークの構築と最適化
model = models.Sequential() model.add(layers.Dense(8, activation='tanh', input_shape=(2,))) model.add(layers.Dense(8, activation='tanh')) model.add(layers.Dense(1, activation='sigmoid')) model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy']) model.fit( X_train, y_train, batch_size=10, epochs=500, verbose=0)# 結果の評価 results = model.evaluate(X_train, y_train) results # 8/8 [==============================] - 0s 1ms/step - loss: 3.0139e-05 - accuracy: 1.0000 # [3.0139368391246535e-05, 1.0] results = model.evaluate(X_test, y_test) results # 8/8 [==============================] - 0s 2ms/step - loss: 1.6788e-04 - accuracy: 1.0000 # [0.0001678814151091501, 1.0]どちらの結果も誤差はゼロです。全問正解でした。
さらに理解を深めるために入力データを変更してみます。
単純パーセプトロンでデータをきれいに分類できました。これをKerasで行ってみましょう。X2=np.stack([x1**2,x2**2],1)#.reshape(-1,2) X2_train, X2_test, y_train, y_test = train_test_split( X2, y, test_size=0.33, random_state=42) model = models.Sequential() model.add(layers.Dense(1, activation='tanh', input_shape=(2,))) model.add(layers.Dense(1, activation='sigmoid')) model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy']) model.fit( X2_train, y_train, batch_size=10, epochs=500, verbose=0)結果はつぎに様になりました。
results = model.evaluate(X2_train, y_train) results # 11/11 [==============================] - 0s 3ms/step - loss: 8.3843e-08 - accuracy: 1.0000 # [8.38432754335372e-08, 1.0] results = model.evaluate(X2_test, y_test) results # 6/6 [==============================] - 0s 2ms/step - loss: 8.3747e-08 - accuracy: 1.0000 # [8.374658477805497e-08, 1.0]どちらも正解率100%で誤差はゼロです。
正規分布
つぎは正規分布です。
まずはデータを構築します。
n=250 x1=np.random.normal(2,0.5, n) x2=np.random.normal(2,0.5, n) y=np.ones(n) plt.figure(figsize=(4, 4), dpi=50) plt.scatter(x1,x2) x11=np.random.normal(-2,0.5, n) x22=np.random.normal(-2,0.5, n) yy=np.zeros(n) plt.scatter(x11,x22) x1=np.concatenate([x1,x11],axis=0) x2=np.concatenate([x2,x22],axis=0) y=np.concatenate([y,yy],axis=0) X=np.stack([x1,x2],1)#.reshape(-1,2)
ニューラルネットワークはサークルのときと同じものを使います。その結果はresults = model.evaluate(X_train, y_train) results # 8/8 [==============================] - 0s 1ms/step - loss: 3.0139e-05 - accuracy: 1.0000 # [3.0139368391246535e-05, 1.0]ふたたび誤差ゼロの正解率100%となりました。
XOR
n=125 x1=np.random.uniform(0,5, n) x2=np.random.uniform(0,5, n) y=np.ones(n) x11=np.random.uniform(-5,0, n) x22=np.random.uniform(-5,0, n) yy=np.ones(n) x1=np.concatenate([x1,x11],axis=0) x2=np.concatenate([x2,x22],axis=0) y=np.concatenate([y,yy],axis=0) plt.figure(figsize=(4, 4), dpi=50) plt.scatter(x1,x2) x11=np.random.uniform(0,5, n) x22=np.random.uniform(0,-5, n) yy=np.zeros(n) x111=np.random.uniform(-5,0, n) x222=np.random.uniform(0,5, n) yyy=np.zeros(n) x11=np.concatenate([x11,x111],axis=0) x22=np.concatenate([x22,x222],axis=0) yy=np.concatenate([yy,yyy],axis=0) plt.scatter(x11,x22) len(x1),len(x2) # (250, 250)250個のデータができたのが分かります。
訓練データとテストデータにシャッフルをして分割します。x1=np.concatenate([x1,x11],axis=0) x2=np.concatenate([x2,x22],axis=0) y=np.concatenate([y,yy],axis=0) X=np.stack([x1,x2],1)#.reshape(-1,2) len(y) X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.5, random_state=42)このデータを2層(第一層4ユニット,第二層2ユニット)のNNで分類を試みます。結果は
results = model.evaluate(X_train, y_train) results # 8/8 [==============================] - 0s 2ms/step - loss: 0.0818 - accuracy: 0.9640 # [0.08181502670049667, 0.9639999866485596] results = model.evaluate(X_test, y_test) results # 8/8 [==============================] - 0s 2ms/step - loss: 0.1269 - accuracy: 0.9520 # [0.1269153356552124, 0.9520000219345093]誤差はほぼゼロで、正解率も9割を超えています。
X_train, X_test, y_train, y_test = train_test_split( x1*x2, y, test_size=0.33, random_state=42) model = models.Sequential() model.add(layers.Dense(1, activation='tanh', input_shape=(1,))) model.add(layers.Dense(1, activation='sigmoid')) model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy']) model.fit( X_train, y_train, batch_size=10, epochs=500, verbose=0)結果はつぎのようになりました。
results = model.evaluate(X_train, y_train) results # 11/11 [==============================] - 0s 1ms/step - loss: 5.6793e-04 - accuracy: 1.0000 # [0.0005679333116859198, 1.0] results = model.evaluate(X_test, y_test) results # 6/6 [==============================] - 0s 3ms/step - loss: 0.0070 - accuracy: 0.9939 # [0.007003221195191145, 0.9939393997192383]誤差はほぼゼロで、正解率もほぼ100%になりました。
参考:
「シミュレーターでまなぶニューラルネットワーク」(アマゾンkindle出版)
「脳・心・人工知能 数理で脳を解き明かす」(ブルーバックス)
「圧縮センシングにもとづくスパースモデリングへのアプローチ」