循環(huán)神經(jīng)網(wǎng)絡(luò)

花書中關(guān)于RNN的內(nèi)容記錄于http://www.itdecent.cn/p/206090600f13。

在前饋神經(jīng)網(wǎng)絡(luò)中,信息的傳遞是單向的,這種限制雖然使得網(wǎng)絡(luò)變得更容易學(xué)習,但在一定程度上也減弱了神經(jīng)網(wǎng)絡(luò)模型的能力。在生物神經(jīng)網(wǎng)絡(luò)中,神經(jīng)元之間的連接關(guān)系要復(fù)雜的多。前饋神經(jīng)網(wǎng)絡(luò)可以看作是一個復(fù)雜的函數(shù),每次輸入都是獨立的,即網(wǎng)絡(luò)的輸出只依賴于當前的輸入。但是在很多現(xiàn)實任務(wù)中,網(wǎng)絡(luò)的輸入不僅和當前時刻的輸入相關(guān),也和其過去一段時間的輸出相關(guān)。因此,前饋網(wǎng)絡(luò)難以處理時序數(shù)據(jù),比如視頻、語音、文本等。時序數(shù)據(jù)的長度一般是不固定的,而前饋神經(jīng)網(wǎng)絡(luò)要求輸入和輸出的維數(shù)都是固定的,不能任意改變。因此,當處理這一類和時序相關(guān)的問題時,就需要一種能力更強的模型。

循環(huán)神經(jīng)網(wǎng)絡(luò)(Recurrent Neural Network,RNN)是一類具有短期記憶能力的神經(jīng)網(wǎng)絡(luò)。在循環(huán)神經(jīng)網(wǎng)絡(luò)中,神經(jīng)元不但可以接受其它神經(jīng)元的信息,也可以接受自身的信息,形成具有環(huán)路的網(wǎng)絡(luò)結(jié)構(gòu)。和前饋神經(jīng)網(wǎng)絡(luò)相比,循環(huán)神經(jīng)網(wǎng)絡(luò)更加符合生物神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)。循環(huán)神經(jīng)網(wǎng)絡(luò)已經(jīng)被廣泛應(yīng)用在語音識別、語言模型以及自然語言生成等任務(wù)上。循環(huán)神經(jīng)網(wǎng)絡(luò)的參數(shù)學(xué)習可以通過隨時間反向傳播算法來學(xué)習。

1、給網(wǎng)絡(luò)增加記憶能力

為了處理這些時序數(shù)據(jù)并利用其歷史信息,我們需要讓網(wǎng)絡(luò)具有短期記憶能力。而前饋網(wǎng)絡(luò)是一個靜態(tài)網(wǎng)絡(luò),不具備這種記憶能力。

1.1、延時神經(jīng)網(wǎng)絡(luò)

一種簡單的利用歷史信息的方法是建立一個額外的延時單元,用來存儲網(wǎng)絡(luò)的歷史信息(可以包括輸入、輸出、隱狀態(tài)等)。比較有代表性的模型是延時神經(jīng)網(wǎng)絡(luò)。

延時神經(jīng)網(wǎng)絡(luò)是在前饋網(wǎng)絡(luò)中的非輸出層都添加一個延時器,記錄最近幾次神經(jīng)元的輸出。在第t個時刻,第l + 1層神經(jīng)元和第l層神經(jīng)元的最近p次輸出相關(guān),即:

\mathbf{h}_{t}^{(l+1)}=f\left(\mathbf{h}_{t}^{(l)}, \mathbf{h}_{t-1}^{(l)}, \cdots, \mathbf{h}_{t-p}^{(l)}\right)

延時神經(jīng)網(wǎng)絡(luò)在時間維度上共享權(quán)值,以降低參數(shù)數(shù)量。因此對于序列輸入來講,延時神經(jīng)網(wǎng)絡(luò)就相當于卷積神經(jīng)網(wǎng)絡(luò)。

1.2、有外部輸入的非線性自回歸模型

自回歸模型(Autoregressive Model,AR)是統(tǒng)計學(xué)上常用的一類時間序列模型,用一個變量y_t的歷史信息來預(yù)測自己:

\mathbf{y}_{t}=w_{0}+\sum_{i=1}^{p} w_{p} \mathbf{y}_{t-i}+\epsilon_{t}

其中p為超參數(shù),w_p為參數(shù),\epsilon_{t} \sim \mathcal{N}\left(0, \sigma^{2}\right)為第t個時刻的噪聲,方差σ^2和時間無關(guān)。

有外部輸入的非線性自回歸模型(Nonlinear Autoregressive with ExogenousInputs Model,NARX)是自回歸模型的擴展,在每個時刻t都有一個外部輸入x_t,產(chǎn)生一個輸出y_t。NARX通過一個延時器記錄最近幾次的外部輸入和輸出,第t個時刻的輸出y_t為:

\mathbf{y}_{t}=f\left(\mathbf{x}_{t}, \mathbf{x}_{t-1}, \cdots, \mathbf{x}_{t-p}, \mathbf{y}_{t-1}, \mathbf{y}_{t-2}, \cdots, \mathbf{y}_{t-q}\right)

其中f(·)表示非線性函數(shù),可以是一個前饋網(wǎng)絡(luò),pq為超參數(shù)。

1.3、循環(huán)神經(jīng)網(wǎng)絡(luò)

循環(huán)神經(jīng)網(wǎng)絡(luò)通過使用帶自反饋的神經(jīng)元,能夠處理任意長度的時序數(shù)據(jù)。

給定一個輸入序列\mathbf{x}_{1 : T}=\left(\mathbf{x}_{1}, \mathbf{x}_{2}, \dots, \mathbf{x}_{t}, \dots, \mathbf{x}_{T}\right),循環(huán)神經(jīng)網(wǎng)絡(luò)通過下面
公式更新帶反饋邊的隱藏層的活性值h_t

