はじめに
こんにちは、swim-loverです。Pythonで機械学習の一つである手書き数字認識を実装しています。 Pythonを始めたばかりですが、「使いながら覚える」をコンセプトに勉強しています。 第9回は、 参考図書の学習済重みデータを使用し、MNISTデータの推論処理を実装しました。今回は、機械学習の本丸?である学習処理を勉強したいと思います。参考図書にしたがって、自ら実装することにしてみました。
参考図書
今回、機械学習の参考書籍として、”斎藤康毅著 ゼロから作るDeep Learning オライリージャパン 2016年9月”を使用しました。
損失関数
ニューラルネットワークの学習は、最適な重みパラメータを見つけ出すことだと考えられます。では、どのようにして最適かどうかを判断するのでしょうか?
それは、損失関数によって、最適かどうかを判断することになります。具体的な関数を確認していきます。
二乗和誤差
二乗和誤差は、以下の式で表されます。ニューラルネットの出力と教示データとの差が大きければ大きいほど、二乗和誤差は大きい値になることがわかります。なお、二乗することで、y_k > t_kの場合とy_k < t_kの場合のどちらも差分として加味できるようにしています。(そうしないと、(y_k-t_k) > 0 の場合と(y_k -t_k) <0 のデータが打ち消しあってしまします。1/2のところは、この式を微分すると、いい感じに消えてくれそうですね。
前回までと同じく、Colab環境で二乗和誤差を実装して動作させてみました。参考書籍の内容とほぼ同じです。pythonで二乗は、”**2″と書くのですね。個人的には、^2の方がわかりやすい気がします。
sample data1は、学習データの出力は、正解の’2’の位置の確立が0.6で一番大きいですね。 この場合、二乗和誤差も値も小さくなっています。
一方、sample data2のように、正解以外の位置のデータ(‘9’の位置)の確立が高くなると、二乗和誤差も値も大きくなることが確認できました。
import numpy as np
def mean_squre_err(y,t):
return 0.5* np.sum((y-t)**2)
#sample data 1
t=[0,0,1,0,0,0,0,0,0,0] # number is from 0 to 9, number 2 is correct
y=[0.1,0.01,0.6,0.0,0.0,0.1,0.02,0.1,0.1,0.04] #学習データの出力は、'2'の位置の確立が0.6
ans = mean_squre_err(np.array(y),np.array(t)) #0.10105000000000001
print(ans)
#sample data 2
t=[0,0,1,0,0,0,0,0,0,0] # number 2 is correct
y=[0.1,0.01,0.2,0.0,0.0,0.1,0.02,0.1,0.1,0.5]#学習データの出力は、'9'の位置の確立が0.5
ans = mean_squre_err(np.array(y),np.array(t)) #0.46525000000000005
print(ans)
交差エントロピー誤差
次に交差エントロピー誤差について進めます。 交差エントロピー誤差、すっと頭に入ってこない印象です。教師データが正解ラベルのみ’1’だとするデータの場合、一回の-logy_kの演算だけです。y_kが1.0に近ければ近いほど、交差エントロピー誤差は、0に近づきます。0に近づくところが使いやすいのかもしれません。
交差エントロピー誤差を実装してみました。
sample data1はニューラルネットの出力を0.99にしてみました。交差エントロピー誤差も、0に近い値になっています。
sample data2はニューラルネットの出力を0.2にしてみました。交差エントロピー誤差は、1.60になっています。これらの結果は想定通りです。
なお、deltaとして10^-7という小さな値を足し合わせています。これはy=0の場合、log(0)=-infが出力されることに備えての実装上のケアになります。また、e表記についても初めて触れました。1e2=10^2=100,1e-2=10^-2=0.01ですね。
import numpy as np
def corss_entropy_err(y,t):
delta=1e-7
return -np.sum(t*np.log(y+delta))
#sample data 1
t=[0,0,1,0,0,0,0,0,0,0] # number 2 is correct
y=[0.1,0.01,0.99,0.0,0.0,0.1,0.02,0.1,0.1,0.04]
ans = corss_entropy_err(np.array(y),np.array(t)) #0.010050234843405595
print(ans)
#sample data 2
t=[0,0,1,0,0,0,0,0,0,0] # number 2 is correct
y=[0.1,0.01,0.2,0.0,0.0,0.1,0.02,0.1,0.1,0.5]
ans = corss_entropy_err(np.array(y),np.array(t)) #1.6094374124342252
print(ans)
まとめ
今回、機会学習で使う損失関数の二乗和誤差、交差エントロピー誤差について実装してみました。
引き続き、ニューラルネットワークの学習について学んでいきたいと思います。
組み込み系ソフトエンジニアをしています。これまでフロントエンド技術は避けてきましたが、食わず嫌いをやめて、勉強を始めました。
趣味は、水泳、ロードバイク、ランニング、登山です。
組み込み系技術ネタ、勉強したフロントエンド技術、たまに趣味の運動について発信していきます。
どうぞよろしくお願いします。
コメント