1. 程式人生 > >通俗易懂--迴圈神經網路(RNN)的網路結構!(TensorFlow實現)

通俗易懂--迴圈神經網路(RNN)的網路結構!(TensorFlow實現)

1. 什麼是RNN

迴圈神經網路(Recurrent Neural Network, RNN)是一類以序列(sequence)資料為輸入,在序列的演進方向進行遞迴(recursion)且所有節點(迴圈單元)按鏈式連線的遞迴神經網路(recursive neural network)

1.1 RNN的應用

  • 文字生成(生成序列)
  • 機器翻譯
  • 看圖說話
  • 文字(情感)分析
  • 智慧客服
  • 聊天機器人
  • 語音識別
  • 搜尋引擎
  • 個性化推薦

1.2 為什麼有了CNN,還要RNN?

  • 傳統神經網路(包括CNN),輸入和輸出都是互相獨立的。影象上的貓和狗是分隔開的,但有些任務,後續的輸出和之前的內容是相關的。例如:我是中國人,我的母語是____。這是一道填空題,需要依賴於之前的輸入。
  • 所以,RNN引入“記憶”的概念,也就是輸出需要依賴於之前的輸入序列,並把關鍵輸入記住。迴圈2字來源於其每個元素都執行相同的任務。
  • 它並⾮剛性地記憶所有固定⻓度的序列,而是通過隱藏狀態來儲存之前時間步的資訊。

1.3 RNN的網路結構

首先先上圖,然後再解釋:

現在我們考慮輸⼊資料存在時間相關性的情況。假設 \(X_t\in_{}\mathbb{R}^{n*d}\) 是序列中時間步t的小批量輸⼊,\(H_t\in_{}\mathbb{R}^{n*h}\) 是該時間步的隱藏變數。那麼根據以上結構圖當前的隱藏變數的公式如下:

\[H_t=\phi(X_tW_{xh}+H_{t-1}W_{hh}+b_h)\]

從以上公式我們可以看出,這⾥我們儲存上⼀時間步的隱藏變數 \(H_{t-1}\),並引⼊⼀個新的權重引數,該引數⽤來描述在當前時間步如何使⽤上⼀時間步的隱藏變數。具體來說,時間步 t 的隱藏變數的計算由當前時間步的輸⼊和上⼀時間步的隱藏變數共同決定。 \(\phi\) 函式其實就是啟用函式。

我們在這⾥添加了 \(H_{t-1}W_{hh}\) ⼀項。由上式中相鄰時間步的隱藏變數 \(H_t 和H_{t-1}\) 之間的關係可知,這⾥的隱藏變數能夠捕捉截⾄當前時間步的序列的歷史資訊,就像是神經⽹絡當前時間步的狀態或記憶⼀樣。因此,該隱藏變數也稱為隱藏狀態。由於隱藏狀態在當前時間步的定義使⽤了上⼀時間步的隱藏狀態,上式的計算是迴圈的。使⽤迴圈計算的⽹絡即迴圈神經⽹絡(recurrent neural network)。

在時間步t,輸出層的輸出和多層感知機中的計算類似:

\[O_t=H_tW_{hq}+b_q\]

1.4 雙向RNN

之前介紹的迴圈神經⽹絡模型都是假設當前時間步是由前⾯的較早時間步的序列決定的,因此它
們都將資訊通過隱藏狀態從前往後傳遞。有時候,當前時間步也可能由後⾯時間步決定。例如,
當我們寫下⼀個句⼦時,可能會根據句⼦後⾯的詞來修改句⼦前⾯的⽤詞。雙向迴圈神經⽹絡通過增加從後往前傳遞資訊的隱藏層來更靈活地處理這類資訊。下圖演⽰了⼀個含單隱藏層的雙向迴圈神經⽹絡的架構。

在雙向迴圈神經⽹絡的架構中,設該時間步正向隱藏狀態為 \(\overrightarrow{H}_t\in_{}\mathbb{R}^{n*h}\)(正向隱藏單元個數為h),反向隱藏狀態為 \(\overleftarrow{H}_t\in_{}\mathbb{R}^{n*h}\)(反向隱藏單元個數為h)。我們可以分別
計算正向隱藏狀態和反向隱藏狀態:

\[\overrightarrow{H}_t=\phi(X_tW_{xh}^{(f)}+\overrightarrow{H}_{t-1}W_{hh}^{(f)}+b_h^{(f)})\]

\[\overleftarrow{H}_t=\phi(X_tW_{xh}^{(b)}+\overleftarrow{H}_{t-1}W_{hh}^{(b)}+b_h^{(b)})\]

然後我們連結兩個⽅向的隱藏狀態 \(\overrightarrow{H}_t和\overleftarrow{H}_t\) 來得到隱藏狀態 \(H_t\in_{}\mathbb{R}^{n*2h}\),並將其輸⼊到輸出層。輸出層計算輸出 \(O_t\in_{}\mathbb{R}^{n*q}\)(輸出個數為q):

\[O_t=H_tW_{hq}+b_q\]

雙向迴圈神經⽹絡在每個時間步的隱藏狀態同時取決於該時間步之前和之後的⼦序列(包
括當前時間步的輸⼊)。

1.5 BPTT演算法

在之前你已經見過對於前向傳播(上圖藍色箭頭所指方向)怎樣在神經網路中從左到右地計算這些啟用項,直到輸出所有地預測結果。而對於反向傳播,我想你已經猜到了,反向傳播地計算方向(上圖紅色箭頭所指方向)與前向傳播基本上是相反的。

我們先定義一個元素損失函式:

\[L^{(t)}(y^{'(t)},y^{(t)})=-y^{(t)}logy^{'(t)}-(1-y^{'(t)})log(1-y^{'(t)})\]

整個序列的損失函式:

\[L(y^{'},y)=\sum_{t=1}^{T_x}L^{(t)}(y^{'(t)},y^{(t)})\]$

在這個計算圖中,通過\(y^{'(1)}\)可以計算對應的損失函式,於是計算出第一個時間步的損失函式,然後計算出第二個時間步的損失函式,然後是第三個時間步,一直到最後一個時間步,最後為了計算出總體損失函式,我們要把它們都加起來,通過等式計算出最後的