天天看點

零基礎入門深度學習(五):長短時記憶網絡

但不幸的一面是,lstm的結構很複雜,是以,我們需要花上一些力氣,才能把lstm以及它的訓練算法弄明白。在搞清楚lstm之後,我們再介紹一種lstm的變體:gru (gated recurrent unit)。 它的結構比lstm簡單,而效果卻和lstm一樣好,是以,它正在逐漸流行起來。最後,我們仍然會動手實作一個lstm。

長短時記憶網絡是啥

零基礎入門深度學習(五):長短時記憶網絡
零基礎入門深度學習(五):長短時記憶網絡

梯度消失到底意味着什麼?在《零基礎入門深度學習(4):循環神經網絡》中我們已證明,權重數組w最終的梯度是各個時刻的梯度之和,即:

零基礎入門深度學習(五):長短時記憶網絡

假設某輪訓練中,各時刻的梯度以及最終的梯度之和如下圖:

零基礎入門深度學習(五):長短時記憶網絡

我們就可以看到,從上圖的t-3時刻開始,梯度已經幾乎減少到0了。那麼,從這個時刻開始再往之前走,得到的梯度(幾乎為零)就不會對最終的梯度值有任何貢獻,這就相當于無論t-3時刻之前的網絡狀态h是什麼,在訓練中都不會對權重數組w的更新産生影響,也就是網絡事實上已經忽略了t-3時刻之前的狀态。這就是原始rnn無法處理長距離依賴的原因。

既然找到了問題的原因,那麼我們就能解決它。從問題的定位到解決,科學家們大概花了7、8年時間。終于有一天,hochreiter和schmidhuber兩位科學家發明出長短時記憶網絡,一舉解決這個問題。

其實,長短時記憶網絡的思路比較簡單。原始rnn的隐藏層隻有一個狀态,即h,它對于短期的輸入非常敏感。那麼,假如我們再增加一個狀态,即c,讓它來儲存長期的狀态,那麼問題不就解決了麼?如下圖所示:

零基礎入門深度學習(五):長短時記憶網絡

新增加的狀态c,稱為單元狀态(cell state)。我們把上圖按照時間次元展開:

零基礎入門深度學習(五):長短時記憶網絡
零基礎入門深度學習(五):長短時記憶網絡

lstm的關鍵,就是怎樣控制長期狀态c。在這裡,lstm的思路是使用三個控制開關。第一個開關,負責控制繼續儲存長期狀态c;第二個開關,負責控制把即時狀态輸入到長期狀态c;第三個開關,負責控制是否把長期狀态c作為目前的lstm的輸出。三個開關的作用如下圖所示:

零基礎入門深度學習(五):長短時記憶網絡

接下來,我們要描述一下,輸出h和單元狀态c的具體計算方法。

長短時記憶網絡的前向計算

前面描述的開關是怎樣在算法中實作的呢?這就用到了門(gate)的概念。門實際上就是一層全連接配接層,它的輸入是一個向量,輸出是一個0到1之間的實數向量。假設w是門的權重向量,是偏置項,那麼門可以表示為:

零基礎入門深度學習(五):長短時記憶網絡

我們先來看一下遺忘門:

零基礎入門深度學習(五):長短時記憶網絡

下圖顯示了遺忘門的計算:

零基礎入門深度學習(五):長短時記憶網絡

接下來看看輸入門:

零基礎入門深度學習(五):長短時記憶網絡

上式中,wi是輸入門的權重矩陣,bi是輸入門的偏置項。下圖表示了輸入門的計算:

零基礎入門深度學習(五):長短時記憶網絡
零基礎入門深度學習(五):長短時記憶網絡
零基礎入門深度學習(五):長短時記憶網絡
零基礎入門深度學習(五):長短時記憶網絡
零基礎入門深度學習(五):長短時記憶網絡
零基礎入門深度學習(五):長短時記憶網絡

下圖表示輸出門的計算:

零基礎入門深度學習(五):長短時記憶網絡

lstm最終的輸出,是由輸出門和單元狀态共同确定的:

零基礎入門深度學習(五):長短時記憶網絡

