轉(zhuǎn)自:

創(chuàng)新互聯(lián)從2013年成立,我們提供高端網(wǎng)站建設(shè)、小程序制作、電商視覺設(shè)計、app軟件開發(fā)公司及網(wǎng)絡(luò)營銷搜索優(yōu)化服務(wù),在傳統(tǒng)互聯(lián)網(wǎng)與移動互聯(lián)網(wǎng)發(fā)展的背景下,我們堅守著用標(biāo)準(zhǔn)的設(shè)計方案與技術(shù)開發(fā)實力作基礎(chǔ),以企業(yè)及品牌的互聯(lián)網(wǎng)商業(yè)目標(biāo)為核心,為客戶打造具商業(yè)價值與用戶體驗的互聯(lián)網(wǎng)+產(chǎn)品。
注意 :tensorflow交叉熵計算函數(shù)輸入中的logits都不是softmax或sigmoid的 輸出 ,而是softmax或sigmoid函數(shù)的 輸入 ,因為它在 函數(shù)內(nèi)部進(jìn)行sigmoid或softmax操作
tf.nn.sigmoid_cross_entropy_with_logits(_sentinel=None,labels=None, logits=None, name=None)
參數(shù): ?? _sentinel:本質(zhì)上是不用的參數(shù),不用填
? ? ?? logits:一個數(shù)據(jù)類型(type)是float32或float64;
? ? ?? shape:[batch_size,num_classes],單樣本是[num_classes]
? ? ?? labels:和logits具有相同的type(float)和shape的張量(tensor),
? ? ?? name:操作的名字,可填可不填
輸出:
? ? ?? loss,shape:[batch_size,num_classes]
Note: 它對于輸入的logits先通過sigmoid函數(shù)計算,再計算它們的交叉熵,但是它對交叉熵的計算方式進(jìn)行了優(yōu)化,使得結(jié)果不至于溢出。它適用于每個類別相互獨立但互不排斥的情況:例如一幅圖可以同時包含一條狗和一只大象。output不是一個數(shù),而是一個batch中每個樣本的loss,所以一般配合tf.reduce_mea(loss)使用
計算公式:
Python 程序:
輸出的E1,E2結(jié)果相同
tf.nn.softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, dim=-1, name=None)argument:
_sentinel: 本質(zhì)上是不用的參數(shù),不用填
logits:一個數(shù)據(jù)類型(type)是float32或float64;
shape :[batch_size,num_classes]
labels:和logits具有相同type和shape的張量(tensor),,是一個有效的概率,sum(labels)=1, one_hot=True(向量中只有一個值為1.0,其他值為0.0)
name:操作的名字,可填可不填
output: loss,shape:[batch_size]
Note: 它對于輸入的logits先通過softmax( 不同于sigmoid )函數(shù)計算,再計算它們的交叉熵,但是它對交叉熵的計算方式進(jìn)行了優(yōu)化,使得結(jié)果不至于溢出。它適用于每個類別相互獨立且排斥的情況,一幅圖只能屬于一類,而不能同時包含一條狗和一只大象。output不是一個數(shù),而是一個batch中每個樣本的loss,所以一般配合tf.reduce_mean(loss)使用。
計算公式:
Python程序:
import tensorflow as tf
import numpy as np
def softmax(x):
sum_raw = np.sum(np.exp(x),axis=-1)
x1 = np.ones(np.shape(x))
for i in range(np.shape(x)[0]):
? ? x1[i] = np.exp(x[i])/sum_raw[i]
return x1
y = np.array([[1,0,0],[0,1,0],[0,0,1],[1,0,0],[0,1,0]])#每一行只有一個1
logits =np.array([[12,3,2],[3,10,1],[1,2,5],[4,6.5,1.2],[3,6,1]])
y_pred =softmax(logits)
E1 = -np.sum(y*np.log(y_pred),-1)
print(E1)
sess = tf.Session()
y = np.array(y).astype(np.float64)
E2 = sess.run(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=logits))
print(E2)
輸出的E1,E2結(jié)果相同
tf.nn.sparse_softmax_cross_entropy_with_logits(_sentinel=None,labels=None,logits=None, name=None)
argument:
_sentinel:本質(zhì)上是不用的參數(shù),不用填
logits:一個數(shù)據(jù)類型(type)是float32或float64;
shape:[batch_size,num_classes]
labels: shape為[batch_size],labels[i]是{0,1,2,……,num_classes-1}的一個索引, type為int32或int64
name:操作的名字,可填可不填
output:
loss,shape:[batch_size]
Note:它對于輸入的logits先通過softmax函數(shù)計算,再計算它們的交叉熵,但是它對交叉熵的計算方式進(jìn)行了優(yōu)化,使得結(jié)果不至于溢出
它適用于每個類別相互獨立且排斥的情況,一幅圖只能屬于一類,而不能同時包含一條狗和一只大象
output不是一個數(shù),而是一個batch中每個樣本的loss,所以一般配合tf.reduce_mean(loss)使用
計算公式:
和tf.nn.softmax_cross_entropy_with_logits()一樣,只是要將labels轉(zhuǎn)換成tf.nn.softmax_cross_entropy_with_logits()中l(wèi)abels的形式
tf.nn.weighted_cross_entropy_with_logits(labels,logits, pos_weight, name=None)
計算具有權(quán)重的sigmoid交叉熵sigmoid_cross_entropy_with_logits()
argument:
_sentinel:本質(zhì)上是不用的參數(shù),不用填
logits:一個數(shù)據(jù)類型(type)是float32或float64;
shape:[batch_size,num_classes],單樣本是[num_classes]
labels:和logits具有相同的type(float)和shape的張量(tensor),
pos_weight:正樣本的一個系數(shù)
name:操作的名字,可填可不填
output:
loss,shape:[batch_size,num_classes]
計算公式:
平滑函數(shù)。
交叉熵?fù)p失函數(shù),也稱為對數(shù)損失或者logistic損失。當(dāng)模型產(chǎn)生了預(yù)測值之后,將對類別的預(yù)測概率與真實值(由0或1組成)進(jìn)行不比較,計算所產(chǎn)生的損失,然后基于此損失設(shè)置對數(shù)形式的懲罰項。
在神經(jīng)網(wǎng)絡(luò)中,所使用的Softmax函數(shù)是連續(xù)可導(dǎo)函數(shù),這使得可以計算出損失函數(shù)相對于神經(jīng)網(wǎng)絡(luò)中每個權(quán)重的導(dǎo)數(shù)(在《機(jī)器學(xué)習(xí)數(shù)學(xué)基礎(chǔ)》中有對此的完整推導(dǎo)過程和案例,這樣就可以相應(yīng)地調(diào)整模型的權(quán)重以最小化損失函數(shù)。
擴(kuò)展資料:
注意事項:
當(dāng)預(yù)測類別為二分類時,交叉熵?fù)p失函數(shù)的計算公式如下圖,其中y是真實類別(值為0或1),p是預(yù)測類別的概率(值為0~1之間的小數(shù))。
計算二分類的交叉熵?fù)p失函數(shù)的python代碼如下圖,其中esp是一個極小值,第五行代碼clip的目的是保證預(yù)測概率的值在0~1之間,輸出的損失值數(shù)組求和后,就是損失函數(shù)最后的返回值。
參考資料來源:百度百科-交叉熵
參考資料來源:百度百科-損失函數(shù)
一條信息的信息量大小和它的不確定性有很大的關(guān)系 。一句話如果需要很多外部信息才能確定,我們就稱這句話的信息量比較大。比如你聽到“云南西雙版納下雪了”,那你需要去看天氣預(yù)報、問當(dāng)?shù)厝说鹊炔樽C(因為云南西雙版納從沒下過雪)。相反,如果和你說“人一天要吃三頓飯”,那這條信息的信息量就很小,因為這條信息的確定性很高。
那我們就能將事件 的信息量定義如下(其中 表示事件 發(fā)生的概率):
信息量是對于單個事件來說的 ,但是實際情況一件事有很多種發(fā)生的可能,比如擲骰子有可能出現(xiàn)6種情況,明天的天氣可能晴、多云或者下雨等等。 熵是表示隨機(jī)變量不確定的度量,是對所有可能發(fā)生的事件產(chǎn)生的信息量的期望 。公式如下:
的曲線如下:
結(jié)合熵的公式(2)以及 曲線,當(dāng)這些所有可能發(fā)生事件的概率比較小(接近0)或者比較大(接近1)時,熵的值會比較小;如果事件發(fā)生的概率既遠(yuǎn)離0也遠(yuǎn)離1時,熵的值就會比較大。
例如,如下三組事件比較:
1)事件概率均等,[0.2500, 0.2500, 0.2500, 0.2500],熵為2;
2)事件概率比較靠近0或者1,[0.1, 0.1, 0.1, 0.7],熵為1.3568;
3)事件概率極其靠近0或者1,[0.001, 0.001, 0.001, 0.999],熵為0.0313.
熵的一種比較特殊的情況就是擲硬幣 ,只有正、反兩種情況,該種情況(二項分布或者0-1分布)熵的計算可以簡化如下:
其中, 表示正面概率。
相對熵又稱KL散度,用于衡量對于同一個隨機(jī)變量 的兩個分布 和 之間的差異 。在機(jī)器學(xué)習(xí)中, 常用于描述樣本的真實分布 ,例如[1,0,0,0]表示樣本屬于第一類,而 則常常用于表示預(yù)測的分布 ,例如[0.7,0.1,0.1,0.1]。顯然使用q(x)來描述樣本不如 準(zhǔn)確, 需要不斷地學(xué)習(xí)來擬合準(zhǔn)確的分布 。
KL散度的公式如下:
KL散度的值越小表示兩個分布越接近。
我們將KL散度的公式進(jìn)行變形,得到:
前半部分就是 的熵,后半部分就是我們的交叉熵:
機(jī)器學(xué)習(xí)中,我們常常使用KL散度來評估predict和label之間的差別,但是由于KL散度的前半部分是一個常量,所以我們常常將后半部分的交叉熵作為損失函數(shù),其實二者是一樣的。
交叉熵代價函數(shù)(Cross-entropy cost function)是用來衡量人工神經(jīng)網(wǎng)絡(luò)(ANN)的預(yù)測值與實際值的一種方式。與二次代價函數(shù)相比,它能更有效地促進(jìn)ANN的訓(xùn)練。在介紹交叉熵代價函數(shù)之前,本文先簡要介紹二次代價函數(shù),以及其存在的不足。
ANN的設(shè)計目的之一是為了使機(jī)器可以像人一樣學(xué)習(xí)知識。人在學(xué)習(xí)分析新事物時,當(dāng)發(fā)現(xiàn)自己犯的錯誤越大時,改正的力度就越大。比如投籃:當(dāng)運動員發(fā)現(xiàn)自己的投籃方向離正確方向越遠(yuǎn),那么他調(diào)整的投籃角度就應(yīng)該越大,籃球就更容易投進(jìn)籃筐。同理, 我們希望:ANN在訓(xùn)練時,如果預(yù)測值與實際值的誤差越大,那么在反向傳播訓(xùn)練的過程中,各種參數(shù)調(diào)整的幅度就要更大,從而使訓(xùn)練更快收斂。 然而,如果使用二次代價函數(shù)訓(xùn)練ANN,看到的實際效果是,如果誤差越大,參數(shù)調(diào)整的幅度可能更小,訓(xùn)練更緩慢。
以一個神經(jīng)元的二類分類訓(xùn)練為例,進(jìn)行兩次實驗(ANN常用的激活函數(shù)為sigmoid函數(shù),該實驗也采用該函數(shù)):輸入一個相同的樣本數(shù)據(jù)x=1.0(該樣本對應(yīng)的實際分類y=0);兩次實驗各自隨機(jī)初始化參數(shù),從而在各自的第一次前向傳播后得到不同的輸出值,形成不同的代價(誤差):
在實驗1中,隨機(jī)初始化參數(shù),使得第一次輸出值為0.82(該樣本對應(yīng)的實際值為0);經(jīng)過300次迭代訓(xùn)練后,輸出值由0.82降到0.09,逼近實際值。而在實驗2中,第一次輸出值為0.98,同樣經(jīng)過300迭代訓(xùn)練,輸出值只降到了0.20。
從兩次實驗的代價曲線中可以看出: 實驗1的代價隨著訓(xùn)練次數(shù)增加而快速降低,但實驗2的代價在一開始下降得非常緩慢;直觀上看,初始的誤差越大,收斂得越緩慢。
其實,誤差大導(dǎo)致訓(xùn)練緩慢的原因在于使用了二次代價函數(shù)。二次代價函數(shù)的公式如下:
其中, 表示代價, 表示樣本, 表示實際值, 表示輸出值, 表示樣本的總數(shù)。為簡單起見,同樣一個樣本為例進(jìn)行說明,此時二次代價函數(shù)為:
目前訓(xùn)練ANN最有效的算法是反向傳播算法 。簡而言之,訓(xùn)練ANN就是通過反向傳播代價,以減少代價為導(dǎo)向,調(diào)整參數(shù)。參數(shù)主要有:神經(jīng)元之間的連接權(quán)重 ,以及每個神經(jīng)元本身的偏置 。調(diào)參的方式是采用梯度下降算法(Gradient descent),沿著梯度方向調(diào)整參數(shù)大小。 和 的梯度推導(dǎo)如下:
其中, 表示神經(jīng)元的輸入, 表示激活函數(shù)。從以上公式可以看出, 和 的梯度跟激活函數(shù)的梯度成正比,激活函數(shù)的梯度越大, 和 的大小調(diào)整得越快,訓(xùn)練收斂得就越快。而神經(jīng)網(wǎng)絡(luò)常用的激活函數(shù)為sigmoid函數(shù),該函數(shù)的曲線如下所示:
如圖所示, 實驗2的初始輸出值(0.98)對應(yīng)的梯度明顯小于實驗1的輸出值(0.82),因此實驗2的參數(shù)梯度下降得比實驗1慢。這就是初始的代價(誤差)越大,導(dǎo)致訓(xùn)練越慢的原因。 與我們的期望不符,即:不能像人一樣,錯誤越大,改正的幅度越大,從而學(xué)習(xí)得越快。
可能有人會說,那就選擇一個梯度不變化或變化不明顯的激活函數(shù)不就解決問題了嗎?那樣雖然簡單粗暴地解決了這個問題,但可能會引起其他更多更麻煩的問題。而且,類似sigmoid這樣的函數(shù)(比如tanh函數(shù))有很多優(yōu)點,非常適合用來做激活函數(shù),具體請自行g(shù)oogle之。
換個思路,我們不換激活函數(shù),而是換掉二次代價函數(shù),改用交叉熵代價函數(shù):
其中, 表示樣本, 表示樣本的總數(shù)。那么,重新計算參數(shù) 的梯度:
因此, 的梯度公式中原來的 被消掉了;另外,該梯度公式中的 表示輸出值與實際值之間的誤差。所以,當(dāng)誤差越大,梯度就越大,參數(shù) 調(diào)整得越快,訓(xùn)練速度也就越快。 實際情況證明,交叉熵代價函數(shù)帶來的訓(xùn)練效果往往比二次代價函數(shù)要好。
在實際分類任務(wù)中,要先將輸出層的輸出值經(jīng)過Softmax函數(shù),再經(jīng)過log函數(shù),最后才用交叉熵?fù)p失函數(shù)計算損失。
pytorch中有計算交叉熵?fù)p失的接口,即 F.cross_entropy() ,不過該接口包含了Softmax函數(shù)、log函數(shù)、交叉熵?fù)p失函數(shù)。也就是說 F.cross_entropy() = F.softmax() + torch.log() + F.nnl_loss() 。即使如此,也要使用 F.cross_entropy() ,不僅是因為它簡單,更因為它能保證數(shù)值穩(wěn)定。
機(jī)器學(xué)習(xí)的過程就是希望在訓(xùn)練數(shù)據(jù)熵 模型學(xué)到的分布 和 真實的分布 越近越好,我們知道KL散度可以表示兩個分布之間的不同。
但我們沒有真實數(shù)據(jù)的分布,那么只能退而求其次,希望模型學(xué)到的分布和訓(xùn)練數(shù)據(jù)的分布 ,也就是把訓(xùn)練數(shù)據(jù)當(dāng)做模型和真實數(shù)據(jù)之間的代理人 。假設(shè)訓(xùn)練數(shù)據(jù)是從總體中獨立同步分布采樣(Independent and identically distributed sampled)而來,那么我們可以利用最小化訓(xùn)練數(shù)據(jù)的經(jīng)驗誤差來降低模型的泛化誤差。簡單說:
由此非常理想化的看法是如果 模型(左) 能夠?qū)W到 訓(xùn)練數(shù)據(jù)(中) 的分布,那么應(yīng)該近似的學(xué)到了 真實數(shù)據(jù)(右) 的分布: 近似于 近似于
簡單的交叉熵,你真的懂了嗎?
交叉熵?fù)p失函數(shù)
????在使用pytorch深度學(xué)習(xí)框架,計算損失函數(shù)的時候經(jīng)常回到這么一個個函數(shù):
????該損失函數(shù)結(jié)合了 和 兩個函數(shù)。它在做分類(具體幾類)訓(xùn)練的時候是非常有用的。在訓(xùn)練過程中,對于每個類分配權(quán)值,可選的參數(shù)權(quán)值應(yīng)該是一個1D張量。當(dāng)你有一個不平衡的訓(xùn)練集時,這是是非常有用的。那么針對這個函數(shù),下面將做詳細(xì)的介紹。
???? 交叉熵主要是用來判定實際的輸出與期望的輸出的接近程度 ,為什么這么說呢,舉個例子:在做分類的訓(xùn)練的時候,如果一個樣本屬于第K類,那么這個類別所對應(yīng)的的輸出節(jié)點的輸出值應(yīng)該為1,而其他節(jié)點的輸出都為0,即[0,0,1,0,….0,0],這個數(shù)組也就是樣本的Label,是神經(jīng)網(wǎng)絡(luò)最期望的輸出結(jié)果。也就是說用它來衡量網(wǎng)絡(luò)的輸出與標(biāo)簽的差異,利用這種差異經(jīng)過反向傳播去更新網(wǎng)絡(luò)參數(shù)。
在說交叉熵之前,先說一下 信息量 與 熵 。
???? 信息量: 它是用來衡量一個事件的不確定性的;一個事件發(fā)生的概率越大,不確定性越小,則它所攜帶的信息量就越小。假設(shè)X是一個離散型隨機(jī)變量,其取值集合為X,概率分布函數(shù)為 ,我們定義事件 的信息量為:
當(dāng) 時,熵將等于0,也就是說該事件的發(fā)生不會導(dǎo)致任何信息量的增加。
???? 熵: 它是用來衡量一個系統(tǒng)的混亂程度的,代表一個系統(tǒng)中信息量的總和;信息量總和越大,表明這個系統(tǒng)不確定性就越大。
????舉個例子:假如小明和小王去打靶,那么打靶結(jié)果其實是一個0-1分布,X的取值有{0:打中,1:打不中}。在打靶之前我們知道小明和小王打中的先驗概率為10%,99.9%。根據(jù)上面的信息量的介紹,我們可以分別得到小明和小王打靶打中的信息量。但是如果我們想進(jìn)一步度量小明打靶結(jié)果的不確定度,這就需要用到熵的概念了。那么如何度量呢,那就要采用 期望 了。我們對所有可能事件所帶來的信息量求期望,其結(jié)果就能衡量小明打靶的不確定度:
與之對應(yīng)的,小王的熵(打靶的不確定度)為: ????雖然小明打靶結(jié)果的不確定度較低,畢竟十次有9次都脫靶;但是小王打靶結(jié)果的不確定度更低,1000次射擊只有1次脫靶,結(jié)果相當(dāng)?shù)拇_定。
???? 交叉熵: 它主要刻畫的是實際輸出(概率)與期望輸出(概率)的距離,也就是交叉熵的值越小,兩個概率分布就越接近。假設(shè)概率分布p為期望輸出,概率分布q為實際輸出, 為交叉熵,則 ????那么該公式如何表示,舉個例子,假設(shè)N=3,期望輸出為 ,實際輸出 , ,那么: 通過上面可以看出,q2與p更為接近,它的交叉熵也更小。
????Pytorch中計算的交叉熵并不是采用 這種方式計算得到的,而是交叉熵的另外一種方式計算得到的: 它是交叉熵的另外一種方式。
????Pytorch中CrossEntropyLoss()函數(shù)的主要是將softmax-log-NLLLoss合并到一塊得到的結(jié)果。
????1、Softmax后的數(shù)值都在0~1之間,所以ln之后值域是負(fù)無窮到0。
????2、然后將Softmax之后的結(jié)果取log,將乘法改成加法減少計算量,同時保障函數(shù)的單調(diào)性
????3、NLLLoss的結(jié)果就是把上面的輸出與Label對應(yīng)的那個值拿出來(下面例子中就是:將log_output\logsoftmax_output中與y_target對應(yīng)的值拿出來),去掉負(fù)號,再求均值。
下面是我仿真寫的一個例子:
最計算得到的結(jié)果為:
????通過上面的結(jié)果可以看出,直接使用pytorch中的loss_func=nn.CrossEntropyLoss()計算得到的結(jié)果與softmax-log-NLLLoss計算得到的結(jié)果是一致的。
[1]
[2]
[3]
更多自然語言處理、pytorch相關(guān)知識,還請關(guān)注 AINLPer 公眾號,極品干貨即刻送達(dá)。
當(dāng)前標(biāo)題:python交叉熵函數(shù),熵 交叉熵
當(dāng)前鏈接:http://chinadenli.net/article8/hshcop.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、網(wǎng)站導(dǎo)航、微信小程序、企業(yè)網(wǎng)站制作、網(wǎng)站策劃、網(wǎng)站維護(hù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)