机器学习入门(08)— 损失函数作用和分类(均方误差、交叉熵误差)
神經網絡的學習中的“學習”是指從訓練數據中自動獲取最優權重參數的過程。
為了使神經網絡能進行學習,將導入損失函數這一指標。而學習的目的就是以該損失函數為基準,找出能使它的值達到最小的權重參數。為了找出盡可能小的損失函數的值,我們將介紹利用函數斜率的梯度法。
神經網絡的學習通過某個指標表示現在的狀態。然后,以這個指標為基準,尋找最優權重參數。
神經網絡的學習中所用的指標稱為損失函數(loss function)。這個損失函數可以使用任意函數,但一般用均方誤差和交叉熵誤差等。
損失函數是表示神經網絡性能的“惡劣程度”的指標,即當前的神經網絡對監督數據在多大程度上不擬合,在多大程度上不一致。
1. 為什么要設定損失函數
在神經網絡的學習中,尋找最優參數(權重和偏置)時,要尋找使損失函數的值盡可能小的參數。為了找到使損失函數的值盡可能小的地方,需要計算參數的導數(確切地講是梯度),然后以這個導數為指引,逐步更新參數的值。
假設有一個神經網絡,現在我們來關注這個神經網絡中的某一個權重參數。此時,對該權重參數的損失函數求導,表示的是“如果稍微改變這個權重參數的值,損失函數的值會如何變化”。
- 如果導數的值為負,通過使該權重參數向正方向改變,可以減小損失函數的值;
- 如果導數的值為正,則通過使該權重參數向負方向改變,可以減小損失函數的值;
- 當導數的值為 0 時,無論權重參數向哪個方向變化,損失函數的值都不會改變,此時該權重參數的更新會停在此處。
2. 損失函數分類
2.1 均方誤差
可以用作損失函數的函數有很多,其中最有名的是均方誤差(mean squared error )。均方誤差如下式所示。
這里,yk 是表示神經網絡的輸出,tk 表示監督數據,k 表示數據的維數。
舉例如下:手寫數字識別的例子中,yk、tk 是由如下10 個元素構成的數據。
In [1]: y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]In [2]: t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]In [3]:
數組元素的索引從第一個開始依次對應數字 0, 1, 2 …… 這里,神經網絡的輸出 y 是 softmax 函數的輸出。
由于 softmax 函數的輸出可以理解為概率,因此上例表示 0 的概率是0.1,1 的概率是 0.05,2 的概率是 0.6 等。
t 是監督數據,將正確解標簽設為 1,其他均設為 0。這里,標簽 2 為 1,表示正確解是 2 。
將正確解標簽表示為 1,其他標簽表示為 0 的表示方法稱為 one-hot 表示。
代碼實現如下:
In [3]: import numpy as npIn [4]: def mean_square(y, t):...: return 0.5 * np.sum((y - t)**2)In [5]:
實際使用示例:
# 假設 2 為正確的預測值
In [5]: t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0] # 2 的概率最高為 0.6
In [6]: y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]In [7]: mean_square(np.array(y), np.array(t))
Out[7]: 0.09750000000000003# 7 的概率最高為 0.6
In [8]: y = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]In [9]: mean_square(np.array(y), np.array(t))
Out[9]: 0.5975In [10]:
第一個例子中,正確解是 2 ,神經網絡的輸出的最大值是概率值為 2;
第二個例子中,正確解是 2, 神經網絡的輸出的最大值是概率值為 7;
如實驗結果所示,我們發現第一個例子的損失函數的值更小,和監督數據之間的誤差較小。也就是說,均方誤差顯示第一個例子的輸出結果與監督數據更加吻合。
2.2 交叉熵誤差
交叉熵誤差(cross entropy error)也經常被用作損失函數。交叉熵誤差如下式所示。
這里,log 表示以 e 為底數的自然對數(log e)。yk 是神經網絡的輸出,tk是正確解標簽。并且,tk 中只有正確解標簽的索引為1,其他均為 0(one-hot 表示)。因此,式(4.2)實際上只計算對應正確解標簽的輸出的自然對數。
In [10]: np.log(np.e)
Out[10]: 1.0In [11]: np.log(np.e **2)
Out[11]: 2.0In [12]:
比如,假設正確解標簽的索引是 2 ,
- 與之對應的神經網絡的輸出是0.6,則交叉熵誤差是?log 0.6 = 0.51;
- 若 2 對應的輸出是 0.1,則交叉熵誤差為?log 0.1 = 2.30;
也就是說,交叉熵誤差的值是由正確解標簽所對應的輸出結果決定的。
自然對數的代碼和圖像如下所示:
import numpy as np
import matplotlib.pylab as pltdef log_e(x):return np.log(x)x = np.arange(-5.0, np.e, 0.1)
y = log_e(x)
plt.plot(x, y)
plt.xlabel("x") # x軸標簽
plt.ylabel("y") # y軸標簽
plt.ylim(-2, 1.2) # 指定y軸的范圍
plt.title('log_e') # 標題
plt.legend()
plt.show()
如上圖所示,x 等于1 時,y 為0;隨著 x 向 0 靠近,y 逐漸變小。因此,正確解標簽對應的輸出越大,式(4.2)的值越接近 0;當輸出為 1 時,交叉熵誤差為 0。此外,如果正確解標簽對應的輸出較小,則式(4.2)的值較大。
用代碼實現如下:
In [1]: import numpy as npIn [2]: def cross_entropy(y, t):...: delta = 1e-7...: return -np.sum(t*np.log(y+delta))...: In [3]: 1e-7
Out[3]: 1e-07In [4]:
參數 y 和 t 是 NumPy 數組。函數內部在計算 np.log 時,加上了一個微小值 delta 。這是因為,當出現np.log(0) 時,np.log(0) 會變為負無限大的 -inf ,這樣一來就會導致后續計算無法進行。作為保護性對策,添加一個微小值可以防止負無限大的發生。
In [4]: t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]In [5]: y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]In [6]: cross_entropy(np.array(y), np.array(t))
Out[6]: 0.510825457099338In [7]: y = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]In [8]: cross_entropy(np.array(y), np.array(t))
Out[8]: 2.302584092994546In [9]:
第一個例子中,正確解標簽對應的輸出為 0.6,此時的交叉熵誤差大約為 0.51。
第二個例子中,正確解標簽對應的輸出為0.1 的低值,此時的交叉熵誤差大約為 2.3。
由此可以看出,與前面的理論描述是一致的。
2.3 mini-batch學習
2.4 mini-batch版交叉熵誤差的實現
參考:《深度學習入門:基于Python的理論與實現》
總結
以上是生活随笔為你收集整理的机器学习入门(08)— 损失函数作用和分类(均方误差、交叉熵误差)的全部內容,希望文章能夠幫你解決所遇到的問題。