\mathbf{h}_{t}=f\left(\mathbf{h}_{t-1}, \mathbf{x}_{t}\right)

其中h_0 = 0,f(·)為一個非線性函數(shù),也可以是一個前饋網(wǎng)絡(luò)。

從數(shù)學(xué)上講,上式可以看成一個動力系統(tǒng)。動力系統(tǒng)(Dynamical System)是一個數(shù)學(xué)上的概念,指系統(tǒng)狀態(tài)按照一定的規(guī)律隨時間變化的系統(tǒng)。具體地講,動力系統(tǒng)是使用一個函數(shù)來描述一個給定空間(如某個物理系統(tǒng)的狀態(tài)空間)中所有點隨時間的變化情況。因此,隱藏層的活性值h_t在很多文獻上也稱為狀態(tài)(State)或隱狀態(tài)(Hidden States)。理論上,循環(huán)神經(jīng)網(wǎng)絡(luò)可以近似任意的非線性動力系統(tǒng)。

2、簡單循環(huán)網(wǎng)絡(luò)

簡單循環(huán)網(wǎng)絡(luò)(Simple Recurrent Network,SRN)是一個非常簡單的循環(huán)神經(jīng)網(wǎng)絡(luò),只有一個隱藏層的神經(jīng)網(wǎng)絡(luò)。

在一個兩層的前饋神經(jīng)網(wǎng)絡(luò)中,連接存在相鄰的層與層之間,隱藏層的節(jié)點之間是無連接的。而簡單循環(huán)網(wǎng)絡(luò)增加了從隱藏層到隱藏層的反饋連接。

假設(shè)在時刻t時,網(wǎng)絡(luò)的輸入為x_t,隱藏層狀態(tài)(即隱藏層神經(jīng)元活性值)h_t不僅和當前時刻的輸入x_t相關(guān),也和上一個時刻的隱藏層狀態(tài)h_{t?1}相關(guān):

\begin{array}{l}{\mathbf{z}_{t}=U \mathbf{h}_{t-1}+W \mathbf{x}_{t}+\mathbf} \\ {\mathbf{h}_{t}=f\left(\mathbf{z}_{t}\right)}\\ \end{array}

其中z_t為隱藏層的凈輸入,f(·)是非線性激活函數(shù),通常為Logistic函數(shù)或Tanh函數(shù),U為狀態(tài)-狀態(tài)權(quán)重矩陣,W為狀態(tài)-輸入權(quán)重矩陣,b為偏置。上面兩式也經(jīng)常直接寫為:

\mathbf{h}_{t}=f\left(U \mathbf{h}_{t-1}+W \mathbf{x}_{t}+\mathbf\right)

如果我們把每個時刻的狀態(tài)都看作是前饋神經(jīng)網(wǎng)絡(luò)的一層的話,循環(huán)神經(jīng)網(wǎng)絡(luò)可以看作是在時間維度上權(quán)值共享的神經(jīng)網(wǎng)絡(luò)。下圖給出了按時間展開的循環(huán)神經(jīng)網(wǎng)絡(luò)。

由于循環(huán)神經(jīng)網(wǎng)絡(luò)具有短期記憶能力,相當于存儲裝置,因此其計算能力十分強大。前饋神經(jīng)網(wǎng)絡(luò)可以模擬任何連續(xù)函數(shù),而循環(huán)神經(jīng)網(wǎng)絡(luò)可以模擬任何程序。

定義一個完全連接的循環(huán)神經(jīng)網(wǎng)絡(luò),其輸入為x_t,輸出為y_t

\begin{aligned} \mathbf{h}_{t} &=f\left(U \mathbf{h}_{t-1}+W \mathbf{x}_{t}+\mathbf\right) \\ \mathbf{y}_{t} &=V \mathbf{h}_{t} \\ \end{aligned}

其中h為隱狀態(tài),f(·)為非線性激活函數(shù),U、W、bV為網(wǎng)絡(luò)參數(shù)。

這樣一個完全連接的循環(huán)神經(jīng)網(wǎng)絡(luò)可以近似解決所有的可計算問題。

3、應(yīng)用到機器學(xué)習

循環(huán)神經(jīng)網(wǎng)絡(luò)可以應(yīng)用到很多不同類型的機器學(xué)習任務(wù)。根據(jù)這些任務(wù)的特點可以分為以下幾種模式:序列到類別模式、同步的序列到序列模式、異步的序列到序列模式。

3.1、序列到類別模式

序列到類別模式主要用于序列數(shù)據(jù)的分類問題:輸入為序列,輸出為類別。比如在文本分類中,輸入數(shù)據(jù)為單詞的序列,輸出為該文本的類別。

假設(shè)一個樣本\mathbf{x}_{1 : T}=\left(\mathbf{x}_{1}, \cdots, \mathbf{x}_{T}\right)為一個長度為T的序列,輸出為一個類別y \in\{1, \cdots, C\}。我們可以將樣本x按不同時刻輸入到循環(huán)神經(jīng)網(wǎng)絡(luò)中,并得到不同時刻的隱藏狀態(tài)\mathbf{h}_{1}, \cdots, \mathbf{h}_{T}。我們可以將h_T看作整個序列的最終表示(或特征),并輸入給分類器g(·)進行分類:

\hat{y}=g\left(\mathbf{h}_{T}\right)

其中g(·)可以是簡單的線性分類器(比如Logistic 回歸)或復(fù)雜的分類器(比如多層前饋神經(jīng)網(wǎng)絡(luò))

除了將最后時刻的狀態(tài)作為序列表示之外,我們還可以對整個序列的所有狀態(tài)進行平均,并用這個平均狀態(tài)來作為整個序列的表示:

