編者按:Mac Brennan詳細講解了用于機器翻譯的編碼器-解碼器架構。
概要
本文將講解如何創建、訓練一個法翻英的神經翻譯模型。本文的重點是解釋概念,具體的項目代碼請參考配套的Jupyter notebook(鏈接見文末)。
這篇文章大致分成兩部分:
理解模型概念
簡短總結模型表現
這篇文章參考了PyTorch序列到序列教程,不過試圖更深入一點。感謝Sean Robertsan和PyTorch提供了這么棒的教程。
理解模型
編碼器-解碼器網絡是一個很成功的翻譯模型。這個模型接受一個序列作為輸入,并將序列中的信息編碼為中間表示。然后解碼器解碼中間表示為目標語言。在我們的這個項目中,輸入序列是法語句子,輸出是相應的英語翻譯。
在我們深入編碼器和解碼器如何工作之前,我們需要了解下模型是如何表示我們的數據的。在對模型的工作機制一無所知的情況下,我們可以合理地推測如果我們給模型一個法語句子,模型能給我們對應的英語句子。也就是說,輸入一個單詞序列,模型應該輸出另一個單詞序列。然而,模型只不過是一組參數,在輸入上進行多種運算。模型并不知道什么是單詞。類似ASCII編碼將字母映射到數字,我們的單詞也需要轉成數值表是。為此,數據集中的每個唯一的單詞需要有一個唯一的索引。模型接受的實際上不是一個單詞序列,而是一個索引序列。
一次傳入一個句子,這沒什么問題。不過,怎樣才能一次傳入多個句子以加速訓練過程呢?句子長短不一。這些數字序列又該如何組織呢?答案是輸入序列將表示為維度等于(batch大小 × 最大句子長度)的張量(矩陣)。這樣就可以一次輸入一組句子,短于數據集中最長句的句子可以用事先確定的“補齊索引”補齊。如下圖所示:
編碼器
詞嵌入
輸入張量讓我們能夠以索引序列的形式輸入多個句子。這個方向是對的,但這些索引并沒有保留什么信息。索引54代表的單詞,和索引55代表的單詞可能全無關系。基于這些索引數字進行計算沒什么意義。這些索引需要以其他格式表示,讓模型可以計算一些有意義的東西。一種更好的表示單詞的方法是詞嵌入。
詞嵌入用N維向量表示每個單詞。相似單詞具有相似詞嵌入,在N維嵌入空間中距離相近。詞嵌入基于在某種語言任務上訓練的模型得到。幸運的是,其他研究人員已經完成了這項工作,同時發布了相關成果。我們的項目使用的是FastText的300維詞嵌入。
將輸入句子表示為詞嵌入序列后,可以傳入編碼器的循環層。
編碼器架構
上述嵌入過程通過一個嵌入層完成。整個編碼器的架構如下圖所示。
從上圖我們可以看到,輸入張量通過嵌入層之后,到達雙向RNN層。雙向RNN既從前往后處理序列,又從后往前處理序列。從后往前處理序列時,已經看過整個序列。
獲取嵌入輸入張量后,RNN逐步處理序列中的每一項(單詞)。在每次迭代中,輸出一個長度等于編碼器隱藏尺寸的編碼向量。RNN并行處理批次中的每個樣本。每一步的輸出可以看成一個大小為(batch大小 × 編碼向量大小)的矩陣,不過實際上整個RNN所有步驟輸出一個最終張量。
在處理序列的每一步中,RNN的隱藏狀態傳給接受序列下一項作為輸入的RNN的下一次迭代。迭代同時為批次中的每個樣本輸出一個編碼向量。序列處理的每一步都輸出這樣一個“矩陣”,并與相應的反向處理序列的RNN步驟輸出的矩陣相連接。在我們的項目中,RNN單元使用了兩個循環層,中間隔著一個dropout層。另外,我們比較了兩種不同的RNN:LSTM(長短時記憶網絡)和GRU(門控循環單元)。
RNN層的最終輸出是一個張量,其中每步的“矩陣”輸出堆疊在一起,如下圖所示。
解碼器
編碼器的最終隱藏狀態可以傳給另一個RNN(解碼器)。該RNN的每個輸出都是輸出序列中的一個單詞,并作為RNN下一步的輸入。然而,這樣的架構需要編碼器編碼整個輸入序列為最終隱藏狀態。相反,如果使用注意力模型,解碼器不僅接受最終隱藏狀態作為輸入,還接受編碼器處理輸入序列的每一步的輸出作為輸入。編碼器可以賦予編碼器輸出不同的權重,在計算解碼器輸出序列的每次迭代中使用。
解碼器循環層的最終輸入為注意力加權的編碼器輸出和循環單元前一步的預測單詞索引。下為這一過程的示意圖,其中“Context”(上下文)表示編碼器輸出張量。為了簡化圖形,示意圖中省略了嵌入層。
下面讓我們詳細討論下注意力模塊加權編碼器權重的方式。
注意力
回顧下編碼器輸出張量,序列維度的每一項保存了RNN輸出的向量。注意力模塊就批次中的每個樣本在序列維度上取這些向量的加權和。這樣,每個樣本得到一個向量,表示當前輸出序列步驟計算所需的相關信息。
下面我們將舉一個具體的例子。如果輸入句子的第一個單詞包含了給定輸出單詞所需的所有最重要的信息,那么第一個單詞分配的權重是一,其他各項權重為零。也就是加權向量等于輸入句子的第一個單詞對應的向量。
模型需要學習如何分配這些權重,所以我們使用了一個全連接層。序列中的每個單詞對應一個權重,所以權重數量等于最長句子長度。權重之和應等于一,所以全連接層將使用softmax激活函數。注意力模塊將接受解碼器先前的隱藏狀態與解碼器前一步輸出的預測單詞的詞嵌入的連接作為輸入,從而決定這些權重的值。下為這一過程的示意圖。
計算出這些權重之后,就批次中的每個樣本,對權重和編碼器輸出應用矩陣乘法,得到整個序列的編碼向量的加權和。表示批次中每個樣本的編碼器輸出的矩陣,可以看成編碼器張量的一個水平切片。下為單個樣本的計算過程示意圖。實際運算時堆疊批次中的每個樣本以構成維度為(batch大小 × 2 × 編碼器隱藏向量)的矩陣,得到加權編碼器輸出。
循環計算
編碼器輸出經注意力模塊加權后,可以傳給解碼器的RNN層了。RNN層同時接受解碼器上一步預測的單詞的詞嵌入作為輸入。RNN不直接接受這兩個矩陣的連接作為輸入,它們在此之前還需通過一個使用ReLU激活的全連接層。這一層的輸出作為RNN的輸入。
RNN的輸出傳給一個全連接層,該全連接層使用對數softmax激活,節點數等于輸出語言的詞匯量。這一層的輸出表示對輸出序列中的下一個單詞的預測。這個單詞和RNN的隱藏狀態傳至注意力模塊和RNN的下一步,用來計算序列的下一項。下為這一過程的示意圖。不斷重復這一過程,直到整個輸出序列輸出完畢。
訓練模型
為訓練模型,我們需要計算一個損失函數,反向傳播誤差以更新模型參數。我們的模型計算的損失函數為輸出預測和目標翻譯之前的負對數似然,在序列上累加,在批次中取均值。在整個數據集上重復這一過程,經過足夠多的epoch后達到要求的結果。
然而,訓練語言模型要稍微復雜一點。因為解碼器依賴序列前面的項預測后面的項,較早的誤差會帶偏整個序列。這使得模型學習起來很困難。為了解決這一問題,我們使用了一種稱為教師強制(teacher forcing)的技術。這一技術的思路是某些批次(通常是隨機選擇半數)不將解碼器前一步的預測傳給下一步,而是將前一步的目標翻譯傳給下一步。應用教師強制時,解碼器每一步的計算使用的是正確的前序單詞。這一技術大大降低了訓練模型的難度。
創建和訓練模型的細節參見配套的Jupyter notebook(鏈接見文末)。下面簡短地總結下模型的表現。
數據集
我們使用了兩個數據集。第一個數據集相對簡單,詞匯量較低,句式看起來也不怎么多樣。不過,它倒是有一個優勢,訓練起來相對較快。第二個數據集更加多樣化,盡管句長較短,但詞匯量較高,句式也更加多樣。
簡單數據集
樣本數:137861
法語詞匯量:356
英語詞匯量:228
最長法語句長度:23個單詞
最長英語句長度:17個單詞
樣本示例:
法語句 paris est jamais agréable en décembre , et il est relaxant au mois d' ao?t .
英語句 paris is never nice during december , and it is relaxing in august .
法語句 elle déteste les pommes , les citrons verts et les citrons .
英語句 she dislikes apples , limes , and lemons .
法語句 la france est généralement calme en février , mais il est généralement chaud en avril .
英語句 france is usually quiet during february , but it is usually hot in april .
法語句 la souris était mon animal préféré moins .
英語句 the mouse was my least favorite animal .
法語句 paris est parfois clémentes en septembre , et il gèle habituellement en ao?t .
英語句 paris is sometimes mild during september , and it is usually freezing in august .
多樣化數據集
樣本數:139692
法語詞匯量:25809
英語詞匯量:12603
最長法語句長度:10個單詞
最長英語句長度:10個單詞
法語句 je vais laver les plats
英語句 ill wash dishes
法語句 les nouvelles les rendirent heureux
英語句 the news made them happy
法語句 globalement la conférence internationale fut un succès
英語句 all in all the international conference was a success
法語句 comment marche cet appareil photo
英語句 how do you usethis camera
法語句 cest ton jour de chance
英語句 thisis your lucky day
損失圖形
如前所述,我們分別實現了雙向LSTM和雙向GRU。
在第一個數據集上訓練一個epoch后的損失圖形如下:
在第二個數據集上訓練50個epoch后的損失圖形如下:
翻譯樣本和注意力可視化
翻譯樣本:簡單數據集
如上一節所示,在簡單數據集上訓練一個epoch后,LSTM和GRU都能非常精準地生成正確翻譯。然而,模型在翻譯句子時看起來并沒有用到注意力機制。下面是3個翻譯示例,以及相應的輸出序列的注意力權重。從這些例子來看,注意力權重說不上隨機,但也沒有落在我們期望的單詞上。
示例一
輸入句
californie est sec en janvier , mais il est généralement occupé en mars .
輸出句
california is dry during january , but it is usually busy in march .
LSTM模型輸出
california is dry during january , but it is usually busy in march .
GRU模型輸出
california is dry during january , but it is usually busy in march .
示例二
輸入句
new jersey est généralement chaud en juin , et il est parfois merveilleux en hiver .
輸出句
new jersey is usually hot during june , and it is sometimes wonderful in winter .
LSTM模型輸出
new jersey is usually warm during june , and it is sometimes wonderful in winter .
GRU模型輸出
new jersey is usually hot during june , and it is sometimes wonderful in winter .
示例三
輸入句
輸出句
i like strawberries , mangoes , and grapefruit .
LSTM模型輸出
i like strawberries , mangoes , and grapefruit .
GRU模型輸出
i like strawberries , mangoes , and grapefruit .
翻譯樣本:多樣化數據集
我們的模型能夠正確翻譯更加多樣化的句子。不過,這需要長很多的時間訓練,總共花了50個epoch才得到看起來合理的結果。下面顯示了其中幾個示例。GRU模型的注意力權重開始揭示模型使用了注意力機制,但LSTM模型看起來仍然沒有學習利用注意力機制。這可能是因為LSTM可以訪問保存了長期依賴的單元狀態。也許注意力計算沒能為模型提供足夠有用的信息,使模型優先學習更好的注意力計算的參數。
示例一
輸入句
jai perdu mon intérêt pour le golf
輸出句
ive lost interest in golf
LSTM模型輸出
i lost my interest golf
GRU模型輸出
ive lost interest in golf
示例二
輸入句
le livre était meilleur que le film
輸出句
the book was better than the movie
LSTM模型輸出
the book was better than the movie
GRU模型輸出
the book was better than the movie
示例三
輸入句
quel genre de trucs
輸出句
what sort of things do you do on weekends
LSTM模型輸出
what sort of things do you do on weekends
GRU模型輸出
what sort of stuff do you do on weekends
結語
GRU模型演示了注意力計算讓模型重點關注編碼序列的不同部分。然而,我們并不清楚為什么LSTM看起來要么沒有利用注意力信息,要么基于一種不同的方式使用注意力信息。如果有更多時間,我們想調查下這是為什么。如果使用句長更長的數據集還會這樣嗎?還可以和不帶注意力機制的簡單編碼器-解碼器網絡比較一下,看看表現是否優于不帶注意力機制的架構,如果優于不帶注意力機制的架構,那么是在哪些情況下?
我們選擇的架構和PyTorch教程中的模型略有不同。這個項目使用的模型使用了batching,而原教程中的模型每次處理一個序列。因此,原模型不必處理輸出補齊。我們本來覺得batching可以通過并行化縮短訓練時間,但原模型聲稱只需大約40分鐘就可以在CPU上完成訓練,而這個項目所用的模型在GPU上訓練了將近12小時,才得到良好的翻譯。
一些改進也許可以彌合這一差異。首先,PyTorch有內置的處理補齊序列的函數,這樣循環單元不會看到補齊項。這可能提高模型的學習能力。其次,第二個數據集沒有處理成token,只是直接移除了標點。這可能導致轉換單詞為索引時,一些單詞無法辨識。這意味著它們會被替換為未知token,使模型更難識別句子的內容。盡管還有提升的空間,總體上而言這個項目是成功的,因為它能夠成功地翻譯法語為英語。
-
解碼器
+關注
關注
9文章
1131瀏覽量
40684 -
編碼器
+關注
關注
45文章
3601瀏覽量
134205 -
機器翻譯
+關注
關注
0文章
139瀏覽量
14873
原文標題:編碼器-解碼器網絡:神經翻譯模型詳解
文章出處:【微信號:jqr_AI,微信公眾號:論智】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論