CS224n學習筆記(三)

語言模型

對於一個文本中出現的單詞 $w_i$ 的機率,他更多的依靠的是前 $n$ 個單詞,而不是這句話中前面全部的單詞。 $$ P\left(w_{1}, \ldots, w_{m}\right)=\prod_{i=1}^{i=m} P\left(w_{i} | w_{1}, \ldots, w_{i-1}\right) \approx \prod_{i=1}^{i=m} P\left(w_{i} | w_{i-n}, \ldots, w_{i-1}\right) $$ 在翻譯系統中就是對於輸入的短語,經過對全部的輸出的語句進行評分,獲得機率最大的那個輸出,做爲預測的機率。算法

n-gram 語言模型

對於N-Gram模型,首先要知道其中的該模型中的 count的意思,count 能夠用來表示單詞出現的頻率,這個模型與條件機率密切相關,其中, $$ \begin{aligned} p\left(w_{2} | w_{1}\right) &=\frac{\operatorname{count}\left(w_{1}, w_{2}\right)}{\operatorname{count}\left(w_{1}\right)} \ p\left(w_{3} | w_{1}, w_{2}\right) &=\frac{\operatorname{count}\left(w_{1}, w_{2}, w_{3}\right)}{\operatorname{count}\left(w_{1}, w_{2}\right)} \end{aligned} $$ 對於上面的式子的解釋就是,咱們將 連續單詞出現的頻率做爲機率,而後經過條件機率的形式預測出下一個單詞。這個模型面臨的問題是,選取多大的框,也就是選取前面多少個單詞,這裏面還牽涉到稀疏問題,沒必要要的信息就不存儲,同時還要存儲必要信息。網絡

對於上面的模型須要考慮一些問題,首先是,分母分子爲零的app

基於窗口的神經語言模型

傳統的模型能夠簡化爲下面的圖片中的樣式:函數

藍色的一層是對輸入的處理,獲取單詞向量:$\boldsymbol{e}=\left[\boldsymbol{e}^{(1)} ; \boldsymbol{e}^{(2)} ; \boldsymbol{e}^{(3)} ; \boldsymbol{e}^{(4)}\right]$。而後紅色就是中間的隱含層,$h=f\left(\boldsymbol{W} \boldsymbol{e}+\boldsymbol{b}{1}\right)$,最後加一個 $Softmax$ 層,就是分類的意思,$\hat{y}=\operatorname{softmax}\left(U h+b{2}\right)$。優化

Recurrent Neural Networks (RNN)

傳統的 $RNN$ 以下圖所示,是一個比較簡單的結構,咱們能夠用兩個式子來表示:spa

對於每一層的輸入,像下面這個式子,其中激活函數通常會使用 $tanh()$, 也可使用 $sigmoid$,下面的兩個矩陣 $W^{(hh)}$ 和矩陣 $W^{(hx)}$ 維度不一樣,由於本質都是線性的,因此維度不一樣沒有關係。 $$ h_{t}=\sigma\left(W^{(h h)} h_{t-1}+W^{(h x)} x_{[t]}\right) $$ 而後先經過一個矩陣 $W^{(S)}$ 而後經過一個 $Softmax$ 函數就能夠了, $$ \hat{y}{t}=\operatorname{softmax}\left(W^{(S)} h{t}\right) $$ 對於 $softmax$ 函數,咱們還要知道,$\hat{y}{t}$ 是最終預測的得分,而咱們 $RNN$ 傳遞的是 $h_t$。其中$W^{(S)} \in \mathbb{R}^{|V| \times D{h}}$ and $\hat{y} \in \mathbb{R}^{|V|}$。翻譯

上圖就是對於一個句子的翻譯,能夠看出傳統方法,與 RNN的區別。code

RNN 的損失函數

咱們一般用交叉熵損失函數來表示錯誤率,交叉熵損失函數就是統計預測正確的原本正確的機率,而後取反做爲目標函數,一般還會取一個對數, $$ J^{(t)}(\theta)=-\sum_{j=1}^{|V|} y_{t, j} \times \log \left(\hat{y}{t, j}\right) $$ 若是一個語料庫的大小爲 $T$,那麼交叉熵損失函數就是應用於 大小爲 $T$ 的每個單詞: $$ J=\frac{1}{T} \sum{t=1}^{T} J^{(t)}(\theta)=-\frac{1}{T} \sum_{t=1}^{T} \sum_{j=1}^{|V|} y_{t, j} \times \log \left(\hat{y}_{t, j}\right) $$ RNN還有一個概念叫作困惑,所謂困惑,定義以下: $$ Perplexity =2^{J} $$blog

