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