[英]Activation functions: Softmax vs Sigmoid
我一直在嘗試使用 CNN 構建圖像分類器。 我的數據集中有 2300 張圖像,分為兩類:男性和女性。 這是我使用的 model:
early_stopping = EarlyStopping(min_delta = 0.001, patience = 30, restore_best_weights = True)
model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(256, (3, 3), input_shape=X.shape[1:], activation = 'relu'))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Conv2D(256, (3, 3), input_shape=X.shape[1:], activation = 'relu'))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Flatten()) # this converts our 3D feature maps to 1D feature vectors
model.add(tf.keras.layers.Dense(64))
model.add(tf.keras.layers.Dense(1, activation='softmax'))
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
h= model.fit(xtrain, ytrain, validation_data=(xval, yval), batch_size=32, epochs=30, callbacks = [early_stopping], verbose = 0)
這個 model 的准確度是 0.501897 和損失 7.595693(model 在每個時期都停留在這些數字上)但是如果我用 Sigmoid 替換 Softmax 激活,准確度約為 0.98 和損失 0。 為什么 Softmax 會發生這種奇怪的事情? 我能找到的所有信息是這兩個激活是相似的,softmax 甚至更好,但我找不到任何關於這種異常的信息。 如果有人可以解釋問題所在,我會很高興。
結果總結:
TLDR
更新:
現在我還看到您僅使用 1 個 output 神經元和 Softmax,您將無法在二進制分類中捕獲第二個 class 。 使用 Softmax,您需要在 output 層中定義 K 個神經元- 其中 K 是您要預測的類數。 而使用 Sigmoid:1 output 神經元足以進行二元分類。
所以簡而言之,當對 2 個類使用 softmax 時,這應該在你的代碼中改變:
#use 2 neurons with softmax
model.add(tf.keras.layers.Dense(2, activation='softmax'))
此外:
在進行二進制分類時, sigmoid function 更合適,因為與更通用的 softmax function 相比,它在計算上更有效(當您有 K>2 類時,它通常用於多類預測)。
延伸閱讀:
選定激活函數的一些屬性
如果上面的簡短答案對您來說還不夠,我可以與您分享一些我從關於神經網絡激活函數的研究中學到的東西,簡而言之:
首先,讓我們清楚術語激活和激活 function
激活(alpha):是神經元的 state。 隱藏層或 output 層中神經元的 state 將通過來自前一層的輸入信號的加權和來量化
激活 function f(alpha):是將激活轉換為神經元信號的 function。 通常是非線性和可微分的 function,例如 sigmoid function。 sigmoid function 已應用於許多應用和研究(參見 Bengio & Courville, 2016, p.67 ff.)。 大多數相同的激活 function 正在整個神經網絡中使用,但也可以使用多個(例如,不同層中的不同激活)。
現在來看看激活函數的效果:
激活 function 的選擇會對神經網絡的學習產生巨大影響(正如您在示例中看到的那樣)。 從歷史上看,通常使用 sigmoid function,因為它是一個很好的 function 來描繪飽和神經元。 今天,特別是在 CNN 的其他激活函數中,也只有部分線性激活函數(如 relu)優於 sigmoid function。 有許多不同的函數,僅舉幾例:sigmoid、tanh、relu、prelu、elu、maxout、max、argmax、softmax 等。
現在我們只比較 sigmoid、relu/maxout 和 softmax:
# pseudo code / formula
sigmoid = f(alpha) = 1 / (1 + exp(-alpha))
relu = f(alpha) = max(0,alpha)
maxout = f(alpha) = max(alpha1, alpha2)
softmax = f(alpha_j) = alpha_j / sum_K(alpha_k)
乙狀結腸:
回復:
最大輸出:
軟最大:
一些很好的參考資料供進一步閱讀:
您看到這些不同結果的原因是您的 output 層的大小 - 它是 1 個神經元。
根據定義,Softmax 需要超過 1 個 output 神經元才有意義。 1 Softmax 神經元總是 output 1 (查找公式並考慮一下)。 這就是為什么您會看到大約 50% 的准確率,因為您的網絡總是預測 class 1。
Sigmoid 沒有這個問題,output 什么都可以,這就是它訓練的原因。
如果要測試 softmax,則必須為每個 class 制作一個 output 神經元,然后對 ytrain 和 yval 進行“單熱編碼”(查找單熱編碼以獲得更多解釋)。 在您的情況下,這意味着:label 0 -> [1, 0],label 1 -> [0, 1]。 你可以看到,一個的索引編碼了 class。 我不確定,但在那種情況下,我相信你會使用分類交叉熵。 我無法從文檔中得出結論,但在我看來,二進制交叉熵期望 1 個 output 神經元為 0 或 1(其中 Sigmoid 是正確的激活使用),而分類交叉熵期望每個 Z78E6221F6393D1356681DB398F1 都有一個 Z78E6221F6393D1356681DB398F1 class,其中 Softmax 有意義。 即使是多輸出情況,您也可以使用 Sigmoid,但這並不常見。
簡而言之,在我看來,二進制熵期望 class 由 1 個神經元的值編碼,而分類熵期望 class 編碼的 Z78E6221F6393D1366681Z 神經元 DB398 最活躍。 (簡而言之)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.