sigmoid
1 函數+求導
-
sigmoid
函數
σ ( x ) = 1 1 + e ( ? x ) \sigma(x) = \frac{1}{1+e^{(-x)}} σ(x)=1+e(?x)1? -
sigmoid
函數求導
d d x σ ( x ) = d d x ( 1 1 + e ? x ) = e ? x ( 1 + e ? x ) 2 = ( 1 + e ? x ) ? 1 ( 1 + e ? x ) 2 = 1 1 + e ? x ? 1 ( 1 + e ? x ) 2 = σ ( x ) ? σ ( x ) 2 = σ ( x ) ( 1 ? σ ( x ) ) \begin{aligned} \frac{d}{dx}\sigma(x) & = \frac{d}{dx}\left( \frac{1}{1+e^{-x}} \right) \\ & = \frac{e^{-x}}{(1+e^{-x})^2} \\ & = \frac{(1+e^{-x})-1}{(1+e^{-x})^2} \\ & = \frac{1}{1+e^{-x}} - \frac{1}{(1+e^{-x})^2} \\ & = \sigma(x)-\sigma(x)^2 \\ & = \sigma(x)(1-\sigma(x)) \end{aligned} dxd?σ(x)?=dxd?(1+e?x1?)=(1+e?x)2e?x?=(1+e?x)2(1+e?x)?1?=1+e?x1??(1+e?x)21?=σ(x)?σ(x)2=σ(x)(1?σ(x))?
在神經網絡的梯度計算中,通過緩存每層的 Sigmoid 函數輸出值,即可在需 要的時候計算出其導數.
2 函數和導函數圖像
-
畫圖
import pandas as pd import numpy as np from matplotlib import pyplot as pltdef sigmoid(x):return 1/(1+np.exp(-x))x = np.linspace(-4,4,1000) y = [sigmoid(i) for i in x] y1 = [sigmoid(i)*(1-sigmoid(i)) for i in x] y2 = [1 for i in x]ax = plt.gca() plt.plot(x,y,label='Sigmoid') plt.plot(x,y1,label='Derivative') plt.plot(x,y2,color='black',linestyle='--')#設置上邊和右邊無邊框 ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') #設置x坐標刻度數字或名稱的位置 ax.xaxis.set_ticks_position('bottom') #設置邊框位置 ax.spines['bottom'].set_position(('data', 0)) ax.yaxis.set_ticks_position('left') ax.spines['left'].set_position(('data',0))plt.legend(loc = 6)
3 優缺點
-
sigmoid 函數優點:
-
值域為 [ 0 , 1 ] [0,1] [0,1],適合輸出概率值:
sigmoid
函數的值域為 ( 0 , 1 ) (0,1) (0,1),非常適合作為模型的輸出函數,用于輸出 ( 0 , 1 ) (0,1) (0,1) 范圍內的概率值。它可以用于將預測概率作為輸出的模型(如風控中的評分卡、邏輯回歸等),例如表示二分類的類別概率或置信度。 -
輸出值限定在 0 到 1,對神經元輸出進行歸一化:
由于
sigmoid
函數的輸出范圍是 ( 0 , 1 ) (0,1) (0,1),它對每個神經元的輸出進行了“軟”歸一化,將任意實數輸入壓縮到 ( 0 , 1 ) (0,1) (0,1) 之間。(這里注意sigmoid和softmax的區別,經過sigmoid的所有輸出加起來不等于1) -
連續可導,提供平滑的梯度值:
sigmoid
函數是連續可導的(即可微),能夠提供非常平滑的梯度值,防止模型訓練過程中出現突變的梯度(即避免“跳躍”的輸出值)。
-
-
sigmoid 函數缺點:
- 梯度消失問題:從
sigmoid
函數的導數圖像可以看出,其導數的最大值只有 0.25。當輸入 x x x 在 [ ? 5 , 5 ] [-5,5] [?5,5] 的范圍之外時,導數值幾乎接近于 0。這種情況會導致訓練過程中神經元處于飽和狀態(即導數趨于 0),反向傳播時權重幾乎得不到更新,從而使得模型難以訓練,這種現象被稱為梯度消失問題。 - 輸出不以 0 為中心:
sigmoid
函數的輸出總是大于 0(即不以 0 為中心),這會降低權重更新的效率。下一層神經元會接收到上一層輸出的全正信號作為輸入,導致權重更新時出現“zig-zag”現象。因此,sigmoid
激活函數通常不適合放在神經網絡的隱藏層,而一般用于最后的輸出層。 - 計算量大及計算復雜度高:
sigmoid
函數需要進行指數運算,計算量較大且計算復雜度高,訓練耗時。此外,隨著輸入值的增大,sigmoid
函數的導數會迅速減小,容易產生梯度消失問題。
- 梯度消失問題:從
-
補充說明:
- 梯度消失問題:
sigmoid
函數在深層神經網絡中容易導致梯度消失問題,但在淺層網絡或輸出層中使用時,這個問題的影響相對較小。因此,sigmoid
函數通常用于輸出層,而不是隱藏層。** - 替代方案:在現代深度學習中,
ReLU
(Rectified Linear Unit)及其變體(如Leaky ReLU
、ELU
等)通常被用作隱藏層的激活函數,因為它們能夠有效緩解梯度消失問題,并且計算速度更快。 - zig-zag 現象:具體來說,當激活函數的輸出不以 0 為中心(如
sigmoid
函數的輸出總是大于 0),會導致反向傳播時梯度的更新方向不一致,從而使得權重在優化過程中沿著“鋸齒形”路徑緩慢收斂。
- 梯度消失問題:
4 pytorch 中的sigmoid函數
-
代碼
import torchf = torch.nn.Sigmoid() x = torch.randn(2)sigmoid_x = f(x) print(f"x: \n{x}") print(f"sigmoid_x:\n{sigmoid_x}")"""輸出""" x: tensor([ 0.0259, -2.4006]) sigmoid_x: tensor([0.5065, 0.0831])
5 tensorflow中的sigmoid函數
-
代碼
python: 3.10.9
tensorflow: 2.18.0
import tensorflow as tff = tf.nn.sigmoid x = tf.random.normal([2])sigmoid_x = f(x) print(f"x: \n{x}") print(f"sigmoid_x:\n{sigmoid_x}")"""輸出""" x: [-1.2805938 -1.4400458] sigmoid_x: [0.21744916 0.19153824]