這一部分開始,是對深度學習的有關內容進行學習,在機器學習中有涉及到部分有關深度學習的內容,如CNN、autoencoder等比較簡單的網路模型。這一部分開始,將對深度學習有一個較為系統的學習和了解。
除了基本理論內容外,中間可能穿插一些tensorflow來實現一些東西,也將在這裡一併涉及。
機器學習中有一個通用的三步走的策略:1.function set 2. cost function 3. find the best model。而在深度學習中同樣也是通用的:
第一步:設計一個網路結構,網路結構的引數的不同,組成了一系列的function set,通常深度學習中需要我們自己去設計出網路的結構,然後讓其自動學習其中的引數;
第二步:設計損失函數,通常損失函數根據任務不同需要設計不同的損失函數;
第三步:根據損失函數,讓機器自己去學習得到所設計網路中的各個引數。
本節主要介紹一些在深度學習中常見的一些網路結構,當然,網路結構是多種多樣的,也不可能羅列和學習的完,這裡主要一些常見的或者說是主流的一些結構進行介紹,包括:
1. 全連線網路結構
2. Basic RNN
3. RNN中的LSTM
這種網路結構在機器學習中做了初步的介紹,在前面介紹時,都是以「元素化」的形式進行計算,而在深度學習中多以矩陣的形式運算,在此先對結構中的變數進行宣告:
首先,對於某一層而言:
ail表示第l層的第i個元素,上標「l」表示第l層隱藏層,下標「i」表示第l層的第i個神經元。那麼al則就表示一個向量。
接下來就是全連線中的運算:
從l-1層到第l的運算,第l層的每一個元素都與第l-1層每一個元素有關,因此稱之為全連線網路。
而連線ail與ajl-1的邊稱之為權重wijl,那麼整個w就可以寫成矩陣的形式,矩陣的行數是第l層的神經元的個數,矩陣的列數則是第l-1層的神經元個數。
同樣地,對於引數b,也是一樣:
第l-1層的輸出al-1經過w和b的轉換後,再經過啟用函數,可以得到al,在經過啟用函數前,變數為z,那麼:
那麼從第l-1層到第l層的全連線網路的運算表示為:
然後zl再經過啟用函數:
這樣就以矩陣的形式表示出在全連線網路中兩層之間的關係了:
以上就是全連線網路的基本形式和計算過程。
RNN(Recurrent Neural NetWork)是深度學習中最常見也是最常用的一種技術。為什麼要用RNN呢?
假設在slot filling中,有一個訂票系統,一個人說:
在這句話中"Taipei"表示目的地,出發時間是11月2日。
如果用傳統的神經網路來自動識別出目的地和出發日期,我們訓練一個網路:
輸入「Taipei」則對應的輸出在目的地的概率大,相反,在出發日期的對應的y的概率大。
然而,這裡會有一個問題,當另一個人說了一句話:
而此時的"Taipei"變成了出發地,時間變成了出發時間,但對於傳統的網路來說,同樣的輸入"Taipei"則對於模型而言就無法分出是出發地還是目的地。
此時傳統的網路模型就失效了。
此時就要用到RNN了,之所以RNN可以奏效,是因為RNN可以儲存之前的資訊,通過上下文再進行決策。RNN是如何儲存資訊的呢?
RNN的基本結構圖下:
可以看到,相比於傳統的神經網路,多了cell,可以用來儲存資訊,這些資訊來自於之前的輸入。
如何儲存呢?下面舉個例子,假設有三組資料:
網路所有的權重假設為1,初始化cell都為0,那麼當輸入【1,1】時,第一個layer輸出為【2,2】,那麼【2,2】被儲存到cell中,再經過下一個layer,輸出為【4,4】。
然後下一個時刻,這個儲存到cell中的值就會被拿來當做輸入,並和該時刻的x一起輸入到第一個layer中去:
然後經過後面的結構,第二個時刻輸出為【12,12】。此時cell儲存的值也被更新為【6,6】。
依次類推,到第三個時刻,輸入【2,2】,那麼cell中的【6,6】將一起作為輸入到網路中:
最終輸出為【32,32】。
而當輸入的順序改變時,那麼輸出也就不同。因此對於相同的輸入,由於上下文不同以及輸入的順序不同,RNN的輸出也就不同。
上面就是RNN的"前向傳播"的過程,RNN是隨著時間進行傳播的,將前面時刻的輸入保留「記憶」,輸入到下一個時刻中,總的來說,RNN的基本結構如下:
由於訓練時「Taipei」前面的輸入不同,因此,對於輸出也是不同的:
那麼RNN的一般架構如下:
其中f是一種網路結構,且這種結構在RNN中被反覆使用,也就是說,其中的引數都是一致的。
當然RNN也可以是Deep的:
還有一種比較常見的RNN結構,是雙向RNN:
也就是說,對於yt而言,不僅僅只由xt來決定,還有xt+1,xt+2.....決定。
以上就是一般的RNN的幾種基本結構,之所以稱之為最基本的結構,是因為其中的網路結構是最基本的,也就是:
這種結構通過輸入x和前一個時刻的輸出h,決定當前時刻的輸出y。f的組成就是一堆普通的neural組成的。
然而,RNN也存在一定的問題,當輸入的序列很大時,假設一個最簡單的RNN:
那麼:
可以看到,由於長期的依賴問題,當序列長度過長時,w有略微增大時,最終輸出的結果就變得很大,此時梯度極大,產生梯度爆炸;
當w微小變化時,則輸出變為0,此時梯度幾乎也為0,產生梯度消失。
而為了解決這種長期依賴導致梯度消失的問題,LSTM也就應運而生。
LSTM(Long Short-term Memory)是一種解決RNN長期依賴導致的梯度消失(不是梯度爆炸)的方法,先來說LSTM的基本結構,然後再說為什麼可以解決梯度消失。
一個LSTM的基本單元結構如下:
這個單元有3個gate和一個memory cell,gate負責控制memory的通路;
輸入有四個:
1、一個輸入x(這個x是經過一個轉換後的);
2、一個控制input gate的訊號,該訊號決定x是否要寫進memory;
3、一個控制forget gate的訊號,該訊號決定著memory裡的內容是否要被重置;
4、一個控制output gate的訊號,該訊號決定著memory裡的內容是否要被輸出。
輸出有一個:
單元的輸出。
更具體地,LSTM的基本單元結構為:
在LSTM結構裡這幾個門的啟用函數f通常使用sigmoid函數,這是因為sigmoid輸出值在0~1之間便於控制門的開啟和關閉。
該結構中,輸入為z(輸入)、zi(操控input gate的訊號)、zo(操控output gate的訊號)、zf(操控forget gate的訊號):
1、z經過啟用函數g,得到g(z);
2、zi經過啟用函數f,得到f(zi);
3、g(z)與f(zi)相乘(element wise),得到節點處的值;此時,如果input gate被關閉,f(zi)=0,二者相乘也為0,所以輸入z不會被考慮。
4、zf經過啟用函數f,得到f(zf);
5、f(zf)與原cell中的c相乘,再與節點處的值相加,得到新的c';此時如果f(zf)為0,也就是forget gate被關閉時,則原cell中的c就會被遺忘;
6、新的c'存入到cell中去;
7、c'經過啟用函數h,得到h(c');
8、zo經過啟用函數得到f(zo),然後與h(c')相乘,得到輸出,當f(zo)為0時,也就是output gate被關閉時,則輸出為0;
上面就是單個cell進入LSTM單元的計算過程,那麼當有多個cell時,組成一個向量:
綜上,為了更加清晰地描述LSTM的結構,全部採用向量的形式:
然後zf,zi,z,zo在LSTM的結構中進行運算:
有時也會把上一個時刻的ct-1一併放入到z的計算當中去,稱為peephole:
通常將ct-1放入時,w矩陣對應的ct-1那一塊一般會強制為對角矩陣(一般規定這麼做,也確實有好的結果,至於為什麼...)。
當然,上面只是一個時刻的,下一時刻同樣地:
以上就是LSTM的基本結構,那麼之所有LSTM可以解決梯度消失的問題,主要有兩個原因:
1、LSTM的memory不單單是序列之間傳遞時相乘的,還有一部分是相加的;
2、LSTM的memory一直都不會消失,除非當forget gate被關閉時,才會被洗掉。
上面就是LSTM的基本結構和前向傳播過程。
上邊LSTM有3個gate,還有另外一種結構, 可以說是LSTM的進階版,叫做GRU,其結構如下:
不同於LSTM的是,GRU只有input gate和forget gate,而且兩個gate是相互聯動的,input gate開啟時,forget gate就會被關閉。
這樣GRU相當於在LSTM的基礎上又減少了引數,比較不容易過擬合。
折積神經網路(CNN)在【機器學習基礎】部分已詳細學習過了,這裡就不再寫了。
RNN根據任務的不同,輸入輸出也就不同,對於不同的輸入和輸出的序列長度,在設計RNN網路結構時也存在差異,一般有如下幾種情況(圖片來源於網路):
對於many2one,在語意分析或者評論文字分析中經常用到:
而對於many2many使用場景比較廣泛,比如翻譯、語音識別等都是這樣的情況,而在many2many也分為輸入輸出相等、輸出更短、無限制的情況。
對於輸入輸出同等長度的就不再說了,下面看下輸出更短的情況,在語音識別中:
通過輸入聲音訊號處理後的特徵(acoustic features),轉換為輸入輸出同等長度,然後再去掉重複的字就可以了。
但是這樣無法處理疊詞的問題,「好棒」和「好棒棒」兩個相反的詞義,就無法進行分辨。一種處理這種情況的方法就是CTC(Connectionist Temporal Classificaion)。
CTC通過新增特殊符號「φ」來處理疊詞的問題:
這樣就解決這個問題了,那麼帶有「φ」的符號在訓練時,就要窮舉每個可能的符號是「φ」的情況,認為這些都是正確的樣本:
而對於另一個many2many沒有限制輸入輸出數量的問題,比如翻譯:
訓練時需要在句子的末尾加上結束的標誌:
對於沒有標籤的學習任務,比如文字語意的分析,對於組成相同的兩句話:
兩句話的意義卻完全不同,此時使用前面說過的autoencoder可以解決這樣的問題:
autoencoder也可以用於語音識別中,比如聽歌識曲,將歌曲用一code來表示,輸入一段歌曲,可以搜尋相近的code進行匹配:
上面就是在深度學習中一些基本的網路結構,隨著深度學習的發展,這些結構也出現了各種各樣的形式,但萬變不離其宗,這部分是後面學習的基礎,後面學習到再進行完善和補充,接下來就複習一下這些基本的結構在tensorflow中的實現。