Michael Nielsen對交叉熵的解釋(三)

Contact me:

Blog : cugtyt.github.io/blog/i

Email: cugtyt#qq.com, cugtyt#gmail.com


  1. Michael Nielsen對交叉熵的解釋(一)
  2. Michael Nielsen對交叉熵的解釋(二)
  3. Michael Nielsen對交叉熵的解釋(三)

讓我們回到最開始那個小模型上,探索下使用交叉熵損失函數替代掉二次損失函數後發生了什麼。我們還是以二次損失函數做的不錯的地方開始,weight設置為0.6,bias設置為0.9,損失函數變為交叉熵:

不出所料,神經元學習得很不錯,和原來一樣。讓我們看下原來神經元卡住的地方,weight和bias從2.0開始:

成功了!這次神經元學習如我們期望學習得很快。如果你更近距離觀察,你會發現損失曲線比二次損失的曲線更陡峭一些。這是交叉熵帶給我們的,避開了我們本希望神經元學習更快卻卡住的地方。

我還沒說學習率的事,前面二次損失函數,我們使用0.15,我們應該在此處使用同樣的學習率嗎?事實上,不可能說「同樣」的學習率了,這就像蘋果和橘子一樣不同。兩個損失函數我通過實驗尋找了可以看清發生了什麼的學習率,如果你還是好奇,我還是告訴你這裡我使用了0.005的學習率。

你也許會說學習率不同導致上面的實驗沒有意義了。當我們開始的學習率不固定時,誰還關心神經元學習多快呢?但是這樣的說法遺漏了一點,就是這個圖不是關於學習的絕對速度,而是關於速度如何變化的。更具體的講,在實際輸出和正確輸出接近時,使用二次損失函數毫無疑問慢於後面的情況。當錯的嚴重時,交叉熵也更快,這並不取決於學習速度。

我們已經學習了在一個神經元上使用交叉熵的情況,很容易擴展到多層多神經元的網路中。具體來說:假設期望的輸出值 y = y_1, y_2, ldots ,在最後一層的輸出 a^L_1, a^L_2, ldots ,然後我們定義交叉熵:

egin{eqnarray} C = -frac{1}{n} sum_x sum_j left[y_j ln a^L_j + (1-y_j) ln (1-a^L_j) 
ight] end{eqnarray}

這和我們原來的表達式差不多,除了使用 sum_j 對所有輸出神經元求和。不深究細節,這個表達式的確避免了學習變慢的問題。

也許我使用交叉熵讓很多讀者迷惑,尤其是和其他背景知識相衝突的人。很常見的做法是對兩個概率分布定義交叉熵, p_jq_j ,那麼交叉熵就是 sum_j p_j ln q_j ,這和我們最開始對單個神經元定義的一樣。

但是,當在最後一層有很多sigmoid神經元時,激活向量 a^L_j 通常不是一個概率分布。因此 sum_j p_j ln q_j 就不是很合適了,因為我們處理的不再是概率分布。但是,你可以把上面公式看作是每個神經元交叉熵的合集,每個神經元和它的激活看作是兩元素的概率分布。在這種情況下,就是一個交叉熵對概率分布的泛化了。

什麼時候使用交叉熵而不是用二次損失函數呢?事實上,在輸出是sigmoid神經元情況下,交叉熵幾乎總是更好的選擇。考慮當我們設定神經網路時,我們通常使用隨機化的方式初始化weights和biases。可能出現的情況是初始的結果對於訓練輸入來說錯的離譜,比如輸出應該是0卻飽和在1的附近,或者反過來。如果我們使用二次損失去降低學習速度,它可能永遠不會停下來,即使也在從其他輸入中學習,但是總離期望太遠。

一些問題的解釋:

  • 多層多神經元網路

在前面我們展示了對於二次損失函數,對weights的偏導為:

egin{eqnarray} frac{partial C}{partial w^L_{jk}} & = & frac{1}{n} sum_x a^{L-1}_k (a^L_j-y_j) sigma(z^L_j) end{eqnarray}

sigma(z^L_j) 項導致無論何時輸出神經元在錯誤值處飽和而學習緩慢。而交叉熵單個訓練樣本x輸出的錯誤 delta^L 是:

egin{eqnarray} delta^L = a^L-y end{eqnarray}

這個表達式說明輸出層對weights的偏導是:

egin{eqnarray} frac{partial C}{partial w^L_{jk}} & = & frac{1}{n} sum_x a^{L-1}_k (a^L_j-y_j) end{eqnarray}

sigma(z^L_j) 消失了,因此交叉熵避免了學習變慢的問題,這不僅僅是在單個神經元上,對多層多神經元網路也是適用的。對bias同樣成立。

  • 當輸出層使用線性神經元時,使用二次損失函數

假設我們有多層多神經元網路,最後一層所有神經元是線性神經元,也就是輸出為 a^L_j = z^L_j ,如果我們使用二次損失函數的話,單個神經元的輸出錯誤 delta^L 是:

egin{eqnarray} delta^L = a^L-y end{eqnarray}

那麼和前面的問題一樣,對weights和biases的偏導為:

egin{eqnarray} frac{partial C}{partial w^L_{jk}} & = & frac{1}{n} sum_x a^{L-1}_k (a^L_j-y_j) end{eqnarray}

 frac{partial C}{partial b^L_{j}} = frac{1}{n} sum_x (a^L_j-y_j)

因此,對於線性輸出神經元來說二次損失並沒有什麼問題。在這種情況下,二次損失函數是個合適的選擇。


推薦閱讀:

TAG:機器學習 | 深度學習DeepLearning | 神經網路 |