RNN 的優缺點及其使用

使用 RNN的時的一些問題,圖片

  1. RNN 網絡具備記憶性,
  2. RNN 網絡使用時,內存大小與語句大小成比例。
  3. RNN 中矩陣的大小與迭代的次數有關。

RNN 中的梯度消失與梯度爆炸問題

舉個例子,對於兩個句子:

"Jane walked into the room. John walked in too. Jane said hi to ___"

"Jane walked into the room. John walked in too. It was late in the day, and everyone was walking home after a long day at work. Jane said hi to ___"

使用RNN預測空格里面的單詞,第一個句子預測正確的機率要更大一些。

下面從數學的角度解釋梯度消失問題。

就像傳統神經網絡反向傳播的時候同樣,咱們要對參數矩陣求導,以此得到最佳的參數。而在 RNN中,咱們須要將每一次的損失加起來,也就是下面的式子: $$ \frac{\partial E}{\partial W}=\sum_{t=1}^{T} \frac{\partial E_{t}}{\partial W} $$ 對於每個時間點 $t$,咱們使用鏈式規則, $$ \frac{\partial E_{t}}{\partial W}=\sum_{k=1}^{t} \frac{\partial E_{t}}{\partial y_{t}} \frac{\partial y_{t}}{\partial h_{t}} \frac{\partial h_{t}}{\partial h_{k}} \frac{\partial h_{k}}{\partial W} $$ 注意對於時間點 t, 咱們要考慮從起始點一直到時間點 t,這是由於 RNN是鏈式的,而不像傳統的神經網絡不是鏈式的,至關於每一步都要進行一次優化矩陣 W,因此計算 $d h_{t} / d h_{k}$ 能夠用下面的方法: $$ \frac{\partial h_{t}}{\partial h_{k}}=\prod_{j=k+1}^{t} \frac{\partial h_{j}}{\partial h_{j-1}}=\prod_{j=k+1}^{t} W^{T} \times \operatorname{diag}\left[f^{\prime}\left(h_{j-1}\right)\right] $$ 因此鏈式規則等價於下面的式子: $$ \frac{\partial E}{\partial W}=\sum_{t=1}^{T} \sum_{k=1}^{t} \frac{\partial E_{t}}{\partial y_{t}} \frac{\partial y_{t}}{\partial h_{t}}\left(\prod_{j=k+1}^{t} \frac{\partial h_{j}}{\partial h_{j-1}}\right) \frac{\partial h_{k}}{\partial W} $$ 上週講到神經網絡中的梯度降低的時候,對矩陣的鏈式求導,咱們講到了雅可比矩陣,這裏就用雅可比矩陣。 $$ \frac{\partial h_{j}}{\partial h_{j-1}}=\left[\frac{\partial h_{j}}{\partial h_{j-1,1}} \dots \frac{\partial h_{j}}{\partial h_{j-1, D_{n}}}\right]=\left[ \begin{array}{ccc}{\frac{\partial h_{j, 1}}{\partial h_{j-1,1}}} & {\cdots} & {\frac{\partial h_{j, 1}}{\partial h_{j-1, D_{n}}}} \ {\vdots} & {\ddots} & {\vdots} \ {\frac{\partial h_{j, D_{n}}}{\partial h_{j-1,1}}} & {\cdots} & {\frac{\partial h_{j, D_{n}}}{\partial h_{j-1, D_{n}}}}\end{array}\right] $$ 上面的式子很重要,由於要計算 $h_j$ 與 $h_{j-1}$之間的關係,$h_{t}=\sigma\left(W^{(h h)} h_{t-1}+W^{(h x)} x_{[t]}\right)$。對這個函數中 $h_{j-1}$ 求偏導。根據求導的鏈式法則 $$ \frac{\partial h_{j}}{\partial h_{j-1}} = W^{T} \times \operatorname{diag}\left[f^{\prime}\left(h_{j-1}\right)\right] $$ 咱們用 $\beta_{W} ,\beta_{h}$分別表示兩個行列式的上確界,而對於上面的式子,咱們有: $$ \left|\frac{\partial h_{j}}{\partial h_{j-1}}\right| \leq\left|W^{T}\right|\left|\operatorname{diag}\left[f^{\prime}\left(h_{j-1}\right)\right]\right| \leq \beta_{W} \beta_{h} $$ 所以用於鏈式法則就是: $$ \left|\frac{\partial h_{t}}{\partial h_{k}}\right|=\left|\prod_{j=k+1}^{t} \frac{\partial h_{j}}{\partial h_{j-1}}\right| \leq\left(\beta_{W} \beta_{h}\right)^{t-k} $$ 咱們將最初的式子替換一下,就是下面這樣: $$ \frac{\partial E_{t}}{\partial W}=\sum_{k=1}^{t} \frac{\partial E_{t}}{\partial y_{t}} \frac{\partial y_{t}}{\partial h_{t}} \left(\beta_{W} \beta_{h}\right)^{t-k} \frac{\partial h_{k}}{\partial W} $$ 顯然這裏有指數的問題,因此問題就與直接與 $\beta_{W} ,\beta_{h}$相關了。因此梯度消失的問題就是 $\beta_{W} \beta_{h}$ 與 1 的大小關係的問題了。當 $\beta_{W} \beta_{h}$ 大於 1的時候咱們成爲梯度爆炸,接近 0 的時候,咱們稱爲梯度消失。

