詳解sigmoid與softmax, 多分類及多標(biāo)簽分類
激活函數(shù)介紹
對(duì)于熟悉機(jī)器學(xué)習(xí)或神經(jīng)網(wǎng)絡(luò)的讀者來(lái)說(shuō),sigmoid與softmax兩個(gè)激活函數(shù)并不陌生,但這兩個(gè)激活函數(shù)在邏輯回歸中應(yīng)用,也是面試和筆試會(huì)問(wèn)到的一些內(nèi)容,掌握好這兩個(gè)激活函數(shù)及其衍生的能力是很基礎(chǔ)且重要的,下面為大家介紹下這兩類激活函數(shù)。
sigmoid激活函數(shù)
從函數(shù)定義上來(lái)看,sigmoid激活函數(shù)的定義域能夠取任何范圍的實(shí)數(shù),而返回的輸出值在0到1的范圍內(nèi)。sigmoid函數(shù)也被稱為S型函數(shù),這是由于其函數(shù)曲線類似于S型,在下面的內(nèi)容中可以看到。此外,該函數(shù)曲線也可以用于統(tǒng)計(jì)中,使用的是累積分布函數(shù)。
sigmoid激活函數(shù)的性質(zhì)
根據(jù)定義,sigmoid激活函數(shù)的計(jì)算公式如下:

其中:
- x: 輸入
- float:表示浮點(diǎn)型數(shù)據(jù)
- exp:對(duì)其求指數(shù)
- f(x): 函數(shù)輸出
從上述函數(shù)可以看到,x的取值范圍可以是全實(shí)數(shù),sigmoid函數(shù)返回一個(gè)實(shí)數(shù)值輸出,此外,sigmoid函數(shù)的一階導(dǎo)數(shù)是非負(fù)或非正:
- 非負(fù): 如果輸入數(shù)字大于或等于零;
- 非正: 如果輸入數(shù)字小于或等于零;
sigmoid激活函數(shù)的使用
- Sigmoid函數(shù)用于邏輯回歸模型中的二進(jìn)制分類。
- 在創(chuàng)建人造神經(jīng)元時(shí),Sigmoid函數(shù)用作激活函數(shù)。
- 在統(tǒng)計(jì)學(xué)中,S形函數(shù)圖像是常見(jiàn)的累積分布函數(shù)。
sigmoid激活函數(shù)python實(shí)現(xiàn)并畫(huà)圖
實(shí)現(xiàn)代碼
# Required Python Package
import numpy as np
def sigmoid(inputs):
"""
Calculate the sigmoid for the give inputs (array)
:param inputs:
:return:
"""
sigmoid_scores = [1 / float(1 + np.exp(- x)) for x in inputs]
return sigmoid_scores
sigmoid_inputs = [2, 3, 5, 6]
print "Sigmoid Function Output :: {}".format(sigmoid(sigmoid_inputs))
上是Sigmoid函數(shù)的實(shí)現(xiàn)代碼。該函數(shù)將以列表形式的值作為輸入?yún)?shù)。列表中的每個(gè)元素值將被視為Sigmoid函數(shù)的輸入,并計(jì)算輸出值。
接下來(lái),我們將一個(gè)列表sigmiod_inputs作為函數(shù)的輸入,列表值為2,3,5,6,經(jīng)過(guò)sigmoid函數(shù)計(jì)算后獲得Sigmoid分?jǐn)?shù)。
函數(shù)輸出:
Sigmoid Function Output :: [0.8807970779778823, 0.9525741268224334, 0.9933071490757153, 0.9975273768433653]
畫(huà)圖
現(xiàn)在使用上面的函數(shù)來(lái)創(chuàng)建圖像,以方便了解Sigmoid函數(shù)的性質(zhì)。傳遞一個(gè)包含0到21范圍內(nèi)的數(shù)字的列表,計(jì)算輸入列表的sigmoid分?jǐn)?shù),然后使用輸出值來(lái)顯示圖像。
# Required Python Packages
import numpy as np
import matplotlib.pyplot as plt
def sigmoid(inputs):
"""
Calculate the sigmoid for the give inputs (array)
:param inputs:
:return:
"""
sigmoid_scores = [1 / float(1 + np.exp(- x)) for x in inputs]
return sigmoid_scores
def line_graph(x, y, x_title, y_title):
"""
Draw line graph with x and y values
:param x:
:param y:
:param x_title:
:param y_title:
:return:
"""
plt.plot(x, y)
plt.xlabel(x_title)
plt.ylabel(y_title)
plt.show()
graph_x = range(0, 21)
graph_y = sigmoid(graph_x)
print "Graph X readings: {}".format(graph_x)
print "Graph Y readings: {}".format(graph_y)
line_graph(graph_x, graph_y, "Inputs", "Sigmoid Scores")
創(chuàng)建一個(gè)包含0到21范圍內(nèi)的數(shù)字的graph_x列表,之后在graph_y列表中存儲(chǔ)給定graph_x輸入的計(jì)算sigmoid分?jǐn)?shù),調(diào)用line_graph函數(shù),該函數(shù)采用圖像的x,y和標(biāo)題來(lái)創(chuàng)建線形圖。
腳本輸出:
Graph X readings: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Graph Y readings: [0.5, 0.7310585786300049, 0.8807970779778823, 0.9525741268224334, 0.9820137900379085, 0.9933071490757153, 0.9975273768433653, 0.9990889488055994, 0.9996646498695336, 0.9998766054240137, 0.9999546021312976, 0.999983298578152, 0.9999938558253978, 0.999997739675702, 0.9999991684719722, 0.999999694097773, 0.9999998874648379, 0.9999999586006244, 0.9999999847700205, 0.9999999943972036, 0.9999999979388463]

