20201014のTensorFlowに関する記事は1件です。

アプリでまなぶNN:Kerasでテンソルフロープレイグラウンドを理解する

テンソルフロープレイグラウンド(Neural Network Playground)はブラウザー上で動うニューラルネットワークの学習用アプリケーションです。これを使えば誰でも簡単に短期間でニューラルネットワークを理解することができます。

アプリでまなぶNN:動かす人工知能ーテンソルフロープレイグラウンドを参照してみてください。
image.png
しかし、より詳細にその内容を理解するためには同じものを別のプログラミング言語で作ってみるのも一つの手です。本記事ではこれをkerasを用いて行います。

サークル

上述の画像はテンソルフロープレイグラウンドの初期画面です。出力データにサークルが選択され、入力データにX1とX2が選ばれています。実行してみます。

image.png

これが何を行っているかを正確に理解するために、同じ動きを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)

実行結果
image.png

# 訓練データ、テストデータの作成
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]

どちらの結果も誤差はゼロです。全問正解でした。
さらに理解を深めるために入力データを変更してみます。

image.png
単純パーセプトロンでデータをきれいに分類できました。これを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%で誤差はゼロです。

正規分布

つぎは正規分布です。

image.png

まずはデータを構築します。

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)

image.png
ニューラルネットワークはサークルのときと同じものを使います。その結果は

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%となりました。

この場合には
image.png
ともなります。

XOR

つぎはXORです。
image.png

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個のデータができたのが分かります。
image.png
訓練データとテストデータにシャッフルをして分割します。

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割を超えています。

つぎにデータの構造をつぎにように変えてみます。
image.png

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出版)

image.png

「脳・心・人工知能 数理で脳を解き明かす」(ブルーバックス)
「圧縮センシングにもとづくスパースモデリングへのアプローチ」

誰でもわかるニューラルネットワーク:正則化をテンソルフロープレイグラウンドで試してみた

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む