损失函数、python实现均方误差、交叉熵误差函数、mini-batch的损失函数
損失函數
- what is 損失函數
- 均方誤差
- 交叉熵誤差
- 計算mini-batch學習的損失函數
- why 損失函數
what is 損失函數
神經網絡學習目標是找到各層合適的權重參數w和偏置b,使得最終的輸出結果能夠與實際結果更加接近。那神經網絡的這些權重參數是如何得到的:靠損失函數這個指標來進行一步步訓練優化得到。
通過使損失函數最小,來尋找最優權重參數。學習的目的就是以該損失函數為基準,找出能使它的值達到最小的權重參數。
均方誤差
yk是神經網絡的輸出, tk是監督數據, k是數據的維數。
用python實現均方誤差函數:
def mean_squared_error(y, t):return 0.5 * np.sum((y-t)**2)下面是調用這個函數的例子:
以手寫數字識別為例,數組下標對應的是0-9的數字,y1和y2是神經網絡經過softmax函數的輸出,y1、y2的元素值是該網絡經過判斷這張圖片,得到的0-9數字的概率。t是監督數據,t[2]=1,表明這張圖片是2 。看到均方誤差輸出結果,可以發現,y1的損失函數比y2小,這是因為y1[2]=0.6,而y2[2]=0.1,也就是說y1估計出來的更接近真實的判斷。
# coding: utf-8 import sys, os sys.path.append(os.pardir) # 為了導入父目錄的文件而進行的設定 import numpy as np from common.functions import mean_squared_errorif __name__ == '__main__':y1 = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]y2 = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]r1 = mean_squared_error(np.array(y1), np.array(t))print(r1)r2 = mean_squared_error(np.array(y2), np.array(t))print(r2)輸出:
0.09750000000000003 0.5975交叉熵誤差
yk是神經網絡的輸出, tk是正確解標簽, k表示數據的維數。
如果標簽為one-hot表示,即tk中只有正確解標簽索引為1,其他均為0 。
那么式子只計算對應正確解標簽的輸出的自然對數。
如上面的例子,t[2]=1,正確解標簽索引為2,對應的神經網絡輸出為y1[2]=0.6,則交叉熵誤差為-log0.6。
由上圖y=logx曲線可看出,對于對數函數y=logx,x=1時,y=0;
交叉熵誤差是一個-log函數,也就意味著,交叉熵誤差值越小,神經網絡在對應正確解標簽的輸出越接近1,即神經網絡的判斷和正確解標簽越接近。
用python實現交叉熵誤差函數:
函數里面的參數y、t是Numpy數組,函數計算log時,加上了一個微小值,這是防止出現np.log(0)導致后續計算無法進行。
def cross_entropy_error(y, t):delta = 1e-7return -np.sum(t * np.log(y + delta))調用這個函數的例子:和均方誤差調用的例子類似。
import sys, os sys.path.append(os.pardir) # 為了導入父目錄的文件而進行的設定 import numpy as np from common.functions import cross_entropy_errorif __name__ == '__main__':y1 = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]y2 = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]r1 = cross_entropy_error(np.array(y1), np.array(t))print(r1)r2 = cross_entropy_error(np.array(y2), np.array(t))print(r2)輸出:
0.510825457099338 2.302584092994546計算mini-batch學習的損失函數
上述僅對單個數據進行了損失函數的計算,實際工程中,要把所有訓練數據的損失函數的總和作為學習的指標。以交叉熵誤差為例:
數據有N個, tnk表示第n個數據的第k個元素的值( ynk是神經網絡的輸出, tnk是監督數據)。
這個式子,也就是把所有數據的損失函數值加起來再除以總的數據個數。通過除以N可以求單個數據的平均損失函數,與訓練數據的數量無關。
由于數據集的數據量可能會很大,求全部數據的損失函數的和,將花費很長時間。可以從全部數據中抽出一小部分數據,作為全部數據的近似,稱為mini-batch(小批量),然后對每個mini-batch學習。
下面介紹一下如何使用python進行mini-batch的損失函數計算。
首先,從訓練數據中隨機抽取數據得到mini-batch:
調用(x_train, t_train), (x_test, t_test) = load_mnist(one_hot_label=True, normalize=True)函數,讀取出MINIST數據,輸出x_train.shape、t_train.shape可以看到,訓練數據有60000個。使用np.random.choice(train_size, batch_size)可以從0到train_size-1之間隨機選擇batch_size個數字。輸出batch_mask可以得到一個索引數組。把索引對應的數據存到小批量數據集里,抽出來的數據就有了。也就是說在60000個數據里面隨機選了十個數據,存到了x_batch、t_batch里面。
輸出:
(60000, 784) (60000, 10) [44839 5657 46048 51825 44057 50445 1374 19821 38720 14117] (10, 784) (10, 10)之后,編寫mini-batch版本的交叉熵誤差函數:
函數參數y是神經網絡輸出,它是個二維的,第一維是該數據在mini-batch數據集里面的索引,第二維是數據,t是監督數據。y[np.arange(batch_size), t] 能抽出各個數據正確解標簽對應的神經網絡的輸出。
重點的是,只用求神經網絡在正確解標簽處的輸出。舉個例子y[0,2],這就取出來了mini-batch里面第一個數據在2處的輸出。
def cross_entropy_error(y, t):if y.ndim == 1:t = t.reshape(1, t.size)y = y.reshape(1, y.size)# 監督數據是one-hot-vector的情況下,轉換為正確解標簽的索引if t.size == y.size:t = t.argmax(axis=1)batch_size = y.shape[0]return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7)) / batch_sizewhy 損失函數
尋找最優權重和偏置時,要使損失函數盡可能小。
為什么不能用識別精度來作為指標,使讓精度盡可能高,來尋找最優參數?
我的理解是,精度是除法做出來的,對網絡的權重和偏置調整后,可能除法的結果沒什么變化,也有可能出現突然的變化。這樣的話無法進行調優,因為結果是不連續的。
總結
以上是生活随笔為你收集整理的损失函数、python实现均方误差、交叉熵误差函数、mini-batch的损失函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 今日头条ocpm计费规则_入门篇|信息流
- 下一篇: STM32 串口接收流程-串口接收中断