Neil Zhu,簡書ID Not_GOD,University AI 創始人 & Chief Scientist,致力于推進世界人工智能化進程。制定并實施 UAI 中長期增長戰略和目標,帶領團隊快速成長為人工智能領域最專業的力量。
作為行業領導者,他和UAI一起在2014年創建了TASA(中國最早的人工智能社團), DL Center(深度學習知識中心全球價值網絡),AI growth(行業智庫培訓)等,為中國的人工智能人才建設輸送了大量的血液和養分。此外,他還參與或者舉辦過各類國際性的人工智能峰會和活動,產生了巨大的影響力,書寫了60萬字的人工智能精品技術內容,生產翻譯了全球第一本深度學習入門書《神經網絡與深度學習》,生產的內容被大量的專業垂直公眾號和媒體轉載與連載。曾經受邀為國內頂尖大學制定人工智能學習規劃和教授人工智能前沿課程,均受學生和老師好評。
當一個高爾夫球員剛開始學習打高爾夫時,他們通常會在揮桿的練習上花費大多數時間。慢慢地他們才會在基本的揮桿上通過變化發展其他的擊球方式,學習?低飛球、左曲球和右曲球。類似的,我們現在仍然聚焦在反向傳播算法的理解上。這就是我們的“基本揮桿”——神經網絡中大部分工作學習和研究的基礎。本章,我會解釋若干技術能夠用來提升我們關于反向傳播的初級的實現,最終改進網絡學習的方式。
本章涉及的技術包括:更好的代價函數的選擇——?交叉熵 代價函數;四中規范化方法(L1 和 L2 規范化,dropout 和訓練數據的人工擴展),這會讓我們的網絡在訓練集之外的數據上更好地泛化;更好的權重初始化方法;還有幫助選擇好的超參數的啟發式想法。同樣我也會再給出一些簡要的其他技術介紹。這些討論之間的獨立性比較大,所有你們可以隨自己的意愿挑著看。另外我還會在代碼中實現這些技術,使用他們來提高在第一章中的分類問題上的性能。
當然,我們僅僅覆蓋了大量已經在神經網絡中研究發展出的技術的一點點內容。此處我們學習深度學習的觀點是想要在一些已有的技術上入門的最佳策略其實是深入研究一小部分最重要那些的技術點。掌握了這些關鍵技術不僅僅對這些技術本身的理解很有用,而且會深化你對使用神經網絡時會遇到哪些問題的理解。這會讓你們做好在需要時快速掌握其他技術的充分準備。
交叉熵代價函數
我們大多數人覺得錯了就很不爽。在開始學習彈奏鋼琴不久后,我在一個聽眾前做了處女秀。我很緊張,開始時將八度音階的曲段演奏得很低。我很困惑,因為不能繼續演奏下去了,直到有個人指出了其中的錯誤。當時,我非常尷尬。不過,盡管不開心,我們卻能夠因為明顯的犯錯快速地學習到正確的東西。你應該相信下次我再演奏肯定會是正確的!相反,在我們的錯誤不是很好的定義的時候,學習的過程會變得更加緩慢。
理想地,我們希望和期待神經網絡可以從錯誤中快速地學習。在實踐中,這種情況經常出現么?為了回答這個問題,讓我們看看一個小例子。這個例子包含一個只有一個輸入的神經元:
我們會訓練這個神經元來做一件非常簡單的事:讓輸入 $$1$$ 轉化為 $$0$$。當然,這很簡單了,手工找到合適的權重和偏差就可以了,不需要什么學習算法。然而,看起來使用梯度下降的方式來學習權重和偏差是很有啟發的。所以,我們來看看神經元如何學習。
為了讓事情確定化,我會首先將權重和偏差初始化為 $$0.6$$ 和 $$0.9$$。這些就是一般的開始學習的選擇,并沒有任何刻意的想法。一開始的神經元的輸出是 $$0.82$$,所以這離我們的目標輸出 $$0.0$$ 還差得很遠。點擊右下角的“運行”按鈕來看看神經元如何學習到讓輸出接近 $$0.0$$ 的。注意到,這并不是一個已經錄好的動畫,你的瀏覽器實際上是正在進行梯度的計算,然后使用梯度更新來對權重和偏差進行更新,并且展示結果。設置學習率 $$\eta=0.15$$ 進行學習一方面足夠慢的讓我們跟隨學習的過程,另一方面也保證了學習的時間不會太久,幾秒鐘應該就足夠了。代價函數是我們前面用到的二次函數,$$C$$。這里我也會給出準確的形式,所以不需要翻到前面查看定義了。注意,你可以通過點擊 “Run” 按鈕執行訓練若干次。
我們這里是靜態的例子,在原書中,使用的動態示例,所以為了更好的效果,請參考原書的此處動態示例。
正如你所見,神經元快速地學到了使得代價函數下降的權重和偏差,給出了最終的輸出為 $$0.09$$。這雖然不是我們的目標輸出 $$0.0$$,但是已經挺好了。假設我們現在將初始權重和偏差都設置為 $$2.0$$。此時初始輸出為 $$0.98$$,這是和目標值的差距相當大的。現在看看神經元學習的過程。點擊“Run” 按鈕:
雖然這個例子使用的了同樣的學習率($$\eta=0.15$$),我們可以看到剛開始的學習速度是比較緩慢的。對前 $$150$$ 左右的學習次數,權重和偏差并沒有發生太大的變化。隨后學習速度加快,與上一個例子中類似了,神經網絡的輸出也迅速接近 $$0.0$$。
強烈建議參考原書的此處動態示例感受學習過程的差異。
這種行為看起來和人類學習行為差異很大。正如我在此節開頭所說,我們通常是在犯錯比較明顯的時候學習的速度最快。但是我們已經看到了人工神經元在其犯錯較大的情況下其實學習很有難度。而且,這種現象不僅僅是在這個小例子中出現,也會再更加一般的神經網絡中出現。為何學習如此緩慢?我們能夠找到緩解這種情況的方法么?
為了理解這個問題的源頭,想想神經元是按照偏導數($$\partial C/\partial w$$ 和 $$\partial C/\partial b$$)和學習率($$\eta$$)的乘積來改變權重和偏差的。所以,我們在說“學習緩慢”時,實際上就是說這些偏導數很小。理解他們為何這么小就是我們面臨的挑戰。為了理解這些,讓我們計算偏導數看看。我們一直在用的是二次代價函數,定義如下
其中 $$a$$ 是神經元的輸出,其中訓練輸入為 $$x=1$$,$$y=0$$ 則是目標輸出。顯式地使用權重和偏差來表達這個,我們有 $$a=\sigma(z)$$,其中 $$z=wx+b$$。使用鏈式法則來求偏導數就有:
其中我已經將 $$x=1$$ 和 $$y=0$$ 代入了。為了理解這些表達式的行為,讓我們仔細看 $$\sigma'(z)$$ 這一項。首先回憶一下 $$\sigma$$ 函數圖像:
我們可以從這幅圖看出,當神經元的輸出接近 $$1$$ 的時候,曲線變得相當平,所以 $$\sigma'(z)$$ 就很小了。方程 (55) 和 (56) 也告訴我們 $$\partial C/\partial w$$ 和 $$\partial C/\partial b$$ 會非常小。這其實就是學習緩慢的原因所在。而且,我們后面也會提到,這種學習速度下降的原因實際上也是更加一般的神經網絡學習緩慢的原因,并不僅僅是在這個特例中特有的。
引入交叉熵代價函數
那么我們如何解決這個問題呢?研究表明,我們可以通過使用交叉熵代價函數來替換二次代價函數。為了理解什么是交叉熵,我們稍微改變一下之前的簡單例子。假設,我們現在要訓練一個包含若干輸入變量的的神經元,$$x_1,x_2,...$$ 對應的權重為 $$w_1,w_2,...$$ 和偏差,$$b$$:
神經元的輸出就是 $$a=\sigma(z)$$,其中 $$z=\sum_jw_jx_j+b$$ 是輸入的帶權和。我們如下定義交叉熵代價函數:
其中 $$n$$ 是訓練數據的總數,對所有的訓練數據 $$x$$ 和 對應的目標輸出 $$y$$ 進行求和。
公式(57)是否解決學習緩慢的問題并不明顯。實際上,甚至將這個定義看做是代價函數也不是顯而易見的!在解決學習緩慢前,我們來看看交叉熵為何能夠解釋成一個代價函數。
將交叉熵看做是代價函數有兩點原因。第一,它使非負的,$$C>0$$。可以看出:(a) 公式(57)的和式中所有獨立的項都是非負的,因為對數函數的定義域是 $$(0,1)$$;(b) 前面有一個負號。
第二,如果神經元實際的輸出接近目標值。假設在這個例子中,$$y=0$$ 而 $$a\approx 0$$。這是我們想到得到的結果。我們看到公式(57)中第一個項就消去了,因為 $$y=0$$,而第二項實際上就是 $$-ln(1-a)\approx 0$$。反之,$$y=1$$ 而 $$a\approx 1$$。所以在實際輸出和目標輸出之間的差距越小,最終的交叉熵的值就越低了。
綜上所述,交叉熵是非負的,在神經元達到很好的正確率的時候會接近 $$0$$。這些其實就是我們想要的代價函數的特性。其實這些特性也是二次代價函數具備的。所以,交叉熵就是很好的選擇了。但是交叉熵代價函數有一個比二次代價函數更好的特性就是它避免了學習速度下降的問題。為了弄清楚這個情況,我們來算算交叉熵函數關于權重的偏導數。我們將 $$a=\sigma(z)$$ 代入到公式 (57) 中應用兩次鏈式法則,得到:
將結果合并一下,簡化成:
根據 $$\sigma(z) = 1/(1+e^{-z})$$ 的定義,和一些運算,我們可以得到 $$\sigma'(z) = \sigma(z)(1-\sigma(z))$$。后面在練習中會要求你計算這個,現在可以直接使用這個結果。我們看到 $$\sigma'$$ 和 $$\sigma(z)(1-\sigma(z))$$ 這兩項在方程中直接約去了,所以最終形式就是:
這是一個優美的公式。它告訴我們權重學習的速度受到 $$\sigma(z)-y$$,也就是輸出中的誤差的控制。更大的誤差,更快的學習速度。這是我們直覺上期待的結果。特別地,這個代價函數還避免了像在二次代價函數中類似公式中 $$\sigma'(z)$$ 導致的學習緩慢,見公式(55)。當我們使用交叉熵的時候,$$\sigma'(z)$$ 被約掉了,所以我們不再需要關心它是不是變得很小。這種約除就是交叉熵帶來的?特效。實際上,這也并不是非常奇跡的事情。我們在后面可以看到,交叉熵其實只是滿足這種特性的一種選擇罷了。
根據類似的方法,我們可以計算出關于偏差的偏導數。我這里不再給出詳細的過程,你可以輕易驗證得到
練習
- 驗證 \sigma'(z) = \sigma(z)(1-\sigma(z))。
讓我們重回最原初的例子,來看看換成了交叉熵之后的學習過程。現在仍然按照前面的參數配置來初始化網絡,開始權重為 $$0.6$$,而偏差為 $$0.9$$。點擊“Run”按鈕看看在換成交叉熵之后網絡的學習情況:
毫不奇怪,在這個例子中,神經元學習得相當出色,跟之前差不多。現在我們再看看之前出問題的那個例子,權重和偏差都初始化為 $$2.0$$:
成功了!這次神經元的學習速度相當快,跟我們預期的那樣。如果你觀測的足夠仔細,你可以發現代價函數曲線要比二次代價函數訓練前面部分要陡很多。正是交叉熵帶來的快速下降的坡度讓神經元在處于誤差很大的情況下能夠逃脫出學習緩慢的困境,這才是我們直覺上所期待的效果。
我們還沒有提及關于學習率的討論。剛開始使用二次代價函數的時候,我們使用了 $$\eta=0.15$$。在新例子中,我們還應該使用同樣的學習率么?實際上,根據不同的代價函數,我們不能夠直接去套用同樣的學習率。這好比蘋果和橙子的比較。對于這兩種代價函數,我只是通過簡單的實驗來找到一個能夠讓我們看清楚變化過程的學習率的值。盡管我不愿意提及,但如果你仍然好奇,這個例子中我使用了 $$\eta=0.005$$。
你可能會反對說,上面學習率的改變使得上面的圖失去了意義。誰會在意當學習率的選擇是任意挑選的時候神經元學習的速度?!這樣的反對其實沒有抓住重點。上面的圖例不是想討論學習的絕對速度。而是想研究學習速度的變化情況。特別地,當我們使用二次代價函數時,學習在神經元犯了明顯的錯誤的時候卻比學習快接近真實值的時候緩慢;而使用交叉熵學習正是在神經元犯了明顯錯誤的時候速度更快。這些現象并不是因為學習率的改變造成的。
我們已經研究了一個神經元的交叉熵。不過,將其推廣到多個神經元的多層神經網絡上也是很簡單的。特別地,假設 $$y=y_1,y_2,...$$ 是輸出神經元上的目標值,而 $$a_1L,a_2L,...$$是實際輸出值。那么我們定義交叉熵如下
除了這里需要對所有輸出神經元進行求和外,這個其實和我們早前的公式(57)一樣的。這里不會給出一個推算的過程,但需要說明的時使用公式(63)確實會在很多的神經網絡中避免學習的緩慢。如果你感興趣,你可以嘗試一下下面問題的推導。
那么我們應該在什么時候用交叉熵來替換二次代價函數?實際上,如果在輸出神經元使用 sigmoid 激活函數時,交叉熵一般都是更好的選擇。為什么?考慮一下我們初始化網絡的時候通常使用某種隨機方法。可能會發生這樣的情況,這些初始選擇會對某些訓練輸入誤差相當明顯——比如說,目標輸出是 $$1$$,而實際值是 $$0$$,或者完全反過來。如果我們使用二次代價函數,那么這就會導致學習速度的下降。它并不會完全終止學習的過程,因為這些權重會持續從其他的樣本中進行學習,但是顯然這不是我們想要的效果。
練習
- 一個小問題就是剛接觸交叉熵時,很難一下子記住那些表達式對應的角色。又比如說,表達式的正確形式是 $$?[ylna+(1?y)ln(1?a)]$$
或者 $$?[alny+(1?a)ln(1?y)]$$。在 $$y=0$$ 或者 $$1$$ 的時候第二個表達式的結果怎樣?這個問題會影響第一個表達式么?為什么? - 在對單個神經元討論中,我們指出如果對所有的訓練數據有 $$\sigma(z)\approx y$$,交叉熵會很小。這個論斷其實是和 $$y$$ 只是等于 $$1$$ 或者 $$0$$ 有關。這在分類問題一般是可行的,但是對其他的問題(如回歸問題)$$y$$ 可以取 $$0$$ 和 $$1$$ 之間的中間值的。證明,交叉熵在 $$\sigma(z)=y$$ 時仍然是最小化的。此時交叉熵的表示是:
而其中 $$?[y\ln y+(1?y)\ln(1?y)]$$ 有時候被稱為 ?二元熵
問題
- 多層多神經元網絡 用上一章的定義符號,證明對二次代價函數,關于輸出層的權重的偏導數為
項 $$\sigma'(z_j^L)$$ 會在一個輸出神經元困在錯誤值時導致學習速度的下降。證明對于交叉熵代價函數,針對一個訓練樣本 $$x$$ 的輸出誤差 $$\delta^L$$為
使用這個表達式來證明關于輸出層的權重的偏導數為
這里 $$\sigma'(z_j^L)$$ 就消失了,所以交叉熵避免了學習緩慢的問題,不僅僅是在一個神經元上,而且在多層多元網絡上都起作用。這個分析過程稍作變化對偏差也是一樣的。如果你對這個還不確定,那么請仔細研讀一下前面的分析。
- 在輸出層使用線性神經元時使用二次代價函數 假設我們有一個多層多神經元網絡,最終輸出層的神經元都是線性的,輸出不再是 sigmoid 函數作用的結果,而是 $$a_j^L = z_j^L$$。證明如果我們使用二次代價函數,那么對單個訓練樣本 $$x$$ 的輸出誤差就是
類似于前一個問題,使用這個表達式來證明關于輸出層的權重和偏差的偏導數為
這表明如果輸出神經元是線性的那么二次代價函數不再會導致學習速度下降的問題。在此情形下,二次代價函數就是一種合適的選擇。
使用交叉熵來對 MNIST 數字進行分類
交叉熵很容易作為使用梯度下降和反向傳播方式進行模型學習的一部分來實現。我們將會在下一章進行對前面的程序 network.py
的改進。新的程序寫在 network2.py
中,不僅使用了交叉熵,還有本章中介紹的其他的技術。現在我們看看新的程序在進行 MNIST 數字分類問題上的表現。如在第一章中那樣,我們會使用一個包含 $$30$$ 個隱藏元的網絡,而 minibatch 的大小也設置為 $$10$$。我們將學習率設置為 $$\eta=0.5$$ 然后訓練 30 回合。network2.py
的接口和 network.py
稍微不同,但是過程還是很清楚的。你可以使用如 help(network2.Network.SGD)
這樣的命令來檢查對應的文檔。
>>> import mnist_loader
>>> training_data, validation_data, test_data = \
... mnist_loader.load_data_wrapper()
>>> import network2
>>> net = network2.Network([784, 30, 10], cost=network2.CrossEntropyCost)
>>> net.large_weight_initializer()
>>> net.SGD(training_data, 30, 10, 0.5, evaluation_data=test_data,
... monitor_evaluation_accuracy=True)
注意看下,net.large_weight_initializer()
命令使用和第一章介紹的同樣的方式來進行權重和偏差的初始化。運行上面的代碼我們得到了一個 95.49% 準確度的網絡。這跟我們在第一章中使用二次代價函數得到的結果相當接近了,95.42%。
同樣也來試試使用 $$100$$ 個隱藏元的交叉熵及其他參數保持不變的情況。在這個情形下,我們獲得了 96.82% 的準確度。相比第一章使用二次代價函數的結果 96.59%,這有一定的提升。這看起來是一個小小的變化,但是考慮到誤差率已經從 3.41% 下降到 3.18%了。我們已經消除了原誤差的 $$1/14$$。這其實是可觀的改進。
令人振奮的是交叉熵代價函數給了我們類似的或者更好的結果。然而,這些結果并沒有能夠確定性地證明交叉熵是更好的選擇。原因在于我已經在選擇諸如學習率,minibatch 大小等等這樣的超參數上做出了一些努力。為了讓這些提升更具說服力,我們需要進行對超參數進行深度的優化。當然,這些結果都挺好的,強化了我們早先關于交叉熵優于二次代價的理論論斷。
這只是本章后面的內容和整本書剩余內容中的更為一般的模式的一部分。我們將給出一個新的技術,然后進行嘗試,隨后獲得“提升的”結果。當然,看到這些進步是很好的。但是這些提升的解釋一般來說都困難重重。在進行了大量工作來優化所有其他的超參數,使得提升真的具有說服力。工作量很大,需要大量的計算能力,我們也不會進行這樣耗費的調查。相反,我采用上面進行的那些不正式的測試來達成目標。所以你要記住這樣的測試缺少確定性的證明,需要注意那些使得論斷失效的信號。
至此,我們已經花了大量篇幅介紹交叉熵。為何對一個只能給出一點點性能提升的技術上花費這么多的精力?后面,我們會看到其他的技術——規范化,會帶來更大的提升效果。所以為何要這么細致地討論交叉熵?部分原因在于交叉熵是一種廣泛使用的代價函數,值得深入理解。但是更加重要的原因是神經元的飽和是神經網絡中一個關鍵的問題,整本書都會不斷回歸到這個問題上。因此我現在深入討論交叉熵就是因為這是一種開始理解神經元飽和和如何解決這個問題的很好的實驗。
交叉熵的含義?源自哪里?
我們對于交叉熵的討論聚焦在代數分析和代碼實現。這雖然很有用,但是也留下了一個未能回答的更加寬泛的概念上的問題,如:交叉熵究竟表示什么?存在一些直覺上的思考交叉熵的方法么?我們如何想到這個概念?
讓我們從最后一個問題開始回答:什么能夠激發我們想到交叉熵?假設我們發現學習速度下降了,并理解其原因是因為在公式(55)(56)中的 $$\sigma'(z)$$ 那一項。在研究了這些公式后,我們可能就會想到選擇一個不包含 $$\sigma'(z)$$ 的代價函數。所以,這時候對一個訓練樣本 $$x$$,代價函數是 $$C=C_x$$ 就滿足:
如果我們選擇的代價函數滿足這些條件,那么同樣他們會擁有遇到明顯誤差時的學習速度越快這樣的特性。這也能夠解決學習速度下降的問題。實際上,從這些公式開始,現在就給你們看看若是跟隨自身的數學嗅覺推導出交叉熵的形式是可能的。我們來推一下,由鏈式法則,我們有
使用 $$\sigma'(z)=\sigma(z)(1-\sigma(z))=a(1-a)$$,上個等式就變成
對比等式(72),我們有
對此方程關于 $$a$$ 進行積分,得到
其中 $$constant$$ 是積分常量。這是一個單獨的訓練樣本 $$x$$ 對代價函數的貢獻。為了得到整個的代價函數,我們需要對所有的訓練樣本進行平均,得到了
而這里的常量就是所有單獨的常量的平均。所以我們看到方程(71)和(72)唯一確定了交叉熵的形式,并加上了一個常量的項。這個交叉熵并不是憑空產生的。而是一種我們以自然和簡單的方法獲得的結果。
那么交叉熵直覺含義又是什么?我們如何看待它?深入解釋這一點會將我們帶到一個不大愿意討論的領域。然而,還是值得提一下,有一種源自信息論的解釋交叉熵的標準方式。粗略地說,交叉熵是驚奇的度量(measure of surprise)。特別地,我們的神經元想要要計算函數 $$x\rightarrow y=y(x)$$。但是,它用函數$$x\rightarrow a=a(x)$$ 進行了替換。假設我們將 $$a$$ 想象成我們神經元估計 $$y = 1$$ 概率,而 $$1-a$$ 則是 $$y=0$$ 的概率。如果輸出我們期望的結果,驚奇就會小一點;反之,驚奇就大一些。當然,我這里沒有嚴格地給出“驚奇”到底意味著什么,所以看起來像在夸夸奇談。但是實際上,在信息論中有一種準確的方式來定義驚奇究竟是什么。不過,我也不清楚在網絡上,哪里有好的,短小的自包含對這個內容的討論。但如果你要深入了解的話,Wikipedia 包含一個簡短的總結,這會指引你正確地探索這個領域。而更加細節的內容,你們可以閱讀Cover and Thomas的第五章涉及 Kraft 不等式的有關信息論的內容。
問題
- 我們已經深入討論了使用二次代價函數的網絡中在輸出神經元飽和時候學習緩慢的問題,另一個可能會影響學習的因素就是在方程(61)中的 $$x_j$$ 項。由于此項,當輸入 $$x_j$$ 接近 $$0$$ 時,對應的權重 $$x_j$$ 會學習得相當緩慢。解釋為何不可以通過改變代價函數來消除 $$x_j$$ 項的影響。
Softmax
本章,我們大多數情況會使用交叉熵來解決學習緩慢的問題。但是,我希望簡要介紹一下基于 softmax 神經元層的解決這個問題的另一種觀點。我們不會實際在剩下的章節中使用 softmax 層,所以你如果趕時間,就可以跳到下一個小節了。不過,softmax 仍然有其重要價值,一方面它本身很有趣,另一方面,因為我們會在第六章在對深度神經網絡的討論中使用 softmax 層。
softmax 的想法其實就是為神經網絡定義一種新式的輸出層。開始時和 sigmoid 層一樣的,首先計算帶權輸入 $$z_j^L = \sum_k w_{jk}La_k{L-1}+b_j^L$$。不過,這里我們不會使用 sigmoid 函數來獲得輸出。而是,會應用一種叫做 softmax 函數在 $$z_j^L$$ 上。根據這個函數,激活值 $$a_j^L$$ 就是
其中,分母是對所有的輸出神經元進行求和。
如果你不習慣這個函數,方程(78)可能看起來會比較難理解。因為對于使用這個函數的原因你不清楚。為了更好地理解這個公式,假設我們有一個包含四個輸出神經元的神經網絡,對應四個帶權輸入,表示為 $$z_1^L, z_2^L, z_3^L, z_4^L$$。下面的例子可以進行對應權值的調整,并給出對應的激活值的圖像。可以通過固定其他值,來看看改變 $$z_4^L$$ 的值會產生什么樣的影響:
這里給出了三個選擇的圖像,建議去原網站體驗
在我們增加 $$z_4^L$$ 的時候,你可以看到對應激活值 $$a_4^L$$ 的增加,而其他的激活值就在下降。類似地,如果你降低 $$z_4^L$$ 那么 $$a_4^L$$ 就隨之下降。實際上,如果你仔細看,你會發現在兩種情形下,其他激活值的整個改變恰好填補了 $$a_4^L$$ 的變化的空白。原因很簡單,根據定義,輸出的激活值加起來正好為 $$1$$,使用公式(78)我們可以證明:
所以,如果 $$a_4^L$$ 增加,那么其他輸出激活值肯定會總共下降相同的量,來保證和式為 $$1$$。當然,類似的結論對其他的激活函數也需要滿足。
方程(78)同樣保證輸出激活值都是正數,因為指數函數是正的。將這兩點結合起來,我們看到 softmax 層的輸出是一些相加為 $$1$$ 正數的集合。換言之,softmax 層的輸出可以被看做是一個概率分布。
這樣的效果很令人滿意。在很多問題中,將這些激活值作為網絡對于某個輸出正確的概率的估計非常方便。所以,比如在 MNIST 分類問題中,我們可以將 $$a_j^L$$ 解釋成網絡估計正確數字分類為 $$j$$ 的概率。
對比一下,如果輸出層是 sigmoid 層,那么我們肯定不能假設激活值形成了一個概率分布。我不會證明這一點,但是源自 sigmoid 層的激活值是不能夠形成一種概率分布的一般形式的。所以使用 sigmoid 輸出層,我們沒有關于輸出的激活值的簡單的解釋。
練習
- 構造例子表明在使用 sigmoid 輸出層的網絡中輸出激活值 $$a_j^L$$ 的和并不會確保為 $$1$$。
我們現在開始體會到 softmax 函數的形式和行為特征了。來回顧一下:在公式(78)中的指數函數確保了所有的輸出激活值是正數。然后分母的求和又保證了 softmax 的輸出和為 $$1$$。所以這個特定的形式不再像之前那樣難以理解了:反而是一種確保輸出激活值形成一個概率分布的自然的方式。你可以將其想象成一種重新調節 $$z_j^L$$ 的方法,然后將這個結果整合起來構成一個概率分布。
練習
- softmax 的單調性 證明如果 $$j=k$$ 則 $$\partial a_j^L/\partial z_k^L$$ 為正,否則為負。結果是,增加 $$z_^L$$ 會提高對應的輸出激活值 $$a_k^L$$ 并降低其他所有輸出激活值。我們已經在滑條示例中實驗性地看到了這一點,這里需要你給出一個嚴格證明。
- softmax 的非局部性 sigmoid 層的一個好處是輸出 $$a_j^L$$ 是對應帶權輸入 $$a_j^L = \sigma(z_j^L)$$ 的函數。解釋為何對于 softmax 來說,并不是這樣的情況:仍和特定的輸出激活值 $$a_j^L$$ 依賴所有的帶權輸入。
問題
- 逆轉 softmax 層 假設我們有一個使用 softmax 輸出層的神經網絡,然后激活值 $$a_j^L$$ 已知。證明對應帶權輸入的形式為 $$z_j^L = \ln a_j^L + C$$,其中 $$C$$ 是獨立于 $$j$$ 的。
學習緩慢問題:我們現在已經對 softmax 神經元有了一定的認識。但是我們還沒有看到 softmax 會怎么樣解決學習緩慢問題。為了理解這點,先定義一個 log-likelihood 代價函數。我們使用 $$x$$ 表示訓練輸入,$$y$$ 表示對應的目標輸出。然后關聯這個訓練輸入樣本的 log-likelihood 代價函數就是
所以,如果我們訓練的是 MNIST 圖像,輸入為 $$7$$ 的圖像,那么對應的 log-likelihood 代價就是 $$-\ln a_7^L$$。看看這個直覺上的含義,想想當網絡表現很好的時候,也就是確認輸入為 $$7$$ 的時候。這時,他會估計一個對應的概率 $$a_7^L$$ 跟 $$1$$ 非常接近,所以代價 $$-\ln a_7^L$$ 就會很小。反之,如果網絡的表現糟糕時,概率 $$a_7^L$$ 就變得很小,代價 $$-\ln a_7^L$$ 隨之增大。所以 log-likelihood 代價函數也是滿足我們期待的代價函數的條件的。
那關于學習緩慢問題呢?為了分析它,回想一下學習緩慢的關鍵就是量 $$\partial C/\partial w_{jk}^L$$ 和 $$\partial C/\partial b_j^L$$ 的變化情況。我不會顯式地給出詳細的推導——請你們自己去完成這個過程——但是會給出一些關鍵的步驟:
請注意這里的表示上的差異,這里的 $$y$$ 和之前的目標輸出值不同,是離散的向量表示,對應位的值為 $$1$$,而其他為 $$0$$。
這些方程其實和我們前面對交叉熵得到的類似。就拿方程(82) 和 (67) 比較。盡管后者我對整個訓練樣本進行了平均,不過形式還是一致的。而且,正如前面的分析,這些表達式確保我們不會遇到學習緩慢的問題。實際上,將 softmax 輸出層和 log-likelihood 組合對照 sigmoid 輸出層和交叉熵的組合類比著看是非常有用的。
有了這樣的相似性,你會使用哪一種呢?實際上,在很多應用場景中,這兩種方式的效果都不錯。本章剩下的內容,我們會使用 sigmoid 輸出層和交叉熵的組合。后面,在第六章中,我們有時候會使用 softmax 輸出層和 log-likelihood 的則和。切換的原因就是為了讓我們的網絡和某些在具有影響力的學術論文中的形式更為相似。作為一種更加通用的視角,softmax 加上 log-likelihood 的組合更加適用于那些需要將輸出激活值解釋為概率的場景。當然這不總是合理的,但是在諸如 MNIST 這種有著不重疊的分類問題上確實很有用。
問題
- 推導方程(81) 和 (82)
- softmax 這個名稱從何處來? 假設我們改變一下 softmax 函數,使得輸出激活值定義如下
其中 $$c$$ 是正的常量。注意 $$c=1$$ 對應標準的 softmax 函數。但是如果我們使用不同的 $$c$$ 得到不同的函數,其實最終的量的結果卻和原來的 softmax 差不多。特別地,證明輸出激活值也會形成一個概率分布。假設我們允許 $$c$$ 足夠大,比如說 $$c\rightarrow \inf$$。那么輸出激活值 $$a_j^L$$ 的極限值是什么?在解決了這個問題后,你應該能夠理解 c=1 對應的函數是一個最大化函數的 softened 版本。這就是 softmax 的來源。
這讓我聯想到 EM 算法,對 k-Means 算法的一種推廣。
- softmax 和 log-likelihood 的反向傳播 上一章,我們推到了使用 sigmoid 層的反向傳播算法。為了應用在 softmax 層的網絡上,我們需要搞清楚最后一層上誤差的表示 $$\delta_j^L \equiv \partial C/\partial z_j^L$$。證明形式如下:
使用這個表達式,我們可以應用反向傳播在采用了 softmax 輸出層和 log-likelihood 的網絡上。