\hat{y}=g\left(\frac{1}{T} \sum_{t=1}^{T} \mathbf{h}_{t}\right)

3.2、同步的序列到序列模式

同步的序列到序列模式主要用于序列標注(Sequence Labeling)任務(wù),即每一時刻都有輸入和輸出,輸入序列和輸出序列的長度相同。比如詞性標注(Partof-Speech Tagging)中,每一個單詞都需要標注其對應(yīng)的詞性標簽。

輸入為序列\mathbf{x}_{1 : T}=\left(\mathbf{x}_{1}, \cdots, \mathbf{x}_{T}\right),輸出為序列y_{1 : T}=\left(y_{1}, \cdots, y_{T}\right)。樣本x按不同時刻輸入到循環(huán)神經(jīng)網(wǎng)絡(luò)中,并得到不同時刻的隱狀態(tài)h_1,\cdots,h_T。每個時刻的隱狀態(tài)h_t代表當前和歷史的信息,并輸入給分類器g(·)得到當前時刻的標簽\hat{y}_{t}。

\hat{y}_{t}=g\left(\mathbf{h}_{t}\right), \quad \forall t \in[1, T]

3.3、異步的序列到序列模式

異步的序列到序列模式也稱為編碼器-解碼器(Encoder-Decoder)模型,即輸入序列和輸出序列不需要有嚴格的對應(yīng)關(guān)系,也不需要保持相同的長度。比如在機器翻譯中,輸入為源語言的單詞序列,輸出為目標語言的單詞序列。

在異步的序列到序列模式中,輸入為長度為T的序列\mathbf{x}_{1 : T}=\left(\mathbf{x}_{1}, \cdots, \mathbf{x}_{T}\right),輸出為長度為M的序列y_{1 : T}=\left(y_{1}, \cdots, y_{M}\right)。經(jīng)常通過先編碼后解碼的方式來實現(xiàn)。先將樣本x按不同時刻輸入到一個循環(huán)神經(jīng)網(wǎng)絡(luò)(編碼器)中,并得到其編碼h_T。然后再使用另一個循環(huán)神經(jīng)網(wǎng)絡(luò)(解碼器)中,得到輸出序列\hat{y}_{1:M}。為了建立輸出序列之間的依賴關(guān)系,在解碼器中通常使用非線性的自回歸模型。

\begin{aligned} \mathbf{h}_{t}&=f_{1}\left(\mathbf{h}_{t-1}, \mathbf{x}_{t}\right),&\forall t \in[1, T]\\ \mathbf{h}_{T+t} &=f_{2}\left(\mathbf{h}_{T+t-1}, \hat{\mathbf{y}}_{t-1}\right),&\forall t \in[1, M] \\ \hat{y}_{t} &=g\left(\mathbf{h}_{T+t}\right),&\forall t \in[1, M] \end{aligned}

其中f1(·), f2(·)分別為用作編碼器和解碼器的循環(huán)神經(jīng)網(wǎng)絡(luò),g(·)為分類器,\hat{\mathbf{y}}_{t}為預(yù)測輸出\hat{y}_{t}的向量表示。

4、參數(shù)學(xué)習

循環(huán)神經(jīng)網(wǎng)絡(luò)的參數(shù)可以通過梯度下降方法來進行學(xué)習。給定一個訓(xùn)練樣本(x, y),其中\mathbf{x}_{1 : T}=\left(\mathbf{x}_{1}, \cdots, \mathbf{x}_{T}\right)為長度是T的輸入序列,y_{1 : T}=\left(y_{1}, \cdots, y_{T}\right)是長度為T的標簽序列。即在每個時刻t,都有一個監(jiān)督信息y_t,我們定義時刻t的損失函數(shù)為:

\mathcal{L}_{t}=\mathcal{L}\left(y_{t}, g\left(\mathbf{h}_{t}\right)\right)

其中g\left(\mathbf{h}_{t}\right)為第t時刻的輸出,\mathcal{L}為可微分的損失函數(shù),比如交叉熵。那么整個序列上損失函數(shù)為:

\mathcal{L}=\sum_{t=1}^{T} \mathcal{L}_{t}

整個序列的損失函數(shù)\mathcal{L}關(guān)于參數(shù)U的梯度為:

\frac{\partial \mathcal{L}}{\partial U}=\sum_{t=1}^{T} \frac{\partial \mathcal{L}_{t}}{\partial U}

即每個時刻損失\mathcal{L}_{t}對參數(shù)U的偏導(dǎo)數(shù)之和。

循環(huán)神經(jīng)網(wǎng)絡(luò)中存在一個遞歸調(diào)用的函數(shù)f(·),因此其計算參數(shù)梯度的方式和前饋神經(jīng)網(wǎng)絡(luò)不太相同。在循環(huán)神經(jīng)網(wǎng)絡(luò)中主要有兩種計算梯度的方式:隨時間反向傳播(BPTT)和實時循環(huán)學(xué)習(RTRL)算法。

4.1、隨時間反向傳播算法(BPTT)

隨時間反向傳播(Backpropagation Through Time,BPTT)算法的主要思想是通過類似前饋神經(jīng)網(wǎng)絡(luò)的錯誤反向傳播算法來進行計算梯度。

BPTT算法將循環(huán)神經(jīng)網(wǎng)絡(luò)看作是一個展開的多層前饋網(wǎng)絡(luò),其中“每一層”對應(yīng)循環(huán)網(wǎng)絡(luò)中的“每個時刻”。在“展開”的前饋網(wǎng)絡(luò)中,所有層的參數(shù)是共享的,因此參數(shù)的真實梯度是將所有“展開層”的參數(shù)梯度之和。

