<目次>
ディープラーニングのモデルの評価とは?実際のPythonプログラムもご紹介
(1-1) モデルの評価の概要
(1-2) モデルの評価の指標
(1-3) モデルの評価の実装例①
(1-4) モデルの評価の実装例②(Keras)
ディープラーニングのモデルの評価とは?実際のPythonプログラムもご紹介
(1-1) モデルの評価の概要
「最善」とは、データが持つパターンを見つけ出すこと。多少分類から外れていても、傾向を掴めていれば最善とみなせます。つまり「次回、似たデータを与えられた時に正解できるか?」が重要です。

(図121)
(図122)
(図123)

(1-2) モデルの評価の指標
- True Positive:正解、y=犬
- False Positive:不正解、y=犬
- True Negative:正解、y=猫
- False Negative:不正解、y=猫
式:(TP+TN)/(TP+FP+FN+TN)
意味:全データの中で正しく予測した割合
(図133)
式:TP/(TP+FP)
意味:「発火した」データの中で「発火すべき」だった割合
(図134)
式:TP/(TP+FN)
意味:「発火すべき」データの中で実際に「発火した」割合
(図135)

(1-3) モデルの評価の実装例①
############################################
# STEP6:評価
############################################
# ■ multi_layer_perceptron_evaluate()
# テストデータを用いてモデルの評価を行う(Accuracyの算出)
# ■ 引数(例)
# X_arg = テストデータ[N×M]
# t_arg = 正解データ[N×K]
# W_arg = 学習結果W [J×M]
# b_arg = 学習結果b [J×1]
# V_arg = 学習結果V [K×J]
# c_arg = 学習結果c [K×1]
# ■ 用途(例)
# 学習済みのモデルの評価(Accuracyの算出)
def multi_layer_perceptron_evaluate(X_arg,t_arg,W_arg,b_arg,V_arg,c_arg):
# データセットの規模を取得
N = X_arg.shape[0]
# 入力の電気信号Xの初期化
X_eval = tf.constant(X_arg, dtype = tf.float64, shape=[N,M])
xn_eval = tf.Variable(tf.zeros([M,1],tf.float64),dtype = tf.float64, shape=[M,1])
# 隠れ層の出力(シグモイド関数):h = σ(wx + b)の定義 (※データはn個でも1つのyを更新)
h_eval = tf.Variable(tf.zeros([J,1],tf.float64), dtype = tf.float64, shape=[J,1])
# 出力層の出力(ソフトマックス関数):y = softmax(Wh + b)の定義 (※データはn個でも1つのyを更新)
y_eval = tf.Variable(tf.zeros([K,1],tf.float64), dtype = tf.float64, shape=[K,1])
# 出力層の結果格納用(正解率「Accuracy」算出に使用)
yn = tf.Variable(tf.zeros([N,K],tf.float32), dtype = tf.float32, shape=[N,K])
# 出力層の正解値tの定義
t = tf.Variable(t_arg, dtype = tf.float64, shape=[N,K])
for n in range(N):
# データをシャッフル
#X_,t_ = shuffle(X.numpy(),t.numpy())
X_,t_ = X_eval.numpy(),t.numpy()
# 取り出したX_[n]を転置してxnに格納(Mx1)
xn_eval.assign(tf.transpose([X_[n]]))
# 隠れ層の出力(シグモイド関数):h = σ(wx + b)の計算
# h[J,1] = sigmoid( W[J×M] × X[M×1] + b[J×1] )
h_eval.assign( tf.reshape( tf.nn.sigmoid(tf.reshape(tf.matmul(W_arg,xn_eval)+b_arg,[J])),[J,1]).numpy() )
# 出力層(シグモイド関数):y = σ(Wx + b)の計算
# y[K,1] = sigmoid( V[K×J] × h[J×1] + c[K×1] )
y_eval.assign( tf.reshape( tf.nn.sigmoid(tf.reshape(tf.matmul(V_arg,h_eval)+c_arg,[K])),[K,1]).numpy() )
# 出力yを出力結果保存ynに追加
yfinal = tf.cast(tf.greater(y_eval,0.5),tf.float32)
yn[n].assign(tf.reshape(yfinal,[K]))
### 評価
# tとyのマトリックス単位で比較し、正解率(Accuracy)を算出
m = tf.keras.metrics.Accuracy()
m.update_state(t,yn)
### 評価結果出力
decimals = 4
#print("### yn=",np.array_repr(np.round(yn.numpy(),decimals)).replace('\n', '').replace(' ', ''))
#print("### tn=",np.array_repr(np.round(t.numpy(),decimals)).replace('\n', '').replace(' ', ''))
print("### 正解率(Accuracy) :",m.result().numpy())
print("### 点数(Score) :",sum([yn[i].numpy()==t[i].numpy() for i in range(N)]),"/",N)
~略~
Epoc= 100 No. = 158
x1,x2 = array([0.1587, 1.0442])
t = array([0.])
w1,w2 = array([[0.7214,-3.0339],[0.7214,-3.0339]])
b = array([[0.8721],[0.8721]])
h1,h2 = array([[0.1014],[0.1014]])
v1,v2 = array([[3.9006,3.9006]])
c = array([[-5.2937]])
y = array([[0.011]])
dv1,dv2 = array([[-0.0011,-0.0011]])
dc = array([[-0.011]])
dw1,dw2 = array([[-0.0006,-0.0041],[-0.0006,-0.0041]])
db = array([[-0.0039],[-0.0039]])
Epoc= 100 No. = 159
x1,x2 = array([-0.6342, 0.9228])
t = array([0.])
w1,w2 = array([[0.7213,-3.0344],[0.7213,-3.0344]])
b = array([[0.8717],[0.8717]])
h1,h2 = array([[0.0842],[0.0842]])
v1,v2 = array([[3.9005,3.9005]])
c = array([[-5.2948]])
y = array([[0.0096]])
dv1,dv2 = array([[-0.0008,-0.0008]])
dc = array([[-0.0096]])
dw1,dw2 = array([[0.0018,-0.0027],[0.0018,-0.0027]])
db = array([[-0.0029],[-0.0029]])
### 正解率(Accuracy) : 0.9
### 点数(Score) : [36] / 40
(1-4) モデルの評価の実装例②(Keras)
- モデルのコンパイル時に
metrics='accuracy'を指定(Keras公式ドキュメント)
model.compile(loss='binary_crossentropy', optimizer=SGD(lr=0.05), metrics=['accuracy'])

