干貨 | Andrej Karpathy CS294課程總結:可視化和理解深度神經網絡
一、介紹
這篇文章中,我們將回顧一些目前用來可視化理解深度神經網絡的方法。我不會深入探討這些材料中的細節(jié),而是闡述一些個人觀點以及我在學習這些材料時的個人體會。所有原始材料來自 Andrej Karpathy 在伯克利大學的客座講座,CS294 課程。
二、凸優(yōu)化(Convex Optimization)vs. 非凸神經網絡(Non-Convex Neural Networks)
凸優(yōu)化是一個數學上非常嚴謹的問題,人們對此也一直頗有研究。它的優(yōu)美之處在于能夠推導出易實現的、達到全局***的下降算法。而非凸優(yōu)化問題,卻很難證明其***性。也因此,我們會擔心針對這些問題提出的優(yōu)化算法會停滯在局部最小值。然而,這并不是說我們不能證明非凸問題***解。我已經碰到過一些技術,這些技術使用了區(qū)間分析(interval analysis)方法,只要函數在某些階上(some odrder)Lipschitz 連續(xù),并且它的解(局部最小值)并不會產生組合性爆炸。
神經網絡本質上是一個非凸問題。因此,對其***性的形式證明***。在過去,擔心差在局部最小值是真的,特別是神經網絡剛剛開始發(fā)展的階段(上世紀 80 年代)。其中一篇關于探討這個話題的論文: 多層網絡的損失面(The Loss Surfaces of Multilayer Networks by Choromanska etal. 2015),實證表明,隨著問題維數增加(可視為隱藏層更多了),你的最終解的損失方差會下降。因此,基本上,***解和最差解之間的間隔在不斷銳減,你的所有的局部最小值會變得相同。因此,非凸優(yōu)化解決方案不過是走開了,人們并沒有真正的解決這個問題,它僅僅是變得不重要了。
三、層圖表達以及 t-SNE 可視化
(編者注: t-SNE 是 t-distributed stochastic neighbor embedding 的縮寫,即 t 分布隨機鄰域嵌入算法)
卷積神經網絡,簡單來說,就是一個多層巨無霸三明治。一種用來視化理解這些網絡的方法就是從網絡中取出一個單獨神經元,觀察讓這個神經元興奮的是什么。本質上,我們經驗使用這些激活反應來可視化神經元響應的對象。
圖注:可視化激活神經網絡的事物
另一個技術是可視化網絡權重。這需要訓練自己的神經網絡然后顯示它學習到的 Gabor 過濾器。不過這種辦法只對卷積神經網絡首層有效,因為針對輸入的圖片所得出的權重在***層后又會再做卷積操作。當你不斷深入網絡,我們就不太能解釋 這些濾波器的結果了,因為每一層的權重都是在前一層輸出結果上進行了卷積操作。
圖注:可視化網絡權重
在此,Andrej 給出了一個關于使用 ConvNetJS 來實現可視化技術的鏈接(https://cs.stanford.edu/people/karpathy/convnetjs/),該項技術能把網絡逐層分解,你可以利用這個來觀察網絡在輸出最終分類結果前每一層的梯度、激活函數、 權重等。此外,Andrej 還推薦了一下 TensorFlow Playground:http://playground.tensorflow.org/,以及 Jason Yosinski 的博客:http://yosinski.com/deepvis
四、不僅僅是單個神經元的可視化
有一種觀察卷積神經網絡的方法是看其全局表達,即卷積神經網絡對任何一張圖片,其頂層的輸出結果。我們將一張圖片傳入卷積神經網絡網絡去處理。這個網絡的每一層將對該圖片進行重新的表達,而對于每一層,我們可以學習到原始的圖片是如何被整合到這一層中的。因此,為了可視化這一過程,我們希望能將這些表達整合到 2 維空間。這時候,就需要用到一種超炫的技術,叫做 t-SNE 可視化技術(Van der Maaten, Hinton**)。**這種技術將高維的點嵌入到低維空間,而局部的成對距離被保留了(在低維空間相鄰的點在高維空間也依然相鄰)。
圖注:t-SNE 可視化
圖注:用強化學習玩 Atari 游戲的可視化
五、遮蓋實驗
這種用于可視化網絡究竟學到了什么的技術是把網絡視作黑盒,修改它的輸入然后觀察輸出。假設我們有一張被這個網絡能準確地分類成博美犬的圖片,現在,我們要做的是將這個圖片的某一塊「屏蔽(block)」(將這個地方的像素值設置為 0 或 255,或者顏色設置為黑或白即可)。這樣,這個網絡的輸出是對這張被屏蔽的圖片的輸出。我們可以發(fā)現,當我們屏蔽的部位越是重要,比如臉部,那么這個網絡做出正確分類可能性就越低。
一個有趣的發(fā)現是,比如,我們有一張照片,其正中部位有一只阿富汗獵犬,旁邊是一位男子,網絡能正確的將其標記為阿富汗獵犬。但是,如果將男人的臉用像素為 0 的方塊遮蓋,網絡認為是阿富汗獵犬的概率激增。發(fā)生這種現象的原因在于,每一張圖片只被分配了一個正確的標簽,當我們遮蓋一些可能會引起網絡會做出其他決定的部位,那么,得出這個正確的標簽的概率就大大提高了。這也是一種完整性檢查,這樣網絡可以一種通過調整圖片可能所屬類別標簽的概率大小來做出合理判斷。
六、去卷積方法(Deconvolution Approaches)
通常,我們嘗試去計算出關于網絡權重的損失函數梯度,這樣當我們每做一次更新操作,我們就能優(yōu)化權重?,F在,讓我們思考一個問題:給出一張圖片,怎樣才能得出網絡中任何一個隨機神經元的梯度?有一種可行的方案是:
1)將圖片輸入網絡,對于網絡深處的某一個神經元,我們將其命名為神經元 a。
2)將它的梯度設置為 1,同層的所有其他神經元的梯度設置為 0。
3)一路將梯度反向傳播回圖片,得到一張略古怪的噪聲圖片。
盡管這張?zhí)荻葓D片很難解釋,但至少可以告訴你,如果把這張圖片和原始圖片疊加,將會提高神經元 a 的激活函數值。而反向傳播過程只會改變修正線性單元 ReLU 層。這里的直覺就是:沿著梯度(反向)傳遞到 ReLU 層的某一個神經元,那么說明這個神經元被激活了。否則,傳遞就會停止。
另一種替代方法是不使用簡單的反向傳播,而是使用所謂的導向反向傳播(guided backpropagation)。
這種技術并不僅能夠識別一個修正線性單元 ReLU 是否被激活,而且可以識別所有值為負的梯度。本質上,除了能把所有不被激活的修正線性單元 ReLU 關閉,所有反向傳播時遇到的負信號還能被設置到閾值 0。最終,我們只需要反向傳遞梯度為正的值即可。這樣的話,反向傳播***獲得的圖片就會更加清晰,因為我們去除了所有負梯度對我們所選的神經元造成的影響,只保留了正面的影響(詳見: Striving for Simplicity: The all Convolutional Net, Springenberg, Dosovitskiy, et al., 2015 for more information)。
圖注:使用 guided backpropagation 后噪聲明顯減少
七、對圖像進行***化
1. 類別可視化
接下來講授的技巧涉及在圖像上進行***化操作。考慮如下問題:我們能否找到一個圖像,它能夠***化某些類別的分數?為達到該目的,我們希望保持神經網絡架構不變,而使用不同損失函數以在圖像上進行***化。這個方法包括如下步驟:
(1) 向神經網絡中傳入一個隨機的圖像;
(2) 設定梯度分數向量為 [0,0,…,1,0,...0](將感興趣的那一類設為 1,不感興趣的則為 0),接著對對象進行反向傳播;
(3) 進行一個小規(guī)?!笀D像更新」;
(4) 將更新的圖像進行正向傳播;
(5) 重復 (2) 以設定其他的梯度分數向量。我們基于一個隨機噪聲的圖像開始,并對目標類(也就使用了上述的梯度分數向量進行逆?zhèn)鞑サ哪且活?進行梯度上升操作,我們會生成一個圖像,它能改進神經網絡對目標類的激活狀態(tài)。從數學上來說,令 I 代表一個圖像,y 代表一個目標類,Sy(I) 則是神經網絡賦給圖像 I 在 y 類上的分數。我們希望解決如下的***化問題:
也就是說,我們希望找到一個圖像 I∗,它能夠***化神經網絡賦給 y 類的分數。在如上的等式中,R 是一個正則化項。正則化項改進了輸出圖像的可視化程度(參見 Simonyan 等人,Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps,ICLR Workshop 2014)。這個內容在去年完成,它論述了類的分數問題。但是,該技巧可以被應用到神經網絡中的所有節(jié)點上。我們從某個隨機圖像開始正向傳播,直到到達了我們想要研究以及可視化的層為止。對該層中的任一神經節(jié)點,重復該步驟(即設定其他梯度分數為 0、目標對象梯度值為 1、在圖像上反向傳播),以檢查哪種圖像會***程度地激活神經網絡中的神經節(jié)點。注意,這些技巧中都有正則化項,以避免對抗的圖像。不同的正則化方案側重圖像的不同方面,以判斷我們認為的「正常的」圖像。所以,它們會對這些試驗的結果有很大影響。
2. 特征反演(Feature Inversion)
另一個可以探討的問題是:給定一個卷積神經網絡的「編碼」(特征代表,可以理解為是神經網絡中某一層的輸出值),能否根據其重構原來圖像?如下的技巧就試圖實現這一功能。它分為三步:
(1) 向網絡中傳入一些輸入圖像;
(2) 忽略輸入圖像;
(3) 在某些層對輸入進行反向傳播,直到在網絡中找到這樣的層,能夠生成與輸入圖像相同的「編碼」(在這一層學到的特征表示)的圖像。
從數學上看,令 I 代表一個輸入圖像,φl(I) 為卷積神經網絡 φ 中的激活層 l。我們希望解決如下優(yōu)化問題:
也就是說,我們希望找到一個圖像 I∗,它與圖像 I 在神經網絡 φ 中的 l 層有相似的特征表示。其中 ||.||2 是代表 L2 范數,R 是正則項(可能是隱式的)。
概括來說,我在這里的想法是,要儲存一個圖像,只需存儲圖像的「編碼」就行了。我們可以根據上述方法使用這些「編碼」來重構圖像(盡管有損失)(參見 Yosinski 等人,"Understanding Neural Networks Through DeepVisualization",ICML 2015 Deep Learning Workshop)。
總的來說,這項技術允許我們看到,圖像是如何通過一組特定「編碼」(特征代表)在神經網絡上被恢復的。
八、卷積網絡中的對抗圖像
對抗圖像,是對原有圖像加入很小的擾動而構成的圖像;這些擾動由數據集的數據構成,被特意設定為最壞情況。由此,神經網絡會錯誤地給這個新形成的圖像很高的概率。在實踐中,我們可以取任一被正確標記的傳入神經網絡的圖像,并基于其它對抗圖像對其添加擾動值。
我們無意探討過深的數學細節(jié),但這種情況發(fā)生的原因是因為神經網絡常有很高的維度,因此,它有著內在的線性本質。直覺上說,我們考慮如下的線性例子:令 x 為一輸入圖像,w 為該模型的權重值,則獲得輸出的運算就是 x 和 w 之間的內積,即 wTx。如果我們以 η 來輕微地對輸入進行擾動,我們則得到 x¯ = x + η。那么,輸出就便成了 x¯ = wT x + wTη。這種對抗擾動導致激活值增長了 wTη。進而,我們可以在某些關于 η 的限制條件下(通常是正則化約束)***化該項以引起模型中的問題。但是,隨著問題維度的不斷增加,我們可以在滿足正則化條件的情況下,對 η 向量施加很多小的擾動。這些細微的變化加在一起,最終會對輸出造成很大的變化。
另一種考察不同模型間對抗圖像的方法,是將他們視為對抗擾動在模型權重向量下高度對齊的結果。這是因為如上解釋中所說的內容:這些小的改變迫使該線性模型專注某一個信號,該信號和模型的權重值最相近;即便其它 (從正確圖像中得來的) 信號有更大的振幅也是如此。
九、Deep Dream 實驗
圖注:Deep Dream GitHub:https://github.com/google/deepdream
Deep Dream 實驗背后的機理實際上是很簡單的?;旧衔覀冎灰薷囊幌聢D像,以增強網絡中選定的某層的激活情況。具體地,我們需要:
(1) 從神經網絡中選擇某一層;
(2) 向其中傳入某些輸入圖像,以確定給定層的特征;
(3) 設定那一層的的梯度值為激活值自身;
(4) 對該圖像進行反向傳播。
十、神經風格實驗
考慮如下的情景:我們有兩個圖像,一個為內容圖像 Ic, 一個為風格圖像 Is,我們想生成第三個圖像,使之能夠具有 Ic 的內容及 Is 的風格。也就是說,我們要做的是從 Ic 中解析出內容,從 Is 中解析出風格。
為了解析出內容,我們將 Ic 傳入我們的神經網絡并儲存每一層的激活值。但解析風格的過程卻有所不同。我們將 Is 傳入神經網絡,并計算每一層激活值的 Garmian 矩陣(G=VTV)。從代數的觀點來看,Garmian 矩陣 G 僅僅是 V 的列內積值。例如,CONV1 層由 244×244×64 個激活值構成,我們則計算得一 64×64 的 Gram 矩陣,它是由每個區(qū)域內配對激活值的協(xié)方差求和而成。從圖像的角度來說,我們是將一層由三維(244×244×64)矩陣構成的激活值轉換到一個二維矩陣((244×244)×64),并對其取外積以得到該 64×64 的矩陣。對矩陣中的每個項 gi,j,我們都是將輸出通道 i 及 j 在那一層上的激活值乘在一起。如果通道 i 及 j 的神經元交結在一起,那么它們會加在一起,我們也會得到一個更大的 gi,j。所以 Gram 矩陣 G 含有在對整個空間位置平均后哪些神經元交結在一起的數據。我們對神經網絡中的每一層都計算一個 Gram 矩陣。
最終,我們有了這些信息之后,就能夠對整個圖像進行***化以得到: Ic 的內容及 Is 的風格(詳見 Leon A. Gatys 等人,《A Neural Algorithm of Artistic Style》,2015)。
***,Andrej 還推薦了一個快速神經風格遷移項目,可以實時通過網絡攝像頭實現風格遷移:https://github.com/jcjohnson/fast-neural-style,參見機器之心文章《開源 | 怎么讓你的照片帶上藝術大師風格?李飛飛團隊開源快速神經網絡風格遷移代碼》。
十一、結語
在這篇回顧中,我們回顧了一些能夠用于理解及可視化神經網絡的技術。這些技術是從各種資源中搜集來的,其呈現的順序與重要性無關。
我們探討了如何可視化那些能***化激活神經元的區(qū)塊,檢查了其權重值及其對激活值的影響(第三節(jié));我們亦討論了使用如 t-SNE 這樣的技術來可視化全局表達(第四節(jié));在所討論的遮蓋實驗中,我們修改了輸入并觀察了輸出改變情況(第五節(jié));然后,我們談到了幾種去卷積方法(第六節(jié)),接著對圖像進行***化(第七節(jié))以***化一個類、神經元之間的激活率(firing rates)或是匹配一個特定的編碼。此外,我們還基于簡化的線性解釋,討論了卷積網絡中的對抗輸入。***,我們涉及到了一些關于***化圖像的一些應用(在***關于 Deep Dream、神經風格的兩節(jié)中)。這些技術表明,神經網絡中的「層」或特性并非僅僅是隨機模式,有著能夠直覺被理解的特性。我們能夠使用這些可視化技巧來發(fā)現模型的中的問題,以獲得更好的結果。
***,我們想提及一個也許更具價值的觀點:如今神經網絡給出的解決方案,在神經網絡不斷增長的情況下的被證明是經驗***的——也就是說,在所謂「好」與「差」的答案之間的鴻溝消失了。所以,困在一個局部***點,也許不再是一個問題。
【本文是51CTO專欄機構機器之心的原創(chuàng)文章,微信公眾號“機器之心( id: almosthuman2014)”】