循环神经网络(RNN)相关知识
文章目錄
- RNN概述
- 前向傳播公式
- 通過時間反向傳播(BPTT)
- RNN確定序列長度方式
- 其他RNN結構
- 基于RNN的應用
- 1,序列數據的分析
- 2,序列數據的轉換
- 3,序列數據的生成
- RNN的不足
- 1,從隱藏變量h角度來看
- 2,從梯度傳播角度來看
RNN概述
循環神經網絡(RNN)是用于處理序列數據的神經網絡,該序列在時刻 t(從1 到 τ)包含向量 x(t)x^{(t) }x(t)。典型的網絡結構如下圖所示:
RNN每個時間步都需要將 x 值的輸入序列映射到輸出值 o 的對應序列。其中 o 是未歸一化的對數概率,并且在損失函數 L 內部計算 y^=softmax(x)\hat y = softmax(x)y^?=softmax(x)。損失函數 L 用于衡量每個 o 與相應的訓練目標 y 的距離。
RNN輸入到隱含單元的連接由權重矩陣 U 參數化,隱含單元與隱含單元連接由權重矩陣 W 參數化,隱含單元到輸出節點的連接由權重矩陣 V 參數化。從上面的圖中也可以看出,與CNN類似,在RNN中同樣有參數共享的思想(共享了參數W,U,VW,U,VW,U,V等)。這使得模型的泛化能力更強,因為模型不會依賴于特定位置上的輸入xxx。例如考慮這兩句話:“I went to Nepal in 2009’’ 和 “In 2009, I went to Nepal.” ,他們表達的意思完全相同,但是時間2009出現在不同的地方,RNN的參數共享機制可以更有效的提取到這個時間信息。參數共享也允許模型泛化到沒有見過的序列長度,并且訓練模型所需的訓練樣本遠遠少于不帶參數共享的模型。
當訓練循環網絡根據過去的信息去預測未來的信息時,網絡通常要使用隱含狀態 h (t) 來表示時刻 t 之前的序列信息:
h(t)=g(t)(x(t),x(t?1),x(t?2),…,x(2),x(1))=f(h(t?1),x(t);θ).\begin{aligned} h^{(t)} &=g^{(t)}(x^{(t)},x^{(t-1)},x^{(t-2)},\dots,x^{(2)}, x^{(1)}) \\ & = f(h^{(t-1)}, x^{(t)} ; \theta) . \end{aligned} h(t)?=g(t)(x(t),x(t?1),x(t?2),…,x(2),x(1))=f(h(t?1),x(t);θ).?
函數g(t)g^{(t)}g(t)將過去的序列(x(t),x(t?1),x(t?2),…,x(2),x(1))(x^{(t)},x^{(t-1)}, x^{(t-2)},\dots,x^{(2)}, x^{(1)})(x(t),x(t?1),x(t?2),…,x(2),x(1))作為輸入來生成當前的隱含狀態h(t)h(t)h(t)。實際上,我們可以遞歸調用函數fff來完成隱含狀態的計算。這么做主要有兩個優點:
在不同的NLP場景中,h(t) 需要保存的信息也不同。例如在詞性標注任務中,h(t) 更多的是要保存前一個單詞的信息;而在機器翻譯任務中,則需要保存輸入序列的所有信息。
前向傳播公式
上面的圖中沒有指明激活函數,假設使用tanhtanhtanh作為激活函數,并且假設輸出值是離散的,例如用于預測類別。一種表示離散變量的方式是:把輸出 o 作為離散變量每種可能值的非標準化對數概率。然后,我們可以應用 softmax 函數獲得標準化后概率的輸出向量y^\hat yy^?。
RNN從特定的初始狀態 h (0) 開始前向傳播。從 t = 1 到 t = τ 的每個時間步,我們應用以下更新方程:
a(t)=b+Wh(t?1)+Ux(t)h(t)=tanh?(a(t))o(t)=c+Vh(t)\begin{aligned} &\mathbf a^{(t)} = \mathbf b + \mathbf W \mathbf h^{(t-1)} + \mathbf U \mathbf x^{(t)} \\ &\mathbf h^{(t)} = \tanh(\mathbf a^{(t)}) \\ &\mathbf o^{(t)} = \mathbf c + \mathbf V \mathbf h^{(t)} \\ \end{aligned} ?a(t)=b+Wh(t?1)+Ux(t)h(t)=tanh(a(t))o(t)=c+Vh(t)?
y^(t)=softmax(o(t))=eo(t)∑t=1τeo(t)\hat {\mathbf y} ^{(t)} = softmax(\mathbf o^{(t)}) = \frac{e^{o^{(t)}}}{\sum_{t=1}^\tau e^{o^{(t)}}} \\ y^?(t)=softmax(o(t))=∑t=1τ?eo(t)eo(t)?
其中的參數的偏置向量 b 和 c 連同權重矩陣 U、V 和 W,分別對應于輸入到隱藏單元、
隱藏單元到輸出和隱藏單元到隱藏單元的連接。這個循環網絡將一個輸入序列映射到相同長度的輸出序列。與 x 序列配對的 y 的總損失就是所有時間步的損失之和,例如定義損失L為所有時間步的負對數似然函數:
L({x(1),…,x(τ)},{y(1),…,y(τ)})=∑tL(t)=?∑tlog?Pmodel(y(t)∣{x(1),…,x(τ)})\begin{aligned} &L(\{x^{(1)},\ldots,x^{(\tau)}\},\{y^{(1)},\ldots,y^{(\tau)}\}) \\ &= \sum_{t} L^{(t)} \\ &= -\sum_{t} \log P_{model}(y^{(t)}|\{x^{(1)},\ldots,x^{(\tau)}\}) \end{aligned} ?L({x(1),…,x(τ)},{y(1),…,y(τ)})=t∑?L(t)=?t∑?logPmodel?(y(t)∣{x(1),…,x(τ)})?
了解正向傳播的計算內容之后,就可以討論通過時間反向傳播算法來更新網絡參數了。
通過時間反向傳播(BPTT)
回顧之前的計算圖:
對于每一個節點 N,我們需要先 N 后面的節點的梯度,然后遞歸地計算梯度 ?NL? _N L?N?L。我們從最后一個節點開始遞歸:
?L?L(t)=1\frac{\partial L}{\partial L^{(t)}} = 1 ?L(t)?L?=1
觀察正向傳播的計算公式,不難發現 L(t)L^{(t)}L(t)是關于y^(t)\hat {\mathbf y} ^{(t)}y^?(t)的函數,y^(t)\hat {\mathbf y} ^{(t)}y^?(t)是softmaxsoftmaxsoftmax的結果, 而softmaxsoftmaxsoftmax是關于 o(t)o^{(t)}o(t)的函數。求LLL對非標準化對數概率 o(t)o^{(t)}o(t)求偏導(相關求導過程可以參考Softmax求導),得到:
(?o(t)L)i=?L?oi(t)=?L?L(t)?L(t)?y^i(t)?y^i(t)?oi(t)={y^i(t)?1,yi(t)=labely^i(t)?0,yi(t)≠label\begin{aligned} (\nabla_{\mathbf o^{(t)}} L)_i &= \frac{\partial L}{\partial o_{i}^{(t)}}\\ &= \frac{\partial L}{\partial L^{(t)}} \frac{\partial L^{(t)}}{\partial \hat {\mathbf y} ^{(t)}_i} \frac{\partial \hat {\mathbf y} ^{(t)}_i}{\partial o_{i}^{(t)}} \\ &= \begin{cases} \hat {y}_i ^{(t)} - 1 , \qquad {y}_i ^{(t)} =label\\ \hat {y}_i ^{(t)} - 0, \qquad {y}_i ^{(t)} \ne label \end{cases} \end{aligned} (?o(t)?L)i??=?oi(t)??L?=?L(t)?L??y^?i(t)??L(t)??oi(t)??y^?i(t)??={y^?i(t)??1,yi(t)?=labely^?i(t)??0,yi(t)??=label??
從序列的末尾開始,反向進行計算。在最后的時間步 τ,只有 o (τ) 依賴于h (τ) ,不存在h (τ+1)依賴于h (τ) ,因此這個梯度很簡單。由o(t)=c+Vh(t)\mathbf o^{(t)} = \mathbf c + \mathbf V \mathbf h^{(t)}o(t)=c+Vh(t),可以知道:
?h(τ)L=?o(τ)?h(τ)?o(τ)L=VT?o(τ)L\nabla_{\mathbf h^{(\tau)}}L = \frac{\partial o^{(\tau)}}{\partial h^{(\tau)}}\nabla_{\mathbf o^{(\tau)}} L = \mathbf V^T \nabla_{\mathbf o^{(\tau)}} L ?h(τ)?L=?h(τ)?o(τ)??o(τ)?L=VT?o(τ)?L
然后我們可以從時刻 t = τ ? 1 到 t = 1 反向迭代,通過時間反向傳播梯度。由下面的式子:
a(t)=b+Wh(t?1)+Ux(t)h(t)=tanh?(a(t))o(t)=c+Vh(t)\mathbf a^{(t)} = \mathbf b + \mathbf W \mathbf h^{(t-1)} + \mathbf U \mathbf x^{(t)} \\ \mathbf h^{(t)} = \tanh(\mathbf a^{(t)}) \\ \mathbf o^{(t)} = \mathbf c + \mathbf V \mathbf h^{(t)} a(t)=b+Wh(t?1)+Ux(t)h(t)=tanh(a(t))o(t)=c+Vh(t)
不難發現當t < τ時, o (t) 和 h (t+1) 都依賴于h (t) 。因此,它的梯度由兩個部分組成:
?h(t)L=(?h(t+1)?h(t))?(?h(t+1)L)+(?o(t)?h(t))?(?o(t)L)=W?(?h(t+1)L)diag?(1?(h(t+1))2)+V?(?o(t)L)\begin{array}{l} \nabla_{h^{(t)}} L=\left(\frac{\partial \boldsymbol{h}^{(t+1)}}{\partial \boldsymbol{h}^{(t)}}\right)^{\top}\left(\nabla_{\boldsymbol{h}^{(t+1)}} L\right)+\left(\frac{\partial \boldsymbol{o}^{(t)}}{\partial \boldsymbol{h}^{(t)}}\right)^{\top}\left(\nabla_{\boldsymbol{o}^{(t)}} L\right) \\ =\boldsymbol{W}^{\top}\left(\nabla_{\boldsymbol{h}^{(t+1)}} L\right) \operatorname{diag}\left(1-\left(\boldsymbol{h}^{(t+1)}\right)^{2}\right)+\boldsymbol{V}^{\top}\left(\nabla_{\boldsymbol{o}^{(t)}} L\right) \end{array} ?h(t)?L=(?h(t)?h(t+1)?)?(?h(t+1)?L)+(?h(t)?o(t)?)?(?o(t)?L)=W?(?h(t+1)?L)diag(1?(h(t+1))2)+V?(?o(t)?L)?
其中:
tanh?′(x)=1?(tanh(x))2\tanh'(x) = 1- (tanh(x))^2 tanh′(x)=1?(tanh(x))2
?h(t+1)?h(t)=?tanh?(b+Wh(t)+Ux(t+1))?h(t)=WTdiag(1?(h(t+1))2)\begin{aligned} \frac{\partial \boldsymbol{h}^{(t+1)}}{\partial\boldsymbol{h}^{(t)}} &= \frac{\partial \tanh(\mathbf b + \mathbf W \boldsymbol h^{(t)} + \mathbf U \mathbf x^{(t+1)} )}{\partial\boldsymbol{h}^{(t)}} \\ &= \mathbf W^T diag(1-(\boldsymbol h^{(t+1)})^2) \end{aligned} ?h(t)?h(t+1)??=?h(t)?tanh(b+Wh(t)+Ux(t+1))?=WTdiag(1?(h(t+1))2)?
基于前面的步驟,接下來進行參數的跟新:
?cL=∑t(?o(t)?c)??o(t)L=∑t?o(t)L?bL=∑t(?h(t)?b(t))??h(t)L=∑tdiag?(1?(h(t))2)?h(t)L?VL=∑t∑i(?L?oi(t))?Voi(t)=∑t(?o(t)L)h(t)??W=∑t∑i(?L?hi(t))?W(t)hi(t)=∑tdiag?(1?(h(t))2)(?h(t)L)h(t?1)??UL=∑t∑i(?L?hi(t))?U(t)hi(t)=∑tdiag?(1?(h(t))2)(?h(t)L)x(t)?\begin{aligned} \nabla_{c} L &=\sum_{t}\left(\frac{\partial \boldsymbol{o}^{(t)}}{\partial \boldsymbol{c}}\right)^{\top} \nabla_{\boldsymbol{o}^{(t)}} L=\sum_{t} \nabla_{\boldsymbol{o}^{(t)}} L \\ \nabla_{\boldsymbol{b}} L &=\sum_{t}\left(\frac{\partial \boldsymbol{h}^{(t)}}{\partial \boldsymbol{b}^{(t)}}\right)^{\top} \nabla_{\boldsymbol{h}^{(t)}} L=\sum_{t} \operatorname{diag}\left(1-\left(\boldsymbol{h}^{(t)}\right)^{2}\right) \nabla_{\boldsymbol{h}^{(t)}} L \\ \nabla_{\boldsymbol{V}} L &=\sum_{t} \sum_{i}\left(\frac{\partial L}{\partial o_{i}^{(t)}}\right) \nabla_{\boldsymbol{V}} o_{i}^{(t)}=\sum_{t}\left(\nabla_{o^{(t)}} L\right) \boldsymbol{h}^{(t)^{\top}} \\ \nabla_{\boldsymbol{W}} &=\sum_{t} \sum_{i}\left(\frac{\partial L}{\partial h_{i}^{(t)}}\right) \nabla_{\boldsymbol{W}^{(t)}} h_{i}^{(t)} \\ &=\sum_{t} \operatorname{diag}\left(1-\left(\boldsymbol{h}^{(t)}\right)^{2}\right)\left(\nabla_{\boldsymbol{h}^{(t)}} L\right) \boldsymbol{h}^{(t-1)^{\top}} \\ \nabla_{U} L &=\sum_{t} \sum_{i}\left(\frac{\partial L}{\partial h_{i}^{(t)}}\right) \nabla_{\boldsymbol{U}^{(t)}} h_{i}^{(t)} \\ &=\sum_{t} \operatorname{diag}\left(1-\left(\boldsymbol{h}^{(t)}\right)^{2}\right)\left(\nabla_{\boldsymbol{h}^{(t)}} L\right) \boldsymbol{x}^{(t)^{\top}} \end{aligned} ?c?L?b?L?V?L?W??U?L?=t∑?(?c?o(t)?)??o(t)?L=t∑??o(t)?L=t∑?(?b(t)?h(t)?)??h(t)?L=t∑?diag(1?(h(t))2)?h(t)?L=t∑?i∑?(?oi(t)??L?)?V?oi(t)?=t∑?(?o(t)?L)h(t)?=t∑?i∑?(?hi(t)??L?)?W(t)?hi(t)?=t∑?diag(1?(h(t))2)(?h(t)?L)h(t?1)?=t∑?i∑?(?hi(t)??L?)?U(t)?hi(t)?=t∑?diag(1?(h(t))2)(?h(t)?L)x(t)??
RNN確定序列長度方式
第一種是添加一個表示序列末端的特殊符號。在訓練集中,我們將該符號作為序列的一個額外成員,即緊跟每個訓練樣本 x (τ) 之后。
第二種選擇是在模型中引入一個額外的Bernoulli輸出,表示在每個時間步決定繼續或停止。相比向詞匯表增加一個額外符號,這種方法更普遍,因為它適用于任何RNN。在這種方法中,sigmoid被訓練為最大化正確預測的對數似然,即在每個時間步序列決定結束或繼續。
第三種是將一個額外的輸出添加到模型并預測整數 τ 本身。模型可以預測 τ 的值,然后使用 τ 步有價值的數據。這種方法需要在每個時間步的循環更新中增加一個額外輸入,使得循環更新知道它是否是靠近所產生序列的末尾。
其他RNN結構
除了上面介紹的RNN結構,還有一些其他結構:
1, 每個時間步都產生一個輸出,但是只有當前時刻的輸出 o 與下個時刻的隱藏單元之間有連接的RNN:
這樣的RNN沒有最開始介紹的 RNN 那樣強大,上圖中的RNN被訓練為將特定輸出值放入 o 中,并且 o 是允許傳播到未來的唯一信息。此處沒有從 h 前向傳播的直接連接。之前的 h 僅通過產生的預測間接地連接到當前。o 通常缺乏過去的重要信息,除非它非常高維且內容豐富。這使得該圖中的RNN不那么強大,但是它更容易訓練,因為每個時間步可以與其他時間步分離訓練,允許訓練期間更多的并行化。
2, 隱藏單元之間存在循環連接,但讀取整個序列后只在最后一個時間步產生單個輸出的RNN:
這樣的網絡可以用于概括序列,并產生一個向量 o 用于表示整個輸入序列,然后可以對 o 進行進一步的處理。例如在翻譯任務中,先輸入原始輸入的句子,得到句子的向量表示 o ,然后對 o 展開進一步的翻譯任務。
3,包含上下文的RNN:
此RNN包含從前一個輸出到當前狀態的連接。這些連接允許RNN在給定 x 的序列后,對相同長度的 y 序列上的任意分布建模。
4,雙向RNN
在許多應用中,我們要輸出的 y (t) 的預測可能依賴于整個輸入序列。例如,在語音識別中,當前聲音作為音素的正確解釋可能取決于未來幾個音素,甚至可能取決于未來的幾個詞,因為詞與附近的詞之間的存在語義依賴。雙向RNN結構如下:
隱藏狀態變量 h 在時間上向前傳播信息(向右),而隱藏狀態變量 g 在時間上向后傳播信息(向左)。因此在每個點 t,輸出單元 o (t) 可以受益于輸入 h (t) 中關于過去的相關信息以及輸入 g (t) 中關于未來的相關信息。
5,編碼—解碼結構(序列到序列)的RNN
編碼—解碼結構的RNN支持將輸入序列映射到不一定等長的輸出序列,結構如下圖所示:
這在許多場景中都有應用,如語音識別、機器翻譯或問答,其中訓練集的輸入和輸出序列的長度通常不相同。它由讀取輸入序列的編碼器RNN以及生成輸出序列的解碼器RNN組成。編碼器RNN的最終隱藏狀態用于計算一般為固定大小的上下文向量 C,C 表示輸入序列的語義概要信息并且作為解碼器RNN的輸入。
基于RNN的應用
RNN通常用于處理序列形式的輸入數據,如文本,語音等。輸出也可以是序列或者某個預測值。常見的應用如下:
1,序列數據的分析
例如情感分析,輸入一句話的每個字的向量表示,輸出其情感的預測標簽。網絡結構如下:
2,序列數據的轉換
例如機器翻譯,輸入是某種語言的字序列,輸出是翻譯后的字序列。網絡結構如下:
再如,詞性標注,輸入是字的向量表示,輸出是每個字對應的詞性標注信息,常見網絡結構如下:
3,序列數據的生成
例如,圖片描述生成,輸入是一張圖片的向量表示,輸出圖片的描述信息。網絡結構如下:
RNN的不足
RNN很難解決長依賴問題,即經過許多個時間步的傳播之后,梯度值傾向于0或者無窮大,這樣的現象稱之為梯度消失和梯度爆炸。
1,從隱藏變量h角度來看
為了簡化說明,我們認為:
h(t)=WTh(t?1)\boldsymbol h^{(t)} = \boldsymbol W^T \boldsymbol h^{(t-1)} h(t)=WTh(t?1)
根據遞推關系,可以轉換為:
h(t)=(Wt)Th(0)\boldsymbol h^{(t)} = (\boldsymbol W^t)^T \boldsymbol h^{(0)} h(t)=(Wt)Th(0)
當W\boldsymbol WW 符合下列形式的特征分解:
W=QΣQT\boldsymbol W = \boldsymbol Q \boldsymbol \Sigma \boldsymbol Q^T W=QΣQT
其中Q\boldsymbol QQ是正交矩陣。于是有:
h(t)=QTΣtQh(0)\boldsymbol h^{(t)} = \boldsymbol Q^T \boldsymbol \Sigma^t \boldsymbol Q \boldsymbol h^{(0)} h(t)=QTΣtQh(0)
經過多個階段的傳播后,如果$ \boldsymbol \Sigma^t中的特征值小于1,特征值將衰減到零。如果特征值大于1,經過中的特征值小于1,特征值將衰減到零。如果特征值大于1,經過中的特征值小于1,特征值將衰減到零。如果特征值大于1,經過t次相乘后,特征值將激增。任何不與最大特征向量對齊的次相乘后,特征值將激增。任何不與最大特征向量對齊的次相乘后,特征值將激增。任何不與最大特征向量對齊的\boldsymbol h^{(0)}$的部分將最終被丟棄,無法做到長期依賴。
2,從梯度傳播角度來看
梯度的反向傳播過程如下圖所示:
不難得到:
?J?y0=?J?h3?h3?h2?h2?h1?h1?y0\frac{\partial J}{\partial y_0} = \frac{\partial J}{\partial h_3}\frac{\partial h_3}{\partial h_2} \frac{\partial h_2}{\partial h_1} \frac{\partial h_1}{\partial y_0} ?y0??J?=?h3??J??h2??h3???h1??h2???y0??h1??
上面的式子是多個偏導數的累乘,如果每個偏導數的值都小于1,那么傳播到 t=0t=0t=0 時刻的梯度幾乎等于0了,也就是梯度消失了。梯度消失意味著只有靠近輸出的幾層才真正起到學習的作用,無法通過加深網絡層數來提升預測效果,這樣RNN很難學習到輸入序列中的長距離依賴關系。
反之,如果每個偏導數的值都大于1,那么傳播到 t=0t=0t=0 時刻的梯度被指數倍放大,也就是梯度爆炸了。可以通過梯度裁剪來緩解,即當梯度的范式大于某個給定值的時候,對梯度進行等比縮放。
為了能學習到更長的依賴關系,需要對RNN網絡加以改進,下一篇文章提到的LSTM模型可以一定程度上得到改善。
參考文章:
《深度學習》
RNN詳解
總結
以上是生活随笔為你收集整理的循环神经网络(RNN)相关知识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 菜鸟裹裹怎么添加地址
- 下一篇: matlab设置随机流的种子