傳統的機器翻譯的方法每每是基於單詞與短語的統計,以及複雜的語法結構來完成的。基於序列的方式,能夠當作兩步,分別是 Encoder 與 Decoder,Encoder 階段就是將輸入的單詞序列(單詞向量)變成上下文向量,而後 decoder根據這個向量來預測翻譯的結果。html
encoder 階段面臨的一個問題是,對於輸入語句,語句的長度每每是不固定的,可是咱們訓練神經網絡每每都是要固定長度的向量。因此如何解決這個問題是 encoder階段的關鍵。咱們一般使用多層的 LSTM,上一層的輸出將做爲下一層的輸入。網絡
在 Google 提出 Seq2Seq 的時候,提出了將輸出的語句反序輸入到 encoder中,這麼作是爲了在 encoder階段的最後一個輸出剛好就是 docoder階段的第一個輸入。函數
這一階段要稍微與encoder階段要複雜一點點。首先是一個 Token, 通常是一個 <EOS> 表示輸入的結束,也就是下圖中的 "Go",表示 decoder 階段的開始,還有一點不同就是,咱們指望用以及正確預測的數據做爲下一次的上下文參考,因此也就是上一節講到的 \(C_i\) 的信息,做用到下一個時間點。橫向能夠當作 序列的,縱向能夠當作是並行的(可是實際上不是並行的)。lua
上面的方法面臨這樣一個問題,那就是單詞向量每每是與上下文有關的,而不只僅只於前面的文字有關,因此須要改進單向 RNN,這裏咱們使用雙向 RNN來解決這個問題:spa
上圖是一個雙向 LSTM,圖中是一個encoder的例子,每個隱含層的狀態都有兩個向量表示,分別表示兩個方向,\(h=\left[h^{(f)} \quad h^{(b)}\right]\)。輸出也有兩個,分別是 \(\left[ \begin{array}{ll}{o_{t}^{(f)}} & {o_{t}^{(b)}}\end{array}\right]\)。翻譯
在翻譯的模型中,舉個簡單的例子,code
"the ball is on the field,"htm
其中關鍵的單詞就那麼幾個,並且不少狀況下,若是將全部的單詞都考慮進來的話,會致使過擬合,反而會致使語義的不許確,因此提出了attention 的機制,主要思想做用在 decoder階段,每次觀察整個句子,在每一步能夠決定那些單詞是重要的。blog
encoder階段使用一個雙向 LSTM,ip
神經網絡隱含層的使用的機制:
\[ s_{i}=f\left(s_{i-1}, y_{i-1}, c_{i}\right) \]
其中 \(s_{i-1}\) 是神經網絡前一層的輸出,而後 \(y_{i-1}\) 是上一個時間序列,也就是預測的上一個單詞的輸出,\(C_{t}\) 於LSTM中的 \(C_t\)不太同樣,可是本質上都是用來記錄信息的。
經過神經網絡的輸出,預測的機制:
\[ p\left(y_{i} | y_{1}, \ldots, y_{i-1}, \mathbf{x}\right)=g\left(y_{i-1}, s_{i}, c_{i}\right) \]
上面式子中用到的 \(y_{i-1}\) 就很容易理解了。
這個 \(C_i\) 本質上都是用來記錄信息的,這裏的計算方式是:
\[ c_{i}=\sum_{j=1}^{T_{x}} \alpha_{i j} h_{j} \]
上式中的 \(h_j\) 也不是LSTM中的隱含層的狀態,隱含層的狀態是 \(s_i\) ,而是包含了重點關注第 \(i\)個單詞的信息。因此咱們很容易想到,這裏獲取 \(c_i\) 的時候必需要加權,就是對每一個 \(i\),進行加權,那麼衡量權重的標誌是什麼呢?咱們用 \(e_{ij}\) 來表示,
\[ e_{i j}=a\left(s_{i-1}, h_{j}\right) \]
這是一個對齊模型,表示輸入的單詞 \(j\), (咱們重點關注的)在輸出位置爲 \(i\) 的可能性大小。而後咱們將這個得分進行加權計算,就獲得了
\[ \alpha_{i j}=\frac{\exp \left(e_{i j}\right)}{\sum_{k=1}^{T_{x}} \exp \left(e_{i k}\right)} \]
再返回去求 \(c_i\)。上面的對齊模型,咱們能夠直接使用一個傳統的神經網絡。attention 機制的一個好處就是能夠很好的翻譯長句子,由於能夠忽略不須要的信息。
對於encoder階段給出的隱藏層的狀態,\(h_{1}, \ldots, h_{n}\),對於 decoder階段的隱含層狀態,\(\overline{h_{1}}, \ldots, \overline{h_{n}}\)。咱們能夠計算一個得分,使用下面任意一種函數:
\[ \operatorname{score}\left(h_{i}, \overline{h}_{j}\right)=\left\{\begin{array}{l}{h_{i}^{T} \overline{h}_{j}} \\ {h_{i}^{T} W \overline{h}_{j}} \\ {W\left[h_{i}, \overline{h}_{j}\right]}\end{array}\right. \]
而後就像上面的那個模型同樣,經過 \(softmax\) 函數來計算機率,將這個機率做爲加權便可,
\[ \alpha_{i, j}=\frac{\exp \left(\operatorname{score}\left(h_{j}, \overline{h}_{i}\right)\right)}{\sum_{k=1}^{n} \exp \left(\operatorname{score}\left(h_{k}, \overline{h}_{i}\right)\right)} \]
而後就得出了單詞的文本向量,
\[ c_{i}=\sum_{j=1}^{n} \alpha_{i, j} h_{j} \]
接下來就能夠計算新的隱含層的狀態了:
\[ \tilde{h}_{i}=f\left(\left[\overline{h}_{i}, c_{i}\right]\right) \]
而後經過最後的預測函數,預測出下一個單詞。這裏在時間上 \(\tilde{h}_{i}\) 也會做爲下一個時間點的輸入。
Local Attention 就是使用了一個窗口表示關注的單詞,能夠改變窗口的大小,說明對任意的單詞均可以關注。
上面的例子也說明了,在 Attention 階段最重要的是 Decoder的策略。
機器翻譯起源於統計翻譯,咱們從機率的角度就是對於輸入語句 \(S\) 與目標語句 \(\overline{S}\),咱們的目標就是
\[ \overline{s} *=\operatorname{argmax}_{\overline{s}}(\mathbb{P}(\overline{s} | s)) \]
可是對於目標語句可能性太多,也就形成了計算量太大,咱們有幾種策略:
Beam search 是使用的最多的一種策略,這種方法就是每次維持一個大小爲 \(K\) 的翻譯語句集合,
\[ \mathcal{H}_{t}=\left\{\left(x_{1}^{1}, \ldots, x_{t}^{1}\right), \ldots,\left(x_{1}^{K}, \ldots, x_{t}^{K}\right)\right\} \]
當咱們預測 \(t+1\) 的時刻的時候,咱們依然取可能性最大的 \(K\) 個集合:
\[ \tilde{\mathcal{H}}_{t+1}=\bigcup_{k=1}^{K} \mathcal{H}_{t+1}^{\tilde{k}} \]
其中
\[ \mathcal{H}_{t+1}^{\tilde{k}}=\left\{\left(x_{1}^{k}, \ldots, x_{t}^{k}, v_{1}\right), \ldots,\left(x_{1}^{k}, \ldots, x_{t}^{k}, v_{|V|}\right)\right\} \]
表示每一種可能的組合。
將咱們翻譯的語句用於其餘的系統中以查看翻譯的效果。舉個例子,咱們將翻譯的語句用於問答系統,與標準的語句用於問答系統,都能獲得準確的回答,那麼說明咱們翻譯的過程當中抓住了句子的關鍵信息,在評估翻譯結果的時候,時要考慮多方面的,這是咱們既不能說咱們的翻譯徹底正確,也不能說是失敗了。
這個方法是經過將一個參與的翻譯系統的結果 B,與人工翻譯的結果 A,進行對比評估,使用 n-gram 的方法進行對比。其中可能會有多個參考也就是reference。
n-gram 的方法主要是關注窗口的大小。將連在一塊兒的單詞做爲一個窗口,而後計算匹配的窗口的個數。最簡單的例子就是:
對於窗口,咱們用 window 來表示,出現的次數,
\[ Count_{clip}=\min \left(\text { Count }, \text { Max }_{-} \text { Ref }_{-} \text { Count }\right) \]
表示這個 window 在翻譯文本與 reference文本中出現的最低的次數,那麼精度能夠這樣計算:
\[ P_{n}=\frac{\sum_{i} \sum_{k} \min \left(h_{k}\left(c_{i}\right), \max _{j \in m} h_{k}\left(s_{i j}\right)\right)}{\sum_{i} \sum_{k} \min \left(h_{k}\left(c_{i}\right)\right)} \]
\(H_k(c_i)\) 表示機器翻譯的結果中 \(c_i\) 出現的次數,\(H_k(s_{ij})\) 表示標準答案下 \(S_{ij}\) 出現的次數,這裏爲何 \(S\) 下面有雙下標,是由於,這裏咱們能夠有不少個 reference。
考慮機器翻譯的結果爲第二句,第一句爲參考的狀況,這個時候,計算的結果代表,翻譯的很好,由於第二個語句比較短,因此 \(H_k(s_{ij})\) 的正確率表現得比較高,可是實際上整個句子的翻譯效果沒有那麼高:
there are many ways to evaluate the quality of a translation, like comparing the number of n-grams between a candidate translation and reference
the quality of a translation is evaluate of n-grams in a reference and with translation
所以咱們引入一個懲罰因子:
\[ \beta=e^{\min \left(0,1-\frac{\operatorname{le}_{\mathrm{ref}}}{\operatorname{len}_{\mathrm{MT}}}\right)} \]
其中分子表示 reference的長度,分母是機器翻譯結果的長度,那麼最終的評分咱們就能夠表示成:
\[ B L E U=\beta \times \exp \left(\sum_{n=1}^{N} w_{n} \log P_{n}\right) \]
還有一個問題就是處理 vocabulary 過大的狀況下,因爲輸出的時候須要通過一個 \(softmax\) 函數,因此在輸出的時候,若是輸出的 vocabulary 過大的話,那麼 softmax 這一過程計算量就會特別大。
在第一節課裏面咱們就介紹過兩種方法,分別是分層 SoftMax 與 Negative Sampling(負採樣)。傳送門:傳送門
還有一些方法能夠用:
爲了限制詞典的大小,對於語句中出現的未知的單詞,咱們就用 <UNK> 來表示,可是這樣可能會致使源語句失去一些關鍵信息。還有一種方法就是,
還有一種作法就是將數據集進行劃分,這樣的好處是,類似關係的數據集通常在一塊兒。每一個訓練數據的子集取大小爲 $ \tau=\left|V^{\prime}\right|$ 的字典。而後對整個數據集進行迭代。主要思想就是,咱們在訓練的時候,將訓練數據分紅不少個 Min-Batches,對每一個 Min-Batches 的選取就是選取到 $ \tau$ 個單詞的時候,用來表示這個字典,而後在訓練的時候用這種數據會大大下降在 SoftMax 階段的計算量。咱們假設每次訓練集的目標單詞,也就是 Min-Batches 部分的單詞,構成集合 \(V_{i}^{\prime}\),那麼這個集合中每一個單詞的機率就是:
\[ Q_{i}\left(y_{k}\right)=\left\{\begin{array}{ll}{\frac{1}{\left|V_{i}^{\prime}\right|}} & {\text { if } y_{t} \in V_{i}^{\prime}} \\ {0} & {\text { otherwise }}\end{array}\right. \]
基於單詞的模型,能夠選取出現機率最高的 n-gram 框,而後將這個框不斷地加到數據集中去。
簡單說下這兩種方式的混合策略,
混合策略中,首先是對於單詞的預測,使用常規的 LSTM,可是遇到輸出的單詞是 <UNK> 的時候,咱們就須要使用字母級上的神經網絡了。