簡単な分類問題を解いてみる
データ
以下のようなデータをpythonで出力する。
図1 散布図
エリアごとに色分けされたデータが散らばっていることがわかる。
各点の色は座標(x1,x2)によって定まるようである。
グラフのデータを機械学習で利用しやすい形に持ち込む。
図2 行列データ
図2において、1行目はx1 =0.031295,x2=0.284174の座標に赤点を存在することをします。
モデル
図3モデル
プログラム
今のプログラムの目的は、学習の経過を示すグラフの出力と新データに対して正しくラベル(色)が予測されているかを確認することである。
import keras from keras.layers import Input, Dense#,Dropout from keras.models import Model import numpy as np import matplotlib.pyplot as plt from keras.optimizers import RMSprop #データを作成 # generate data x1_r = np.random.rand(100)*0.5 x2_r = np.random.rand(100)*0.5 #label 1(red) l_r = np.zeros_like(x1_r) l_r = l_r + 0 x1_b = np.random.rand(100)*0.5 + 0.5 x2_b = np.random.rand(100)*0.5 #label 2(blue) l_b = np.zeros_like(x1_b) l_b = l_b + 1 x1_g = np.random.rand(100)*0.5 x2_g = np.random.rand(100)*0.5 + 0.5 #label 3(green) l_g = np.zeros_like(x1_g) l_g = l_g + 2 x1_y = np.random.rand(100)*0.5 + 0.5 x2_y = np.random.rand(100)*0.5 + 0.5 #label 4(yellow) l_y = np.zeros_like(x1_y) l_y = l_y + 3 #array merge A_r = np.c_[x1_r,x2_r,l_r] A_b = np.c_[x1_b,x2_b,l_b] A_g = np.c_[x1_g,x2_g,l_g] A_y = np.c_[x1_y,x2_y,l_y] A = np.r_[A_r,A_b,A_g,A_y] #shuffle np.random.shuffle(A) #split トレイン用データとテスト用データを分離 data,label = np.hsplit(A,[2]) #data_train :(300,2) date_test :(100,2) data_train,data_test = np.vsplit(data,[300]) #label_train :(300,1) label_test :(100,1) label_train,label_test = np.vsplit(label,[300]) label_train = keras.utils.np_utils.to_categorical(label_train.astype('int32'),4) label_test = keras.utils.np_utils.to_categorical(label_test.astype('int32'),4) #ニューラルネットワークのモデルを定義 #入力層 2入力 inputs = Input(shape=(2,)) #隠れ層 3出力で活性化関数ははrelu nw = Dense(3, activation='relu')(inputs) #出力層 4出力 ソフトマックス関数を挿入(0~1の値に収める) predictions = Dense(4, activation='softmax')(nw) #モデルをまとめる model = Model(inputs=inputs, outputs=predictions) #モデルをコンパイル 最適化手法:RMSprop 目的関数:categorical_crossentropy model.compile(optimizer=RMSprop(), loss='categorical_crossentropy', metrics=['accuracy']) #学習の実行 epochsは学習回数 historyには学習の経過が記録される。 history = model.fit(data_train, label_train, batch_size=10, epochs=150, verbose=1,validation_data=(data_test, label_test)) #学習の経過をグラフ化 plt.plot(history.history['acc']) plt.plot(history.history['val_acc']) plt.title('model accuracy') plt.ylabel('accuracy') plt.xlabel('epoch') plt.legend(['train', 'test'], loc='upper left') plt.show() #新データに対する予測 xa = np.array([[0.8,0.7]]) print("新データ(0.8,0.7)に対する予想") print(model.predict(xa))
出力
図4 認識精度の推移
epoch(学習回数)が増えるごとに認識精度が向上していることが見て取れる。
新データ(0.8,0.7)に対する予想 [[ 0.00191311 0.06421792 0.00333812 0.93053085]]
学習済みのニューラルネットワークは新データ(0.8,0.7)に対して4番目の要素(黄色に対応)である確率が
0.93053085でもっとも高いと予想している。
図1を見てみるとデータ(0.8,0.7)には黄色のラベルが付されそうである。
人間の判断とニューラルネットワークの判断が一致している。
このニューラルネットワークは正確な分類器として機能しているようである。
まとめ
非常に簡単なデータにたいして、ニューラルネットワークをトレーニングさせ、高精度の分類器を実現できた。
今回はepoch数を150に設定したが、50に設定しトレーニングすると、認識精度は150のときのそれに及ばなかった。つまり、epoch数を増やすことで認識精度が向上する様子を観察できた。
さらなる認識精度の向上には、さまさまな手法が存在するが、またの機会に記事にしたい。