因為參數(shù)U和隱藏層在每個時刻k的凈輸入\mathbf{z}_{k}=U \mathbf{h}_{k-1}+W \mathbf{x}_{k}+\mathbf有關(guān),因此第t時刻的損失函數(shù)\mathcal{L}_{t}關(guān)于參數(shù)u_{ij}的梯度為:

\frac{\partial \mathcal{L}_{t}}{\partial u_{i j}}=\sum_{k=1}^{t} \frac{\partial^{+} \mathbf{z}_{k}}{\partial u_{i j}} \frac{\partial \mathcal{L}_{t}}{\partial \mathbf{z}_{k}}

其中\frac{\partial^{+} \mathbf{z}_{k}}{\partial \boldsymbol{u}_{i j}}表示“直接”偏導(dǎo)數(shù),即公式\mathbf{z}_{k}=U \mathbf{h}_{k-1}+W \mathbf{x}_{k}+\mathbf中保持h_{k?1}不變,對u_{ij}求偏導(dǎo)數(shù),得到:

\begin{aligned} \frac{\partial^{+} \mathbf{z}_{k}}{\partial u_{i j}} &=\left[0, \cdots,\left[\mathbf{h}_{k-1}\right]_{j}, \cdots, 0\right] \\ & \triangleq \mathbb{I}_{i}\left(\left[\mathbf{h}_{k-1}\right]_{j}\right) \end{aligned}

其中\left[\mathbf{h}_{k-1}\right]_{j}為第k ? 1時刻隱狀態(tài)的第j維;I_i(x)除了第i個值為x外,其余都為0的行向量。

定義誤差項\delta_{t, k}=\frac{\partial \mathcal{L}_{t}}{\partial \mathbf{z}_{k}}為第t時刻的損失對第k時刻隱藏神經(jīng)層的凈輸入z_k的導(dǎo)數(shù),則:

\begin{aligned} \delta_{t, k} &=\frac{\partial \mathcal{L}_{t}}{\partial \mathbf{z}_{k}} \\ &=\frac{\partial \mathbf{h}_{k}}{\partial \mathbf{z}_{k}} \frac{\partial \mathbf{z}_{k+1}}{\partial \mathbf{h}_{k}} \frac{\partial \mathcal{L}_{t}}{\partial \mathbf{z}_{k+1}} \\ &=\operatorname{diag}\left(f^{\prime}\left(\mathbf{z}_{k}\right)\right) U^{\mathrm{T}} \delta_{t, k+1} \end{aligned}

從而:

\frac{\partial \mathcal{L}_{t}}{\partial u_{i j}}=\sum_{k=1}^{t}\left[\delta_{t, k}\right]_{i}\left[\mathbf{h}_{k-1}\right]_{j}

寫成矩陣形式為:

\frac{\partial \mathcal{L}_{t}}{\partial U}=\sum_{k=1}^{t} \delta_{t, k} \mathbf{h}_{k-1}^{\mathrm{T}}

由此得到整個序列的損失函數(shù)\mathcal{L}關(guān)于參數(shù)U的梯度:

\frac{\partial \mathcal{L}}{\partial U}=\sum_{t=1}^{T} \sum_{k=1}^{t} \delta_{t, k} \mathbf{h}_{k-1}^{\mathrm{T}}

同理可得,\mathcal{L}關(guān)于權(quán)重W和偏置b的梯度為:

\begin{aligned} \frac{\partial \mathcal{L}}{\partial W} &=\sum_{t=1}^{T} \sum_{k=1}^{t} \delta_{t, k} \mathbf{x}_{k}^{\mathrm{T}} \\ \frac{\partial \mathcal{L}}{\partial \mathbf} &=\sum_{t=1}^{T} \sum_{k=1}^{t} \delta_{t, k} \\ \end{aligned}

在BPTT算法中,參數(shù)的梯度需要在一個完整的“前向”計算和“反向”計算后才能得到并進行參數(shù)更新。如下圖所示。

4.2、實時循環(huán)學(xué)習算法

與反向傳播的BPTT算法不同的是,實時循環(huán)學(xué)習(Real-Time Recurrent Learning)是通過前向傳播的方式來計算梯度。

假設(shè)循環(huán)神經(jīng)網(wǎng)絡(luò)中第t + 1時刻的狀態(tài)h_{t+1}為:

\mathbf{h}_{t+1}=f\left(\mathbf{z}_{t+1}\right)=f\left(U \mathbf{h}_{t}+W \mathbf{x}_{t+1}+\mathbf\right)

其關(guān)于參數(shù)u_{ij}的偏導(dǎo)數(shù)為:

\frac{\partial \mathbf{h}_{t+1}}{\partial u_{i j}}=\left(\frac{\partial^{+} \mathbf{z}_{t+1}}{\partial u_{i j}}+\frac{\partial \mathbf{h}_{t}}{\partial u_{i j}} U^{\mathrm{T}}\right) \frac{\partial \mathbf{h}_{t+1}}{\partial \mathbf{z}_{t+1}}

RTRL算法從第1 個時刻開始,除了計算循環(huán)神經(jīng)網(wǎng)絡(luò)的隱狀態(tài)之外,還依次前向計算偏導(dǎo)數(shù)\frac{\partial \mathbf{h}_{1}}{\partial u_{i j}}, \frac{\partial \mathbf{h}_{2}}{\partial u_{i j}}, \frac{\partial \mathbf{h}_{3}}{\partial u_{i j}}, \cdots。

兩種學(xué)習算法比較:

RTRL算法和BPTT算法都是基于梯度下降的算法,分別通過前向模式和反向模式應(yīng)用鏈式法則來計算梯度。在循環(huán)神經(jīng)網(wǎng)絡(luò)中,一般網(wǎng)絡(luò)輸出維度遠低于輸入維度,因此BPTT算法的計算量會更小,但BPTT算法需要保存所有時刻的中間梯度,空間復(fù)雜度較高。RTRL算法不需要梯度回傳,因此非常適合于需要在線學(xué)習或無限序列的任務(wù)中。

