1. 程式人生 > >深度學習UFLDL教程翻譯之自動編碼器

深度學習UFLDL教程翻譯之自動編碼器

一、自動編碼器

       目前為止,我們介紹了神經網路在有標籤的訓練樣本的有監督學習中的應用.現在假設我們只有一個未標記的訓練集{x(1),x(2),x(3),…},其中x是n維的.自動編碼器神經網路是一種採用反向傳播的無監督學習演算法,讓目標值和輸入相等,即讓y(i)=x(i).

這是一個自動編碼器:


       自動編碼器試圖學習函式hW,b(x)≈x.換句話說,它試圖學習恆等函式的逼近,使得輸出x^與x類似.這個將要學習的恆等函式看起來是個特別無關緊要的函式;但通過在網路中做些限制,例如限制隱藏單元的個數,我們可以發現數據中的有趣結構.具體地說,假設輸入x是10*10影象的畫素強度值,n=100,然後L2層有s2=50個隱藏單元.注意到y也是100維的.既然只有50個隱藏單元,網路不得不學習輸入的一個“壓縮”表示,即給定隱藏單元的啟用值a(2)只有50維,它必須“重構”100個畫素的輸入.如果輸入是完全隨機的,即每個xi與其它特徵值是高斯獨立同分布的,那麼這次壓縮任務會非常困難.但是如果資料中包含結構,例如如果一些輸入特徵是相關的,那麼這個演算法可以發現這些相關性.事實上,這個簡單的編碼器經常用於學習低維度表示,很像PCA(主成份分析).

       以上的論點是根據隱藏層單元小數目s2.不過即使當隱藏層單元數目大時(也許甚至比輸入畫素數目還大),通過對網路施加其它限制,我們依舊能發現有趣的結構.特別的,如果我們對隱藏層單元施加“稀疏”的限制,那麼我們依舊在資料中能發現有趣的結構,即使隱藏層單元數目多.

       非正式地說,我們會認為神經元是“啟用的”(或者“點著了”),如果它的輸出接近1;或者“未啟用”如果它的輸出接近0.我們希望限制神經元在大部分時間是未啟用的狀態.這個討論假設用的是sigmoid啟用函式.如果你使用tanh啟用函式,我們會認為神經元是未啟用的,如果它的輸出接近-1.

       回憶一下aj(2)

表示自動編碼器隱藏單元j的啟用值.然而,這樣的表示不能搞清楚引起啟用值的輸入x是什麼.這樣,我們會用aj(2)(x)表示當網路給定輸入是x時該隱藏單元的啟用值.

       進一步,令


是隱藏單元j的平均啟用值(在訓練集上取平均).我們可以(近似)實施限制ρ^j=ρ,其中ρ是一個“稀疏引數”,典型值接近0的小值(例如ρ=0.05).換句話說,我們希望每個隱藏單元j的平均啟用值接近0.05(假設).為了滿足這個限制,隱藏單元的大多數啟用值都必須接近0.

       為了實現,我們往我們的優化目標新增一個額外的懲罰項,懲罰ρ^j對ρ的偏離程度.懲罰項的許多選擇都能得到合理的結果.我們選擇以下形式:


這裡,s2是隱藏層的神經元數目,下標j對網路中的隱藏單元求和.如果你熟悉KL分解的概念,這個懲罰項就是基於此,也可以寫為


其中KL(ρ||ρ^j)=ρlogρ/ρ^j+(1−ρ)log1−ρ/1−ρ^j是伯努力隨機變數——平均值ρ和ρ^j間的Kullback-Leibler(KL)分解。KL分解是衡量兩個不同的分佈有多不同。(如果你之前還沒有見過KL分解,別擔心;你需要了解的所有東西都在這節中。)

       懲罰函式有這樣的性質,如果ρ^j=ρ,則KL(ρ||ρ^j)=0,否則會隨著ρ^j和ρ的偏離程度單調遞增。例如,在下面的圖中,我們令ρ=0.2,我們畫出關於取一定範圍ρ^j,KL(ρ||ρ^j)的值。