↓
model.evaluate([入力],[正解])で評価
evaluation = model.evaluate(X_test, t_test)
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import SGD
from sklearn.model_selection import train_test_split
from sklearn.utils import shuffle
from sklearn import datasets
# 入力xの次元
M = 2
# 隠れ層hの次元(クラス数)
J = 4
# 出力yの次元(クラス数)
K = 1
# 入力データセットの総
nc = 300
# 入力データセットの総数
N = nc * K
# エポック数
epoch_num = 100
# ミニバッチのサイズ
mini_batch_size = 20
def multi_layer_perceptron(X_train,t_train,X_test,t_test):
############################################
# STEP1:モデルの定義
############################################
# 入力の電気信号x、正解値tの定義の初期化(トレーニングデータ)
X,t = np.array(X_train),np.array(t_train)
#X_,t_ = shuffle(X,t)
# 入力層 - 隠れ層の定義
# Dense(input_dim=M, units=J):入力がM次元、出力がJ次元のネットワーク
# ⇒ W[J行×M列] × xn[M行×1列] + b[J行×1列]に相当
# Activation('sigmoid'):活性化関数として、シグモイド関数を指定
# ⇒ y = σ(wx + b)に相当
model = Sequential()
model.add(Dense(input_dim=M, units=J))
model.add(Activation('sigmoid'))
# 隠れ層 - 出力層の定義
# Dense(units=K):出力がK次元のネットワーク
# ⇒ V[K行×J列] × h[J行×1列] + c[K行×1列]に相当
model.add(Dense(units=K))
model.add(Activation('sigmoid'))
############################################
# STEP2:誤差関数の定義
############################################
# ⇒compile時の引数として「binary_crossentropy」を指定
############################################
# STEP3:最適化手法の定義(例:確率的勾配降下法)
############################################
# loss='binary_crossentropy'
# 誤差関数の種類を指定。
# 2値(発火する/しない)の交差エントロピー関数の計算をさせる。
# SGD(lr=0.1)
# 最適化の手法を指定している。「SGD」は確率的勾配降下法で「lr」はその学習率。
# それぞれ「Stochastic Gradient Descent」と「learning rate」の頭文字を取っている。
# metrics=['accuracy']
# このオプションを指定する事で、モデルの評価(Accuracyの計算)を行ってくれます。
model.compile(loss='binary_crossentropy',optimizer=SGD(lr=0.05),metrics=['accuracy'])
############################################
# STEP4:セッションの初期化
############################################
# ⇒今回は不要
# (TensorFlow v2以降はSessionを使用しないため)
############################################
# STEP5:学習
############################################
# 指定したエポック数、繰り返し学習を行う
# 第1引数:Xは入力データ(入力の電気信号)
# 第2引数:tは正解データ(出力の電気信号の正解値)
# 第3引数:エポック(データ全体に対する反復回数)の数
# 第4引数:ミニバッチ勾配降下法(N個の入力データをM個ずつのグループに分けて学習する際のMの値)
model.fit(X, t, epochs=epoch_num, batch_size=mini_batch_size)
############################################
# STEP6:学習結果の確認
############################################
# 分類が正しい結果になっているか?(発火するかどうか?が正しい結果になっているか)
classes = (model.predict(X,batch_size=mini_batch_size) > 0.5).astype("int32")
# ネットワークの出力「y」の計算結果を取得
prob = model.predict(X,batch_size=mini_batch_size)
print("*******************************")
print("classified: ",np.array_repr(t==classes).replace('\n', '').replace(' ', ''))
print("probability: ",np.array_repr(np.round(prob,4)).replace('\n', '').replace(' ', ''))
print("*******************************")
############################################
# STEP7:学習結果の評価
############################################
# 入力の電気信号x、正解値tの定義の初期化(テストデータ)
X_,t_ = np.array(X_test),np.array(t_test)
evaluation = model.evaluate(X_,t_)
print(evaluation)
def main():
# データの生成
X, t = datasets.make_moons(N, noise=0.3)
# データをトレーニング用/評価用とに分類
T = t.reshape(N,1)
X_train, X_test, T_train, T_test = train_test_split(X, T, train_size=0.8)
# トレーニング&評価
multi_layer_perceptron(X_train, T_train, X_test, T_test)
if __name__ == "__main__":
main()

