未分類

損失関数で使う2乗和誤差をいじってみる

ニューラルネットワークに出てくる損失関数。
この損失関数は任意の関数を使っていいようなのだが、
2乗和誤差や交差エントロピー誤差などが使われるらしい。

そこで今回はこの2乗和誤差を使って、いろいろ数値いじりを
してみよう。

流れとしては、
変数yとtを用意。

yにはランダムな値を10個入れる。
そのままでは使いづらいので、この値をソフトマックス関数で
総和が1になるように改変する。

tには正解ラベルを入れる。
正解は1、不正解は0を入れる。
この表記法は「one-hot表現」と呼ばれる。

変数yとtを「2乗和誤差」関数に入れて、結果を判断する。

こんなところだろう。

ここで、損失関数に使われる「2乗和誤差」の数式はこちら。
手書きにて失礼。味があるという説もある(笑)。

nijyosiki

かっこが途切れているのはご愛嬌。

ykが出力。
tkが教師データ。
kはデータの次元数。

では実際に始める前に、素材をそれぞれ作っておこう。

まず、変数yにランダムな値を入れる。
ちなみにpython3で行う。

>>>import numpy as np
>>>y=np.random.choice(100,10)
>>>y
array([5,65,92,94,99,4,66,53,71,68])

100以下の値から10個の乱数をyに入れた。

お次は、変数tに正解の場所を入れる。
数字の1がたっている場所が正解。0は不正解。
これを「one-hot表現」と言う。
t=[0,0,0,0,1,0,0,0,0,0]

左端は0から始まるので0→1→2→3→④番目が正解。
わかりづらいっすねえ。

次は2乗和誤差。
こいつをpython3で表すと下記のようになる。

[py]

def nijyowa(y,t):
    return 0.5 * np.sum((y-t)**2)

[/py]

もういっちょ、ソフトマックス関数も使うので書いておこう。

[py]

def softmax(x):
    maxAtai= np.max(x)   #入力値の最大値を変数maxAtaiに入れる
    expA=np.exp(x-maxAtai)   #オーバーフローしないように
    sumexpA= np.sum(expA)
    y= expA / sumexpA
     
    return y

[/py]

さあ、以上で素材は揃った。
揃ったところで、python3のインタプリタで計算してみよう。

>>>import numpy as np
>>>y=np.random.choice(100,10)
>>>y
array([5,65,92,94,99,4,66,53,71,68])

ここでyの値をソフトマックス関数で総和が1になるように変える。

まずはソフトマックス関数を読み込み。
TABは要チェックで。

>>def softmax(x):
… maxAtai= np.max(x)
… expA=np.exp(x-maxAtai)
… sumexpA= np.sum(expA)
…y= expA / sumexpA
… return y

 

で、yの値を変える。
>>>y2=softmax(y)

>>>y2
array([ 1.48939217e-41, 1.70089686e-15, 9.04959183e-04,
6.68679417e-03, 9.92408247e-01, 5.47916758e-42,
4.62351703e-15, 1.04506715e-20, 6.86190769e-13,
3.41634267e-14])

今度は、tに正解ラベルを入れる。
>>>t=[0,0,0,0,1,0,0,0,0,0]

で、2乗和誤差関数を読み込み。

>>>def nijyowa(y,t):
… return 0.5 * np.sum((y-t)**2)

いよいよチェックです。
y2の値とtの値を2乗和誤差関数に渡します。

>>> nijyowa(np.array(y2),np.array(t))
5.158344314838917e-05

こいつは0.000051583…てことなので、限りなく0に近いと。
0に近い程、誤差が少ないってことなので、
yの値は正解ラベルのtと比べて、ほぼ誤差無しってことです。

試しに、y2の正解の値を別の値と交換してみましょう。

>>>y2
array([ 1.48939217e-41, 1.70089686e-15, 9.04959183e-04,
6.68679417e-03, 9.92408247e-01, 5.47916758e-42,
4.62351703e-15, 1.04506715e-20, 6.86190769e-13,
3.41634267e-14])
この「9.92408247e-01」をひとつ前の「6.68679417e-03」と交換します。

>>>y2Mis=np.array([ 1.48939217e-41, 1.70089686e-15, 9.04959183e-04,
9.92408247e-01, 6.68679417e-03, 5.47916758e-42,
4.62351703e-15, 1.04506715e-20, 6.86190769e-13,
3.41634267e-14])

で、こいつを先ほどの2乗和誤差関数に入れてみます。

>>> nijyowa(np.array(y2Mis),np.array(t))
0.98577303627050394

今度は、さっきより数値が上がった=誤差多すぎってことです。

どうでしょう。
こんな感じでニューラルネットワークの性能の良し、悪しを判断する
損失関数の基本が、なんとなくわかったような。

また後で交差エントロピー誤差もやってみましょう。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です