前回考えたニューラルネットワークモデルをPythonで実装することによりイメージをつかみます。
イメージ概要
前回考えたニューラルネットワークモデルに少し修正をしたイメージです。
データの準備の実装
データの説明
まずはニューラルネットワークにかけるデータの準備を行います。
基本データは以前の分類に用いた「アヤメの品種データ」を使います。
※データ自体はなんでもよいです。
■説明変数
0 | sepal length (cm) | がく片の長さ |
---|---|---|
2 | petal length (cm) | 花弁の長さ |
今回はがく片の長さと花弁の長さを使ってみます。
■目的変数
3クラスに分類するという点だけ抑えておけばよいです。
0 | setosa(ヒオウギアヤメ) |
---|---|
1 | versicolor(ブルーフラッグ) |
2 | virginica(バージニカ) |
データの保存
scikit-learnからデータを抜いてきてファイルに保存するところまで。
# データ準備 import numpy as npy import matplotlib.pyplot as plt %matplotlib inline # アヤメ品種データの読み込み from sklearn.datasets import load_iris iris_data = load_iris() # 説明変数 X_array = iris_data.data # カラムデータを取得 X0=X_array[:,0] X1=X_array[:,3] # 目的変数 t_array = iris_data.target T=t_array N=len(X0) petal_data=npy.zeros((N,2)) T3 = npy.zeros((N,3), dtype=npy.uint8) #データの設定 for i in range(N): petal_data[i]=[X0[i], X1[i]] # 0[1,0,0] 1[0,1,0] 2[0,0,1] if T[i] == 0: T3[i]=[1,0,0] elif T[i] == 1: T3[i]=[0,1,0] else: T3[i]=[0,0,1] X_range0=[min(X0)*0.9,max(X0)*1.1] X_range1=[min(X1)*0.9,max(X1)*1.1] # データをclassdata3.npzファイルに保存する npy.savez('neural_rawdata.npz',X=petal_data,T3=T3,X_range0=X_range0,X_range1=X_range1,X_n=N)
訓練データとテストデータに分割
今回はデータを訓練データと検証のためのテストデータに分けてみます。
データセットは150個のデータが50個ごとにクラス1、2、3の順にならんでいるので各クラスから25個をそれぞれ訓練データとテストデータに分割しました。
・実装
# 生データファイルから取り出す sample_data = npy.load('neural_rawdata.npz') # 入力値の設定 X=sample_data['X'] # がく片の長さの表示範囲設定 X_range0=sample_data['X_range0'] # 花弁の長さの表示範囲設定 X_range1=sample_data['X_range1'] # クラス(答え)の設定 T3=sample_data['T3'] # データの並び替え X1 = X[:50,:] X2 = X[50:100,:] X3 = X[100:150,:] npy.random.shuffle(X1) npy.random.shuffle(X2) npy.random.shuffle(X3) X_test=npy.r_[X1[:25,:], X2[:25,:], X3[:25,:]] X_train=npy.r_[X1[25:50,:],X2[25:50,:],X3[25:50,:]] T_test=npy.r_[T3[:25,:], T3[50:75,:], T3[100:125,:]] T_train=npy.r_[T3[25:50,:],T3[75:100,:],T3[125:150,:]] npy.savez('neural_data.npz',X_train=X_train, T_train=T_train,X_test=X_test,T_test=T_test,X_range0=X_range0,X_range1=X_range1)
データのプロット
分割した訓練データとテストデータをグラフ上にプロットします。
・実装例
import matplotlib.pyplot as plt %matplotlib inline # データの表示 def Show_data(x,t): wk,n=t.shape c=[[0,0,0],[.5,.5,.5],[1,1,1]] for i in range(n): plt.plot(x[t[:,i]==1,0],x[t[:,i]==1,1],linestyle='none',marker='o',markeredgecolor='black',color=c[i],alpha=0.8) plt.grid(True) plt.figure(1,figsize=(8,3.7)) plt.subplot(1,2,1) Show_data(X_train,T_train) plt.xlim(X_range0) plt.ylim(X_range1) plt.title('Training Data') plt.subplot(1,2,2) Show_data(X_test,T_test) plt.xlim(X_range0) plt.ylim(X_range1) plt.title('Test Data') plt.show()
・出力結果
訓練データとテストデータがそれぞれ違うデータで表示されていればとりあえずOK。
ニューラルネットワークの実装
シグモイド関数の実装
ニューラルネットワーク内で使用されるシグモイド関数を先に実装しておきます。
・シグモイド関数
・実装例
# シグモイド関数 def Sigmoid(x): y=1/(1+npy.exp(-x)) return y
ニューラルネットワークの実装
# ニューラルネットワーク(wv重み、M中間層ノード数、K出力層ノード数、x入力層の入力値) def FNN(wv, M, K, x): # Nデータ数 Dデータの入力次元 N, D = x.shape # w 入力層⇒中間層の重み w = wv[:M * (D+1)] w = w.reshape(M,(D+1)) # v 中間層⇒出力層の重み v = wv[M*(D+1):] v = v.reshape((K,M+1)) # b 中間層の入力総和 b = npy.zeros((N,M+1)) # z 中間層の出力値 z = npy.zeros((N,M+1)) # a 出力層の入力総和 a = npy.zeros((N,K)) # y 出力層の出力値 y = npy.zeros((N,K)) # データごとに中間層、出力層の計算を行う for n in range(N): # 中間層の計算(シグモイド関数) for m in range(M): b[n,m] = npy.dot(w[m,:],npy.r_[x[n,:],1]) z[n,m] = Sigmoid(b[n,m]) # ダミーニューロン z[n,M]=1 u=0 # 出力層の計算(ソフトマックス関数) for k in range(K): a[n,k] = npy.dot(v[k,:],z[n,:]) u = u + npy.exp(a[n,k]) for k in range(K): y[n,k] = npy.exp(a[n,k])/u return y,a,z,b # テスト実行 WV = npy.ones(15) M = 2 K = 3 FNN(WV,M,K,X_train[:2,:])
WV(中間層と出力層の重み)と中間層のノード数(M)、出力層のノード数(K)、入力値(X)をニューラルネットワークに渡して戻り値として各層の出力値と入力総和を返します。
中間層での計算は先ほど実装したシグモイド関数を適用します。
出力層の計算にはソフトマックス関数を適用するので、ニューラルネットワーク内で合計値(u)を求めて各値を割ることで出力値とします。
・テスト実行
テスト実行なので、重みは全て1としています。
入力値については訓練データの頭2つのデータを適用しています。
・出力結果
(array([[0.33333333, 0.33333333, 0.33333333],
[0.33333333, 0.33333333, 0.33333333]]),
array([[2.9955243 , 2.9955243 , 2.9955243 ],
[2.99396317, 2.99396317, 2.99396317]]),
array([[0.99776215, 0.99776215, 1. ],
[0.99698158, 0.99698158, 1. ]]),
array([[6.1, 6.1, 0. ],
[5.8, 5.8, 0. ]]))
注目すべきは最終的な出力結果となる「y」ですが、テスト実行で重みパラメータが全て1なので確率が全ての「0.33」となっています。
なので、現時点では有効に活用できておらず、重みの設定の重要性が分かります。
重みの設定ができていないとニューラルネットワークがあっても活用することはできないので、次回は最適な重みを設定することを検討します。
・今回のソース
python_dev/Neural_net1_prod.ipynb at master · wantanblog/python_dev · GitHub