5、長程依賴問題

循環(huán)神經(jīng)網(wǎng)絡(luò)在學(xué)習過程中的主要問題是由于梯度消失或爆炸問題,很難建模長時間間隔(Long Range)的狀態(tài)之間的依賴關(guān)系。

在BPTT算法中,我們有:

\delta_{t, k}=\prod_{i=k}^{t-1}\left(\operatorname{diag}\left(f^{\prime}\left(\mathbf{z}_{i}\right)\right) U^{\mathrm{T}}\right) \delta_{t, t}

如果定義\gamma \cong\left\|\operatorname{diag}\left(f^{\prime}\left(\mathbf{z}_{i}\right)\right) U^{\mathrm{T}}\right\|,則:

\delta_{t, k} \cong \gamma^{t-k} \delta_{t, t}

γ > 1,當t ? k → ∞時,γ^{t?k} → ∞,會造成系統(tǒng)不穩(wěn)定,稱為梯度爆炸問題;相反,若γ < 1,當t?k → ∞時,γ^{t?k} → 0,會出現(xiàn)和深度前饋神經(jīng)網(wǎng)絡(luò)類似的梯度消失問題。

雖然簡單循環(huán)網(wǎng)絡(luò)理論上可以建立長時間間隔的狀態(tài)之間的依賴關(guān)系,但是由于梯度爆炸或消失問題,實際上只能學(xué)習到短期的依賴關(guān)系。這樣,如果t時刻的輸出y_t依賴于t ? k時刻的輸入x_{t?k},當間隔k比較大時,簡單神經(jīng)網(wǎng)絡(luò)很難建模這種長距離的依賴關(guān)系,稱為長程依賴問題(Long-Term dependencies Problem)

5.1、梯度爆炸解決方法

一般而言,循環(huán)網(wǎng)絡(luò)的梯度爆炸問題比較容易解決,一般通過權(quán)重衰減或梯度截斷來避免。權(quán)重衰減是通過給參數(shù)增加?1?2范數(shù)的正則化項來限制參數(shù)的取值范圍,從而使得γ ≤ 1。梯度截斷是另一種有效的啟發(fā)式方法,當梯度的模大于一定閾值時,就將它截斷成為一個較小的數(shù)。

5.2、梯度消失解決方法

梯度消失是循環(huán)網(wǎng)絡(luò)的主要問題。除了使用一些優(yōu)化技巧外,更有效的方式就是改變模型,比如讓U = I,同時使用f′(z_i) = 1,即:

\mathbf{h}_{t}=\mathbf{h}_{t-1}+g\left(\mathbf{x}_{t} ; \theta\right)

其中g(·)是一個非線性函數(shù),θ為參數(shù)。

上式中,h_th_{t?1}之間為線性依賴關(guān)系,且權(quán)重系數(shù)為1,這樣就不存在梯度爆炸或消失問題。但是,這種改變也丟失了神經(jīng)元在反饋邊上的非線性激活的性質(zhì),因此也降低了模型的表示能力。

為了避免這個缺點,我們可以采用一種更加有效的改進策略:

\mathbf{h}_{t}=\mathbf{h}_{t-1}+g\left(\mathbf{x}_{t}, \mathbf{h}_{t-1} ; \theta\right)

這樣h_th_{t?1}之間為既有線性關(guān)系,也有非線性關(guān)系,并且可以緩解梯度消失問題。但這種改進依然存在兩個問題:

  • 梯度爆炸問題:令\mathbf{z}_{k}=U \mathbf{h}_{k-1}+W \mathbf{x}_{k}+\mathbf為在第k時刻函數(shù)g(·)的輸入,在計算誤差項\delta_{t, k}=\frac{\partial \mathcal{L}_{t}}{\partial \mathbf{z}_{k}},梯度可能會過大,從而導(dǎo)致梯度爆炸問題;

  • 記憶容量(Memory Capacity)問題:隨著h_t不斷累積存儲新的輸入信息,會發(fā)生飽和現(xiàn)象。假設(shè)g(·)為Logistic 函數(shù),則隨著時間t的增長,h_t會變得越來越大,從而導(dǎo)致h變得飽和。也就是說,隱狀態(tài)h_t可以存儲的信息是有限的,隨著記憶單元存儲的內(nèi)容越來越多,其丟失的信息也越來越多。

為了解決這兩個問題,可以通過引入門控機制來進一步改進模型。

6、基于門控的循環(huán)神經(jīng)網(wǎng)絡(luò)

為了改善循環(huán)神經(jīng)網(wǎng)絡(luò)的長程依賴問題,一種非常好的解決方案是引入門控機制來控制信息的累積速度,包括有選擇地加入新的信息,并有選擇地遺忘之前累積的信息。這一類網(wǎng)絡(luò)可以稱為基于門控的循環(huán)神經(jīng)網(wǎng)絡(luò)(Gated RNN)。本節(jié)中,主要介紹兩種基于門控的循環(huán)神經(jīng)網(wǎng)絡(luò):長短期記憶網(wǎng)絡(luò)和門控循環(huán)單元網(wǎng)絡(luò)。

6.1、長短期記憶網(wǎng)絡(luò)

長短期記憶(Long Short-Term Memory,LSTM)網(wǎng)絡(luò)是循環(huán)神經(jīng)網(wǎng)絡(luò)的一個變體,可以有效地解決簡單循環(huán)神經(jīng)網(wǎng)絡(luò)的梯度爆炸或消失問題。