RNN 梯度降低與梯度消失的解決方法

處理梯度上升的一個簡單的策略就是設置閾值: $$ \begin{array}{c}{\hat{g} \leftarrow \frac{\partial E}{\partial W}} \ {\text { if }|\hat{g}| \geq \text { threshold then }} \ {\hat{g} \leftarrow \frac{\text {threshold}}{|\hat{g}|} \hat{g}} \ {\text { end if }}\end{array} $$ 爲了解決梯度消失問題,能夠採用兩種方法,分別是初始化矩陣 $W^{(h h)}$,而不是隨機取這個矩陣。另外一種方法是,激活函數使用 $ReLU$ 而不是$sigmod$ 函數,由於 ReLU 函數的導數要麼是 0,要麼是 1。

深度雙向RNN

雙向 RNN,顧名思義就是有兩個方向相反的 RNN,若是未知的是中間位置的單詞,咱們也能夠反過來預測,這就是反向 RNN的思想。就如同下面的公式所說的: $$ \vec{h}{t}=f\left(\vec{W} x{t}+\vec{V} \vec{h}_{t-1}+\vec{b}\right) $$

$$ \stackrel{\leftarrow}{h}{t}=f\left(\stackrel\leftarrow{W} x{t}+\stackrel{\leftarrow}{V} \stackrel{\leftarrow}h_{t+1}+\stackrel{\leftarrow}{b}\right) $$

$$ \hat{y}{t}=g\left(U h{t}+c\right)=g\left(U\left[\stackrel{\rightarrow}{h}{t} ; \stackrel{\leftarrow}{h}{t}\right]+c\right) $$

上面右圖是多層 RNN 的模型,對於 $h_t^{(i)}$,既與前一層 t 時刻的神經元 $h_t^{(i-1)}$ 有關,還和 $h_{t-1}^{(i)}$ 這一層前一個時刻的神經元有關,也就是每個時間步長,不只會縱向傳播(RNN的序列傳播),還會橫向傳播,全部的層,並行的向前傳播),用公式表示就是: $$ \vec{h}{t}^{(i)}=f\left(\vec{W}^{(i)} h{t}^{(i-1)}+\vec{V}^{(i)} \vec{h}_{t-1}^{(i)}+\vec{b}^{(i)}\right) $$

$$ \stackrel{\leftarrow}{h}{t}^{(i)}=f\left(\stackrel{\leftarrow}{W}^{(i)} h{t}^{(i-1)}+\stackrel{\leftarrow}{V}^{(i)} \stackrel{\leftarrow}{h}_{t-1}^{(i)}+\stackrel{\leftarrow}{b}^{(i)}\right) $$

$$ \hat{y}{t}=g\left(U h{t}+c\right)=g\left(U\left[\vec{h}{t}^{(L)} ; \stackrel{\leftarrow}{h}{t}^{(L)}\right]+c\right) $$

RNN 翻譯模型

咱們使用 RNN來完成翻譯,首先是 encoder,前面咱們講過神經依賴解析算法,若是咱們用 RNN實現這一步,那就是這裏的encoder了,這一步主要是講源語句轉化爲 dense的單詞向量。下面左圖中的,前三層神經網絡就是encoder的過程,而後最後兩層就是將向量轉換爲另外一種語言,也就是decoder的過程,其實decoder真正作的是,將向量轉爲另外一種語言表示的向量。

下面的等式: $$ h_{t}=\phi\left(h_{t-1}, x_{t}\right)=f\left(W^{(h h)} h_{t-1}+W^{(h x)} x_{t}\right) $$ 表示的是encoder的過程。在decoder階段, $$ h_{t}=\phi\left(h_{t-1}\right)=f\left(W^{(h h)} h_{t-1}\right) $$

$$ y_{t}=\operatorname{softmax}\left(W^{(S)} h_{t}\right) $$