從上圖可以看出,隨著輸入值的增加,sigmoid得分增加到1。
softmax激活函數(shù)
Softmax函數(shù)計(jì)算事件超過(guò)’n’個(gè)不同事件的概率分布。一般來(lái)說(shuō),這個(gè)函數(shù)將會(huì)計(jì)算每個(gè)目標(biāo)類別在所有可能的目標(biāo)類中的概率。計(jì)算出的概率將有助于確定給定輸入的目標(biāo)類別。
使用Softmax的主要優(yōu)點(diǎn)是輸出概率的范圍,范圍為0到1,所有概率的和將等于1。如果將softmax函數(shù)用于多分類模型,它會(huì)返回每個(gè)類別的概率,并且目標(biāo)類別的概率值會(huì)很大。指數(shù)公式計(jì)算給定輸入值的指數(shù)和輸入中所有值的指數(shù)值之和。那么輸入值的指數(shù)與指數(shù)值之和的比值就是softmax函數(shù)的輸出。
softmax激活函數(shù)的性質(zhì)
根據(jù)定義,softmax激活函數(shù)的計(jì)算公式如下:

其中:
- x: 輸入
- exp:對(duì)其求指數(shù)
- f(x): 函數(shù)輸出
從上述計(jì)算公式可以看出:
- 計(jì)算出的概率將在0到1的范圍內(nèi)。
- 所有概率的和等于1。
softmax激活函數(shù)的使用
- 用于多重分類邏輯回歸模型。
- 在構(gòu)建神經(jīng)網(wǎng)絡(luò)中,在不同的層使用softmax函數(shù)。
softmax激活函數(shù)python實(shí)現(xiàn)并畫(huà)圖
實(shí)現(xiàn)代碼
# Required Python Package
import numpy as np
def softmax(inputs):
"""
Calculate the softmax for the give inputs (array)
:param inputs:
:return:
"""
return np.exp(inputs) / float(sum(np.exp(inputs)))
softmax_inputs = [2, 3, 5, 6]
print "Softmax Function Output :: {}".format(softmax(softmax_inputs))
腳本輸出:
Softmax Function Output :: [ 0.01275478 0.03467109 0.25618664 0.69638749]
從中可以觀察到,輸入值為6時(shí),函數(shù)輸出值的概率最高,這是可以從softmax函數(shù)預(yù)先知道的。之后在分類任務(wù)中,可以使用高概率值來(lái)預(yù)測(cè)給定輸入特征的目標(biāo)類別。
畫(huà)圖
現(xiàn)在讓我們使用實(shí)現(xiàn)的Softmax函數(shù)創(chuàng)建圖像來(lái)了解這個(gè)函數(shù)的表現(xiàn)。
創(chuàng)建一個(gè)包含0到21范圍內(nèi)的值的列表,之后將通過(guò)此列表來(lái)計(jì)算已實(shí)現(xiàn)函數(shù)的分?jǐn)?shù),使用列表和估計(jì)分?jǐn)?shù)創(chuàng)建圖像。
# Required Python Packages
import numpy as np
import matplotlib.pyplot as plt
def softmax(inputs):
"""
Calculate the softmax for the give inputs (array)
:param inputs:
:return:
"""
return np.exp(inputs) / float(sum(np.exp(inputs)))
def line_graph(x, y, x_title, y_title):
"""
Draw line graph with x and y values
:param x:
:param y:
:param x_title:
:param y_title:
:return:
"""
plt.plot(x, y)
plt.xlabel(x_title)
plt.ylabel(y_title)
plt.show()
graph_x = range(0, 21)
graph_y = softmax(graph_x)
print "Graph X readings: {}".format(graph_x)
print "Graph Y readings: {}".format(graph_y)
line_graph(graph_x, graph_y, "Inputs", "Softmax Scores")
腳本輸出:
Graph X readings: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Graph Y readings: [ 1.30289758e-09 3.54164282e-09 9.62718331e-09 2.61693975e-08 7.11357976e-08 1.93367146e-07 5.25626399e-07 1.42880069e-06 3.88388295e-06 1.05574884e-05 2.86982290e-05 7.80098744e-05 2.12052824e-04 5.76419338e-04 1.56687021e-03 4.25919483e-03 1.15776919e-02 3.14714295e-02 8.55482149e-02 2.32544158e-01 6.32120559e-01]