我們看到KL分解在ρ^j=ρ處取得最小值0.並隨著ρ^j接近0或1而迅速增大(實際上趨於無窮大).因此,最小化這一懲罰項使得ρ^j接近ρ.

       我們目前的全域性代價函式是


其中J(W,b)之前定義過了,β控制稀疏懲罰項的權重。ρ^j項也(隱性地)依賴W,b,因為它是隱藏單元j的平均啟用值,而隱藏單元的啟用值依賴引數W和b。

       為了讓KL分解項包含到你的導數計算中,有一種易於實現的技巧,只需要對你的程式碼做小的改變。具體而言,之前在第二層(l=2)中,在反向傳播過程中你將會計算:


取而代之的是計算


一個微妙的地方是你需要知道ρ^i來計算這項。那麼,你就首先需要在所有訓練樣本計算前向傳播,從而計算訓練集上的平均啟用值,然後再從任一樣本中計算反向傳播。如果你的訓練集足夠小,能夠很好地滿足計算機記憶體(這對程式設計任務而言也是一樣的),你可以在所有樣本上計算前向傳播,並將啟用值結果儲存在記憶體中然後計算ρ^i。然後你可以用之前計算的啟用值在所有樣本上計算反向傳播。如果你的資料太多記憶體裝不下,你只能瀏覽所有的樣本,在每個樣本上計算前向傳播然後將啟用值累積(求和)然後計算ρ^i(一旦你用啟用值ai(2)計算完ρ^i,便丟棄每次計算前向傳播的結果)。然後計算完ρ^i後,你再對每個樣本做一次前向傳播計算以便你能夠在那個樣本上做反向傳播。在後面這種情況,你會在訓練集的每個樣本計算兩次前向傳播結束,使得計算效率較差。

       以上的演算法得到梯度下降的完整推導已經超出了這節的篇幅。不過如果你使用修改後的反向傳播實現自動編碼器,你將在目標函式Jsparse(W,b)上計算梯度下降。使用導數檢驗的方法,你也可以自己驗證。

二、視覺化訓練好的自動編碼器

       訓練好(稀疏)自動編碼器後,我們想要視覺化這個演算法學習的函式,並理解它學習了什麼。考慮在10×10影象上訓練的自動編碼器,因此n=100。每個隱藏單元i計算輸入的函式:


       我們會使用2D影象將通過隱藏單元i計算的函式視覺化——依賴引數Wij(1)(這裡忽略偏置項)。特別地,我們認為ai(2)是輸入x的一些非線性的特徵。我們會問:是什麼樣的輸入影象x能讓ai(2)最大程度啟用?(不是很正式地說,隱藏單元i在尋找什麼樣的特徵?)為了得到這個不是無關緊要的問題的回答,我們需要在x上施加一些限制。如果我們假設輸入被||x||2=∑xi2≤1標準化限制,那麼我們可以看到(嘗試自己完成)最大化地啟用隱藏單元i的輸入是由按如下方式設定畫素xj給定的(對全部100畫素而言,j為1到100):


通過將由這些畫素強度值填充的影象顯示出來,我們可以開始理解隱藏單元i在尋找什麼樣的特徵。

       如果我們有一個包含100個(舉例)隱藏單元的自動編碼器,那麼我們的視覺化影象將得到100幅這樣的影象——一個代表一個隱藏單元。通過檢查這100幅影象,我們能嘗試理解隱藏單元在學習一個什麼集合。

       當我們對一個稀疏自編碼器這麼做(用建立在10×10畫素輸入上的100個隱藏單元訓練),我們會得到如下結果(每個影象10*10代表一個隱藏單元,共100個隱藏單元):


       上圖中的每個方塊展示了(用標準化界定的)輸入影象x,它最大化地激活了100個隱藏單元的其中一個。我們發現不同的隱藏單元在學習檢測影象中不同位置和方向的邊緣。

       這些特徵,不驚奇地,對於像目標識別和其它視覺任務等是非常有用的。當應用到其它輸入領域(例如音訊),這個演算法同樣學習對這些領域有用的表示/特徵。

       這些學習到的特徵是通過訓練“白化的”自然影象得到的。白化是去除輸入冗餘度的預處理步驟,使相鄰的畫素點變得更不相關。