\mathbf{h}_{t}=\mathbf{h}_{t-1}+g\left(\mathbf{x}_{t}, \mathbf{h}_{t-1} ; \theta\right)基礎(chǔ)上,LSTM網(wǎng)絡(luò)主要改進在以下兩個方面:

  • 新的內(nèi)部狀態(tài):LSTM網(wǎng)絡(luò)引入一個新的內(nèi)部狀態(tài)(internal state)c_t專門進行線性的循環(huán)信息傳遞,同時(非線性)輸出信息給隱藏層的外部狀態(tài)h_t。

\begin{aligned} \mathbf{c}_{t} &=\mathbf{f}_{t} \odot \mathbf{c}_{t-1}+\mathbf{i}_{t} \odot \tilde{\mathbf{c}}_{t} \\ \mathbf{h}_{t} &=\mathbf{o}_{t} \odot \tanh \left(\mathbf{c}_{t}\right) \end{aligned}

其中f_t,i_to_t三個門(gate)來控制信息傳遞的路徑;⊙為向量元素乘積;c_{t?1}為上一時刻的記憶單元;\tilde{\mathbf{c}}_{t}是通過非線性函數(shù)得到的候選狀態(tài):

\tilde{\mathbf{c}}_{t}=\tanh \left(W_{c} \mathbf{x}_{t}+U_{c} \mathbf{h}_{t-1}+\mathbf_{c}\right)

在每個時刻t,LSTM網(wǎng)絡(luò)的內(nèi)部狀態(tài)c_t記錄了到當前時刻為止的歷史信息。

  • 門控機制:LSTM網(wǎng)絡(luò)引入門控機制(Gating Mechanism)來控制信息傳遞的路徑。上面的三個門分別為輸入門i_t, 遺忘門f_t和輸出門o_t

在數(shù)字電路中,門(Gate)為一個二值變量{0, 1},0代表關(guān)閉狀態(tài),不許任何信息通過;1代表開放狀態(tài),允許所有信息通過。LSTM網(wǎng)絡(luò)中的“門”是一種“軟”門,取值在(0, 1) 之間,表示以一定的比例運行信息通過。LSTM網(wǎng)絡(luò)中三個門的作用為:

(1)遺忘門f_t控制上一個時刻的內(nèi)部狀態(tài)c_{t?1}需要遺忘多少信息。
(2)輸入門i_t控制當前時刻的候選狀態(tài)\tilde{c}_t有多少信息需要保存。
(3)輸出門o_t控制當前時刻的內(nèi)部狀態(tài)c_t有多少信息需要輸出給外部狀態(tài)h_t。

三個門的計算方式為:

\begin{aligned} \mathbf{i}_{t} &=\sigma\left(W_{i} \mathbf{x}_{t}+U_{i} \mathbf{h}_{t-1}+\mathbf_{i}\right) \\ \mathbf{f}_{t} &=\sigma\left(W_{f} \mathbf{x}_{t}+U_{f} \mathbf{h}_{t-1}+\mathbf_{f}\right) \\ \mathbf{o}_{t} &=\sigma\left(W_{o} \mathbf{x}_{t}+U_{o} \mathbf{h}_{t-1}+\mathbf_{o}\right) \end{aligned}

其中σ(·)為Logistic函數(shù),其輸出區(qū)間為(0, 1)x_t為當前時刻的輸入,h_{t?1}為上一時刻的外部狀態(tài)。

下圖給出了LSTM網(wǎng)絡(luò)的循環(huán)單元結(jié)構(gòu),其計算過程為:(1)首先利用上一時刻的外部狀態(tài)h_{t?1}和當前時刻的輸入x_t,計算出三個門,以及候選狀態(tài)\tilde{c}_t;(2)結(jié)合遺忘門f_t和輸入門i_t來更新記憶單元c_t;(3)結(jié)合輸出門o_t,將內(nèi)部狀態(tài)的信息傳遞給外部狀態(tài)h_t。

通過LSTM循環(huán)單元,整個網(wǎng)絡(luò)可以建立較長距離的時序依賴關(guān)系。以上計算過程可以簡潔表達如下:

\left[\begin{array}{c}{\tilde{\mathbf{c}}_{t}} \\ {\mathbf{o}_{t}} \\ {\mathbf{i}_{t}} \\ {\mathbf{f}_{t}}\end{array}\right]=\left[\begin{array}{c}{\tanh } \\ {\sigma} \\ {\sigma} \\ {\sigma}\end{array}\right]\left(\mathbf{[}W,U\mathbf{]}\left[\begin{array}{c}{\mathbf{x}_{t}} \\ {\mathbf{h}_{t-1}}\end{array}\right]+\mathbf\right)

\begin{aligned} \mathbf{c}_{t} &=\mathbf{f}_{t} \odot \mathbf{c}_{t-1}+\mathbf{i}_{t} \odot \tilde{\mathbf{c}}_{t} \\ \mathbf{h}_{t} &=\mathbf{o}_{t} \odot \tanh \left(\mathbf{c}_{t}\right) \end{aligned}

記憶循環(huán)神經(jīng)網(wǎng)絡(luò)中的隱狀態(tài)h存儲了歷史信息,可以看作是一種記憶(Memory)。在簡單循環(huán)網(wǎng)絡(luò)中,隱狀態(tài)每個時刻都會被重寫,因此可以看作是一種短期記憶(Short-Term Memory)。在神經(jīng)網(wǎng)絡(luò)中,長期記憶(Long-Term Memory)可以看作是網(wǎng)絡(luò)參數(shù),隱含了從訓(xùn)練數(shù)據(jù)中學(xué)到的經(jīng)驗,其更新周期要遠遠慢于短期記憶。而在LSTM網(wǎng)絡(luò)中,記憶單元c可以在某個時刻捕捉到某個關(guān)鍵信息,并有能力將此關(guān)鍵信息保存一定的時間間隔。記憶單元c中保存信息的生命周期要長于短期記憶h,但又遠遠短于長期記憶,因此稱為長的短期記憶(Long Short-Term Memory)。