該圖顯示了softmax函數(shù)的基本屬性,輸入值越大,其概率越高。
多類分類及多標(biāo)簽分類
多類分類意味著候選集是一個(gè)多分類,而不僅僅是二分類,不是是與否的問(wèn)題,而是屬于多類中哪一類的問(wèn)題。一個(gè)樣本屬于且只屬于多個(gè)分類中的一個(gè),一個(gè)樣本只能屬于一個(gè)類,不同類之間是互斥的。舉例而言,MNIST數(shù)據(jù)集,常用的數(shù)字手寫(xiě)體識(shí)別數(shù)據(jù)集,它的標(biāo)簽是一個(gè)多分類的過(guò)程,要將數(shù)字手寫(xiě)體識(shí)別為0~9中的某一個(gè)數(shù)字:

而對(duì)于多標(biāo)簽分類而言,一個(gè)樣本的標(biāo)簽不僅僅局限于一個(gè)類別,可以具有多個(gè)類別,不同類之間是有關(guān)聯(lián)的。比如一件衣服,其具有的特征類別有長(zhǎng)袖、蕾絲等屬性等,這兩個(gè)屬性標(biāo)簽不是互斥的,而是有關(guān)聯(lián)的。
使用softmax和sigmoid激活函數(shù)來(lái)做多類分類和多標(biāo)簽分類
在實(shí)際應(yīng)用中,一般將softmax用于多類分類的使用之中,而將sigmoid用于多標(biāo)簽分類之中,對(duì)于圖像處理而言,網(wǎng)絡(luò)模型抽取圖像特征的結(jié)構(gòu)基本相同,只是根據(jù)不同的任務(wù)改變?nèi)B接層后的輸出層。下面介紹如何使用softmax和sigmoid完成對(duì)應(yīng)的分類任務(wù)。
softmax激活函數(shù)應(yīng)用于多類分類
假設(shè)神經(jīng)網(wǎng)絡(luò)模型的最后一層的全連接層輸出的是一維向量logits=[1,2,3,4,5,6,7,8,9,10],這里假設(shè)總共類別數(shù)量為10,使用softmax分類器完成多類分類問(wèn)題,并將損失函數(shù)設(shè)置為categorical_crossentropy損失函數(shù):
用tensorflow實(shí)現(xiàn):
tf.argmax(tf.softmax(logits))
首先用softmax將logits轉(zhuǎn)換成一個(gè)概率分布,然后取概率值最大的作為樣本的分類 。softmax的主要作用其實(shí)是在計(jì)算交叉熵上,將logits轉(zhuǎn)換成一個(gè)概率分布后再來(lái)計(jì)算,然后取概率分布中最大的作為最終的分類結(jié)果,這就是將softmax激活函數(shù)應(yīng)用于多分類中。
sigmoid激活函數(shù)應(yīng)用于多標(biāo)簽分類
sigmoid一般不用來(lái)做多類分類,而是用來(lái)做二分類,它是將一個(gè)標(biāo)量數(shù)字轉(zhuǎn)換到[0,1]之間,如果大于一個(gè)概率閾值(一般是0.5),則認(rèn)為屬于某個(gè)類別,否則不屬于某個(gè)類別。這一屬性使得其適合應(yīng)用于多標(biāo)簽分類之中,在多標(biāo)簽分類中,大多使用binary_crossentropy損失函數(shù)。它是將一個(gè)標(biāo)量數(shù)字轉(zhuǎn)換到[0,1]之間,如果大于一個(gè)概率閾值(一般是0.5),則認(rèn)為屬于某個(gè)類別。本質(zhì)上其實(shí)就是針對(duì)logits中每個(gè)分類計(jì)算的結(jié)果分別作用一個(gè)sigmoid分類器,分別判定樣本是否屬于某個(gè)類別同樣假設(shè),神經(jīng)網(wǎng)絡(luò)模型最后的輸出是這樣一個(gè)向量logits=[1,2,3,4,5,6,7,8,9,10], 就是神經(jīng)網(wǎng)絡(luò)最終的全連接的輸出。這里假設(shè)總共有10個(gè)分類。通過(guò):
tf.sigmoid(logits)
sigmoid應(yīng)該會(huì)將logits中每個(gè)數(shù)字都變成[0,1]之間的概率值,假設(shè)結(jié)果為[0.01, 0.05, 0.4, 0.6, 0.3, 0.1, 0.5, 0.4, 0.06, 0.8], 然后設(shè)置一個(gè)概率閾值,比如0.3,如果概率值大于0.3,則判定類別符合,那么該輸入樣本則會(huì)被判定為類別3、類別4、類別5、類別7及類別8。即一個(gè)樣本具有多個(gè)標(biāo)簽。
在這里強(qiáng)調(diào)一點(diǎn):將sigmoid激活函數(shù)應(yīng)用于多標(biāo)簽分類時(shí),其損失函數(shù)應(yīng)設(shè)置為binary_crossentropy。
|