下圖表示lstm最終輸出的計算:

零基礎入門深度學習(五):長短時記憶網絡

式1到式6就是lstm前向計算的全部公式。至此,我們就把lstm前向計算講完了。

長短時記憶網絡的訓練

熟悉我們這個系列文章的同學都清楚,訓練部分往往比前向計算部分複雜多了。lstm的前向計算都這麼複雜,那麼,可想而知,它的訓練算法一定是非常非常複雜的。現在隻有做幾次深呼吸,再一頭紮進公式海洋吧。

lstm訓練算法架構

lstm的訓練算法仍然是反向傳播算法,對于這個算法,我們已經非常熟悉了。主要有下面三個步驟:

零基礎入門深度學習(五):長短時記憶網絡

關于公式和符号的說明

首先,我們對推導中用到的一些公式、符号做一下必要的說明。

接下來的推導中,我們設定gate的激活函數為sigmoid函數,輸出的激活函數為tanh函數。他們的導數分别為:

零基礎入門深度學習(五):長短時記憶網絡

從上面可以看出,sigmoid和tanh函數的導數都是原函數的函數。這樣,我們一旦計算原函數的值,就可以用它來計算出導數的值。

零基礎入門深度學習(五):長短時記憶網絡
零基礎入門深度學習(五):長短時記憶網絡
零基礎入門深度學習(五):長短時記憶網絡

誤差項沿時間的反向傳遞

零基礎入門深度學習(五):長短時記憶網絡

下面,我們要把式7中的每個偏導數都求出來。根據式6,我們可以求出:

零基礎入門深度學習(五):長短時記憶網絡

根據式4,我們可以求出:

零基礎入門深度學習(五):長短時記憶網絡

因為:

零基礎入門深度學習(五):長短時記憶網絡

我們很容易得出:

零基礎入門深度學習(五):長短時記憶網絡

将上述偏導數帶入到式7,我們得到:

零基礎入門深度學習(五):長短時記憶網絡

式8到式12就是将誤差沿時間反向傳播一個時刻的公式。有了它,我們可以寫出将誤差項向前傳遞到任意k時刻的公式:

零基礎入門深度學習(五):長短時記憶網絡

将誤差項傳遞到上一層

我們假設目前為第l層,定義l-1層的誤差項是誤差函數對l-1層權重輸入的導數,即:

零基礎入門深度學習(五):長短時記憶網絡
零基礎入門深度學習(五):長短時記憶網絡

式14就是将誤差傳遞到上一層的公式。

權重梯度的計算

對于

零基礎入門深度學習(五):長短時記憶網絡

我們已經求得了誤差項

零基礎入門深度學習(五):長短時記憶網絡

,很容易求出t時刻的

零基礎入門深度學習(五):長短時記憶網絡

零基礎入門深度學習(五):長短時記憶網絡

将各個時刻的梯度加在一起,就能得到最終的梯度:

零基礎入門深度學習(五):長短時記憶網絡

對于偏置項

零基礎入門深度學習(五):長短時記憶網絡

的梯度,也是将各個時刻的梯度加在一起。下面是各個時刻的偏置項梯度:

零基礎入門深度學習(五):長短時記憶網絡

下面是最終的偏置項梯度,即将各個時刻的偏置項梯度加在一起:

零基礎入門深度學習(五):長短時記憶網絡
零基礎入門深度學習(五):長短時記憶網絡

的權重梯度,隻需要根據相應的誤差項直接計算即可:

零基礎入門深度學習(五):長短時記憶網絡

以上就是lstm的訓練算法的全部公式。因為這裡面存在很多重複的模式,仔細看看,會發覺并不是太複雜。

當然,lstm存在着相當多的變體,讀者可以在網際網路上找到很多資料。因為大家已經熟悉了基本lstm的算法,是以了解這些變體比較容易,是以本文就不再贅述了。

長短時記憶網絡的實作

在下面的實作中,lstmlayer的參數包括輸入次元、輸出次元、隐藏層次元,單元狀态次元等于隐藏層次元。gate的激活函數為sigmoid函數,輸出的激活函數為tanh。