注意,一般在深度網(wǎng)絡(luò)參數(shù)學(xué)習時,參數(shù)初始化的值一般都比較小。但是在訓(xùn)練LSTM網(wǎng)絡(luò)時,過小值會使得遺忘門的值比較小。這意味著前一時刻的信息大部分都丟失了,這樣網(wǎng)絡(luò)很難捕捉到長距離的依賴信息。并且相鄰時間間隔的梯度會非常小,這會導(dǎo)致梯度彌散問題。因此遺忘的參數(shù)初始值一般都設(shè)得比較大,其偏置向量b_f設(shè)為1或2。

6.2、門控循環(huán)單元網(wǎng)絡(luò)

門控循環(huán)單元(Gated Recurrent Unit,GRU)網(wǎng)絡(luò)是一種比LSTM網(wǎng)絡(luò)更加簡單的循環(huán)神經(jīng)網(wǎng)絡(luò)。GRU不引入額外的記憶單元,而是在\mathbf{h}_{t}=\mathbf{h}_{t-1}+g\left(\mathbf{x}_{t}, \mathbf{h}_{t-1} ; \theta\right)的基礎(chǔ)上引入一個更新門(Update Gate)來控制當前狀態(tài)需要從歷史狀態(tài)中保留多少信息(不經(jīng)過非線性變換),以及需要從候選狀態(tài)中接受多少新信息。

\mathbf{h}_{t}=\mathbf{z}_{t} \odot \mathbf{h}_{t-1}+\left(1-\mathbf{z}_{t}\right) \odot g\left(\mathbf{x}_{t}, \mathbf{h}_{t-1} ; \theta\right)

其中\mathbf{z}_{t} \in[0,1]為更新門。

\mathbf{z}_{t}=\sigma\left(\mathbf{W}_{z} \mathbf{x}_{t}+\mathbf{U}_{z} \mathbf{h}_{t-1}+\mathbf_{z}\right)

在LSTM網(wǎng)絡(luò)中,輸入門和遺忘門是互補關(guān)系,具有一定的冗余性。GRU網(wǎng)絡(luò)直接使用一個門來控制輸入和遺忘之間的平衡。當z_t = 0時,當前狀態(tài)h_t和前一時刻的狀態(tài)h_{t?1}之間為非線性函數(shù)關(guān)系;當z_t = 1時,h_th_{t?1}之間為線性函數(shù)關(guān)系。

在GRU網(wǎng)絡(luò)中,函數(shù)g\left(\mathbf{x}_{t}, \mathbf{h}_{t-1} ; \theta\right)的定義為:

\tilde{\mathbf{h}}_{t}=\tanh \left(W_{h} \mathbf{x}_{t}+U_{h}\left(\mathbf{r}_{t} \odot \mathbf{h}_{t-1}\right)+\mathbf_{h}\right)

其中\tilde{\mathbf{h}}_{t}表示當前時刻的候選狀態(tài),\mathbf{r}_{t} \in[0,1]為重置門(Reset Gate),用來控制
候選狀態(tài)\tilde{\mathbf{h}}_{t}的計算是否依賴上一時刻的狀態(tài)h_{t?1}。

\mathbf{r}_{t}=\sigma\left(W_{r} \mathbf{x}_{t}+U_{r} \mathbf{h}_{t-1}+\mathbf_{r}\right)

r_t = 0時,候選狀態(tài)\tilde{\mathbf{h}}_{t}=\tanh \left(W_{c} \mathbf{x}_{t}+\mathbf\right)只和當前輸入x_t相關(guān),和歷史狀態(tài)無關(guān)。當\mathbf{r}_{t}=1時,候選狀態(tài)\tilde{\mathbf{h}}_{t}=\tanh \left(W_{h} \mathbf{x}_{t}+U_{h} \mathbf{h}_{t-1}+\mathbf_{h}\right)和當前輸入x_t和歷史狀態(tài)h_{t?1}相關(guān),和簡單循環(huán)網(wǎng)絡(luò)一致。

綜上,GRU網(wǎng)絡(luò)的狀態(tài)更新方式為:

\mathbf{h}_{t}=\mathbf{z}_{t} \odot \mathbf{h}_{t-1}+\left(1-\mathbf{z}_{t}\right) \odot \tilde{\mathbf{h}}_{t}

7、深層循環(huán)神經(jīng)網(wǎng)絡(luò)

如果將深度定義為網(wǎng)絡(luò)中信息傳遞路徑長度的話,循環(huán)神經(jīng)網(wǎng)絡(luò)可以看作是既深又淺的網(wǎng)絡(luò)。一方面來說,如果我們把循環(huán)網(wǎng)絡(luò)按時間展開,長時間間隔的狀態(tài)之間的路徑很長,循環(huán)網(wǎng)絡(luò)可以看作是一個非常深的網(wǎng)絡(luò)了。從另一方面來說,如果同一時刻網(wǎng)絡(luò)輸入到輸出之間的路徑x_t → y_t,這個網(wǎng)絡(luò)是非常淺的

因此,我們可以增加循環(huán)神經(jīng)網(wǎng)絡(luò)的深度從而增強循環(huán)神經(jīng)網(wǎng)絡(luò)的能力。增加循環(huán)神經(jīng)網(wǎng)絡(luò)的深度主要是增加同一時刻網(wǎng)絡(luò)輸入到輸出之間的路徑x_t → y_t。比如增加隱狀態(tài)到輸出h_t → y_t,以及輸入到隱狀態(tài)x_t → h_t之間的路徑的深度。

7.1、堆疊循環(huán)神經(jīng)網(wǎng)絡(luò)