對於上面的模型,咱們可使用交叉熵損失函數做爲目標函數: $$ \max {\theta} \frac{1}{N} \sum{n=1}^{N} \log p_{\theta}\left(y^{(n)} | x^{(n)}\right) $$

拓展

對於 decoder階段的隱層狀態能夠有三種不一樣的輸入,分別是:

  • decoder 前一個時間段的狀態 $h_{t-1}$.
  • encoder 的最後一層的狀態,就像圖 11所示
  • 前一個預測的輸出的單詞

因此咱們能夠考慮結合這三個輸出,也就獲得下面的模型: $$ h_{t}=\phi\left(h_{t-1}, c, y_{t-1}\right) $$ 這個順帶提到,在谷歌提出的 sequence to sequence中,能夠考慮將輸入單詞反轉來提升翻譯的準確率。

GRU

咱們先看下 GRU直觀的解釋。

新存儲信息的產生

$$ \tilde{h}{t}=\tanh \left(r{t} \circ U h_{t-1}+W x_{t}\right) $$

一個新的內存狀態表示,對於一個新輸入的單詞,考慮過去的狀態,既根據語境結合新的單詞與前面上下文的語境。好比咱們讀到句子中的一個絕不相關的單詞,那麼就不考慮這個單詞的效益。

Reset Gate

$$ r_{t}=\sigma\left(W^{(r)} x_{t}+U^{(r)} h_{t-1}\right) $$

能夠看做是一個通過激活函數的門,來判斷 $h_{t-1}$ 對 $h_t$ 的影響,判斷是否能夠徹底忽略 $h_{t-1}$ 若是 $h_{t-1}$ 與產生新內存無關。好比咱們進入一個徹底新的句子,在長語句中進入一個徹底新的句子,就能夠不考慮 $h_{t-1}$。

Update Gate

$$ z_{t}=\sigma\left(W^{(z)} x_{t}+U^{(z)} h_{t-1}\right) $$

這也是一個門,用來判斷更新的時候的取值,從上面的圖中能夠打看到, $z_t$ 是在 $\tilde{h}{t}$ 與 $h{(\mathrm{t}-1)}$ 之間的權衡的。咱們能夠這麼說,當 $z_t$ $\approx 1$ 的時候,$h_{t-1}$ 這一層幾乎所有複製給 $h_t$,而當 $z_t$ $\approx 0 $ 的時候,咱們更多的將 $\tilde{h}_{t}$ 傳到下一個狀態。

Hidden state:

$$ h_{t}=\left(1-z_{t}\right) \circ \tilde{h}{t}+z{t} \circ h_{t-1} $$

隱含層在計算的時候,是考慮到對 $\tilde{h}{t}$ 與 $h{(\mathrm{t}-1)}$ 之間的權衡取捨,這也是 GRU的核心之一。GRU的核心就是,首先判斷新來的單詞與上下文之間的關係,須要聯合語句構造新的語境。

LSTM

LSTM以前有所接觸,感受理解的不夠深入,比起 GRU,門明顯變多了,可是本質差不了太多,先看下直觀解釋:

New memory generation:

$$ \tilde{c}{t}=\tanh \left(W^{(c)} x{t}+U^{(c)} h_{t-1}\right) $$

這一步與 GRU相似。

Input Gate:

$$ i_{t}=\sigma\left(W^{(i)} x_{t}+U^{(i)} h_{t-1}\right) $$

判斷新的單詞是否值得做爲參數,和 GRU同樣。經過與上下文的結合,判斷這個輸入,有多大的權重做爲新的特徵。

Forget Gate:

$$ f_{t}=\sigma\left(W^{(f)} x_{t}+U^{(f)} h_{t-1}\right) $$

忘記層,與 Input Gate 相似,可是這裏是判斷是否忘記,也就是判斷是否忘記前面所記錄的信息,咱們能夠理解爲特徵。

Final memory generation:

$$ c_{t}=f_{t} \circ c_{t-1}+i_{t} \circ \tilde{c}_{t} $$

這一層就是根據前面的幾個門,信息留下的權重,新的信息考慮進去的權重。

Output/Exposure Gate:

$$ o_{t}=\sigma\left(W^{(o)} x_{t}+U^{(o)} h_{t-1}\right) $$

$$ h_{t}=o_{t} \circ \tanh \left(c_{t}\right) $$

這裏的兩個函數的目的是將 $h_t$ 與 $C_t$ 分開,由於 $C_t$ 中存儲了不少沒必要要的信息。由於隱含層做爲每個門的參數,因此這裏須要考慮哪些信息留在隱含層。因此使用了一個門 $O_t$。

相關文章
相關標籤/搜索