激活函數的實作

我們先實作兩個激活函數:sigmoid和tanh。

零基礎入門深度學習(五):長短時記憶網絡

lstm初始化

和前兩篇文章代碼架構一樣,我們把lstm的實作放在lstmlayer類中。

根據lstm前向計算和方向傳播算法,我們需要初始化一系列矩陣和向量。這些矩陣和向量有兩類用途,一類是用于儲存模型參數,例如

零基礎入門深度學習(五):長短時記憶網絡

;另一類是儲存各種中間計算結果,以便于反向傳播算法使用,它們包括

零基礎入門深度學習(五):長短時記憶網絡

,以及各個權重對應的梯度。

在構造函數的初始化中,隻初始化了與forward計算相關的變量,與backward相關的變量沒有初始化。這是因為構造lstm對象的時候,我們還不知道它未來是用于訓練(既有forward又有backward)還是推理(隻有forward)。

零基礎入門深度學習(五):長短時記憶網絡
零基礎入門深度學習(五):長短時記憶網絡

前向計算的實作

forward方法實作了lstm的前向計算:

零基礎入門深度學習(五):長短時記憶網絡

從上面的代碼我們可以看到,門的計算都是相同的算法,而門和的計算僅僅是激活函數不同。是以我們提出了calc_gate方法,這樣減少了很多重複代碼。

反向傳播算法的實作

backward方法實作了lstm的反向傳播算法。需要注意的是,與backword相關的内部狀态變量是在調用backward方法之後才初始化的。這種延遲初始化的一個好處是,如果lstm隻是用來推理,那麼就不需要初始化這些變量,節省了很多記憶體。

零基礎入門深度學習(五):長短時記憶網絡

算法主要分成兩個部分,一部分使計算誤差項:

零基礎入門深度學習(五):長短時記憶網絡
零基礎入門深度學習(五):長短時記憶網絡

另一部分是計算梯度:

零基礎入門深度學習(五):長短時記憶網絡
零基礎入門深度學習(五):長短時記憶網絡

梯度下降算法的實作

下面是用梯度下降算法來更新權重:

零基礎入門深度學習(五):長短時記憶網絡

梯度檢查的實作

和recurrentlayer一樣,為了支援梯度檢查,我們需要支援重置内部狀态:

零基礎入門深度學習(五):長短時記憶網絡

最後,是梯度檢查的代碼:

零基礎入門深度學習(五):長短時記憶網絡
零基礎入門深度學習(五):長短時記憶網絡

我們隻對做了檢查,讀者可以自行增加對其他梯度的檢查。下面是某次梯度檢查的結果:

零基礎入門深度學習(五):長短時記憶網絡

gru

前面我們講了一種普通的lstm,事實上lstm存在很多變體,許多論文中的lstm都或多或少的不太一樣。在衆多的lstm變體中,gru (gated recurrent unit)也許是最成功的一種。它對lstm做了很多簡化,同時卻保持着和lstm相同的效果。是以,gru最近變得越來越流行。

gru對lstm做了兩個大改動:

将輸入門、遺忘門、輸出門變為兩個門:更新門(update gate)zt和重置門(reset gate)rt。

将單元狀态與輸出合并為一個狀态:h。

gru的前向計算公式為:

零基礎入門深度學習(五):長短時記憶網絡

下圖是gru的示意圖:

零基礎入門深度學習(五):長短時記憶網絡

gru的訓練算法比lstm簡單一些,留給讀者自行推導,本文就不再贅述了。

小結

至此,lstm——也許是結構最複雜的一類神經網絡——就講完了,相信拿下前幾篇文章的讀者們搞定這篇文章也不在話下吧!現在我們已經了解循環神經網絡和它最流行的變體——lstm,它們都可以用來處理序列。但是,有時候僅僅擁有處理序列的能力還不夠,還需要處理比序列更為複雜的結構(比如樹結構),這時候就需要用到另外一類網絡:遞歸神經網絡(recursive neural network),巧合的是,它的縮寫也是rnn。

原文釋出時間為:2011-01-20

本文來自雲栖社群合作夥伴dbaplus

繼續閱讀