常見的做法是將多個循環(huán)網(wǎng)絡(luò)堆疊起來,稱為堆疊循環(huán)神經(jīng)網(wǎng)絡(luò)(Stacked Recurrent Neural Network,SRNN)。一個堆疊的簡單循環(huán)網(wǎng)絡(luò)(stacked SRN)也稱為循環(huán)網(wǎng)絡(luò)循環(huán)多層感知器(Recurrent Multi-Layer Perceptron,RMLP)。

下圖給出了按時間展開的堆疊循環(huán)神經(jīng)網(wǎng)絡(luò)。第l層網(wǎng)絡(luò)的輸入是第l ? 1層網(wǎng)絡(luò)的輸出。我們定義\mathbf{h}_{t}^{(l)}為在時刻t時第l層的隱狀態(tài):

\mathbf{h}_{t}^{(l)}=f\left(U^{(l)} \mathbf{h}_{t-1}^{(l)}+W^{(l)} \mathbf{h}_{t}^{(l-1)}+\mathbf^{(l)}\right)

其中U^{(l)}, W^{(l)}b^{(l)}為權(quán)重矩陣和偏置向量,\mathbf{h}_{t}^{(0)}=\mathbf{x}_{t}。

7.2、雙向循環(huán)神經(jīng)網(wǎng)絡(luò)

雙向循環(huán)神經(jīng)網(wǎng)絡(luò)(Bidirectional Recurrent Neural Network,Bi-RNN)由兩層循環(huán)神經(jīng)網(wǎng)絡(luò)組成,它們的輸入相同,只是信息傳遞的方向不同。

假設(shè)第1層按時間順序,第2層按時間逆序,在時刻t時的隱狀態(tài)定義為\mathbf{h}_{t}^{(1)}\mathbf{h}_{t}^{(2)},則:

\mathbf{h}_{t}^{(1)}=f\left(U^{(1)} \mathbf{h}_{t-1}^{(1)}+W^{(1)} \mathbf{x}_{t}+\mathbf^{(1)}\right)

\mathbf{h}_{t}^{(2)}=f\left(U^{(2)} \mathbf{h}_{t+1}^{(2)}+W^{(2)} \mathbf{x}_{t}+\mathbf^{(2)}\right)

\mathbf{h}_{t}=\mathbf{h}_{t}^{(1)} \oplus \mathbf{h}_{t}^{(2)}

其中⊕為向量拼接操作。

下圖給出了按時間展開的雙向循環(huán)神經(jīng)網(wǎng)絡(luò)。

8、拓展到圖網(wǎng)絡(luò)

如果將循環(huán)神經(jīng)網(wǎng)絡(luò)按時間展開,每個時刻的隱狀態(tài)h_t看做一個節(jié)點,那么這些節(jié)點構(gòu)成一個鏈式結(jié)構(gòu),每個節(jié)點t都收到其父節(jié)點的消息(Message),更新自己的狀態(tài),并傳遞給其子節(jié)點。而鏈式結(jié)構(gòu)是一種特殊的圖結(jié)構(gòu),我們可以比較容易地將這種消息傳遞(Message Passing)的思想擴展到任意的圖結(jié)構(gòu)上。

8.1、遞歸神經(jīng)網(wǎng)絡(luò)

遞歸神經(jīng)網(wǎng)絡(luò)(Recursive Neural Network,RecNN)是循環(huán)神經(jīng)網(wǎng)絡(luò)在有向無循環(huán)圖上的擴展。遞歸神經(jīng)網(wǎng)絡(luò)的一般結(jié)構(gòu)為樹狀的層次結(jié)構(gòu),如圖所示。

遞歸神經(jīng)網(wǎng)絡(luò)主要用來建模自然語言句子的語義。給定一個句子的語法結(jié)構(gòu)(一般為樹狀結(jié)構(gòu)),可以使用遞歸神經(jīng)網(wǎng)絡(luò)來按照句法的組合關(guān)系來合成一個句子的語義。

8.2、圖網(wǎng)絡(luò)

在實際應(yīng)用中,很多數(shù)據(jù)是圖結(jié)構(gòu)的,比如知識圖譜、社交網(wǎng)絡(luò)、分子網(wǎng)絡(luò)等。而前饋網(wǎng)絡(luò)和反饋網(wǎng)絡(luò)很難處理圖結(jié)構(gòu)的數(shù)據(jù)。

對于一個任意的圖結(jié)構(gòu)G(V, E),其中V表示節(jié)點集合,E表示邊集合。每條邊表示兩個節(jié)點之間的依賴關(guān)系。節(jié)點之間的連接可以是有向的,也可以是無向的。圖中每個節(jié)點v都用一組神經(jīng)元來表示其狀態(tài)h^{(v)},初始狀態(tài)可為節(jié)點v的輸入特征x^{(v)}。每個節(jié)點可收到來自相鄰節(jié)點的消息,并更新自己的狀態(tài)。

\begin{aligned} \mathbf{m}_{t}^{(v)} &=\sum_{u \in N(v)} f\left(\mathbf{h}_{t-1}^{(v)}, \mathbf{h}_{t-1}^{(u)}, \mathbf{e}^{(u, v)}\right) \\ \mathbf{h}_{t}^{(v)} &=g\left(\mathbf{h}_{t-1}^{(v)}, \mathbf{m}_{t}^{(v)}\right) \end{aligned}

其中N(v)表示節(jié)點v的鄰居,m^{(v)}_t表示在第t時刻節(jié)點v收到的信息,e^{(u,v)}為邊e^{(u,v)}上的特征。

在整個圖更新T次后,可以通過一個讀出函數(shù)(Readout Function)g(·)來得到整個網(wǎng)絡(luò)的表示。

\mathbf{y}_{t}=g\left(\left\{\mathbf{h}_{T}^{(v)} | v \in \mathcal{V}\right\}\right)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容