App下載

Python實現(xiàn)簡單的機器翻譯模型

猿友 2018-08-06 18:36:35 瀏覽數(shù) (8433)
反饋

本文轉(zhuǎn)載至知乎ID:Charles(白露未晞)知乎個人專欄

下載W3Cschool手機App,0基礎隨時隨地學編程>>戳此了解

導語

好幾天沒推文的罪惡感讓我決定今天來水一篇文章。

和之前“Python玩CartPole”那篇推文一樣,這也是來自于PyTorch官方教程的一個簡單實例。

為了展示我的誠意,我依舊會由淺入深地講解本文使用到的基本模型:Seq2Seq以及Attention機制。

內(nèi)容依舊會很長~~~

希望對初入NLP/DeepLearning的童鞋有所幫助~

廢話不多說,直接進入正題~~~


相關文件

百度網(wǎng)盤下載鏈接: https://pan.baidu.com/s/1y3KcMboz_xZJ9Afh5nRkUw

密碼: qvhd


參考文獻

官方英文教程鏈接:

http://pytorch.org/tutorials/intermediate/seq2seq_translation_tutorial.html

另外:

對英文文獻閱讀有困難的同學也不必擔心,我已經(jīng)把這個教程翻譯為中文放到了相關文件中。

開發(fā)工具

系統(tǒng):Windows10

Python版本:3.6.4

相關模塊:

torch模塊;

numpy模塊;

matplotlib模塊;

以及一些Python自帶的模塊。

其中PyTorch版本為:

0.3.0


環(huán)境搭建

安裝Python并添加到環(huán)境變量,pip安裝需要的相關模塊即可。

補充說明:

PyTorch暫時不支持直接pip安裝。

有兩個選擇:

(1)安裝anaconda3后在anaconda3的環(huán)境下安裝(直接pip安裝即可);

(2)使用編譯好的whl文件安裝,下載鏈接為:

https://pan.baidu.com/s/1dF6ayLr#list/path=%2Fpytorch


原理介紹

PS:

部分內(nèi)容參考了相關網(wǎng)絡博客和書籍。

(1)單層網(wǎng)絡

單層網(wǎng)絡的結構類似下圖:

輸入的x經(jīng)過變換wx+b激活函數(shù)f得到輸出y。

相信對機器學習/深度學習有初步了解的同學都知道,這其實就是單層感知機嘛~~~

為了方便起見,我們把它畫成這樣(請忽視我拙劣的繪圖水平):

x為輸入向量,y為輸出向量,箭頭表示一次變換,也就是y=f(Wx+b)。

(2)經(jīng)典RNN

在實際中,我們會遇到很多序列形的數(shù)據(jù):

X1,X2,X3,X4...

例如我們的機器翻譯模型,X1可以看作是第一個單詞,X2可以看作是第二個單詞,以此類推。

原始的神經(jīng)網(wǎng)絡并不能很好地處理序列形的數(shù)據(jù),于是救世主RNN出現(xiàn)了,它引入了隱狀態(tài)h的概念,利用h對序列形的數(shù)據(jù)提取特征,接著再轉(zhuǎn)換為輸出。下面詳細說明一下其計算過程(下圖中的h0為初始隱藏狀態(tài),為簡單起見,我們假設它是根據(jù)具體模型而設置的一個合理值):

其中:

再重申一遍,所有的字母均為向量,箭頭代表對向量做一次變換。

h2的計算與h1類似,并且每一步使用的參數(shù)P、Q、b都是一樣的,也就是說每個步驟的參數(shù)共享:

其中:

以此類推(記住參數(shù)都是一樣的!?。?/span>),該計算可以無限地持續(xù)下去(不限于圖中的長度4?。?!)。

那么RNN的輸出又如何得到呢?

RNN的輸出值是通過h進行計算的:

其中:

類似地,有y2、y3、y4...:

當然,和前面一樣,這里的參數(shù)W和c也是共享的

以上就是最經(jīng)典的RNN結構,我們可以發(fā)現(xiàn)其存在一個致命的缺點:

輸入和輸出序列必須是等長的!

這個缺點導致了經(jīng)典RNN的適用范圍并沒有想象中的那么大。

(3)改進經(jīng)典RNN

情況1(輸入為N,輸出為1):

假設我們的問題要求我們輸入的是一個序列,輸出的是一個單獨的數(shù)值。那么我們只在最后一個h上進行輸出變換就可以了:

情況2(輸入為1,輸出為N):

當輸入只是單一數(shù)值而非序列時該怎么辦呢?

我們可以只在序列開始進行輸入計算:

當然你也可以把輸入信息x作為每個階段的輸入:

情況3(輸入為N,輸出為M):

這是RNN最重要的一個變種,這種結構也被稱為:

Encoder-Decoder模型,或者說Seq2Seq模型。

我們的機器翻譯模型就是以它為基礎的。

Seq2Seq結構先將輸入數(shù)據(jù)編碼成一個上下文量c

其中:

即上下文量c可以直接等于最后一個隱藏狀態(tài),也可以是對最后的隱藏狀態(tài)做一個變換V得到,當然也可以是對所有的隱藏狀態(tài)做一個變換V得到等等。

上述RNN結構一般稱為Encoder。

得到c之后,我們需要另外一個RNN網(wǎng)絡對其進行解碼操作,即Decoder。你可以把這個c當作初始狀態(tài)h'0輸入到Decoder中:

當然你也可以把c當作Decoder每一步的輸入:

算了,補充說明一下吧:

缺少輸入的部分(比如某些藍色的方塊沒有x輸入)你完全可以把x作為0處理然后再代入經(jīng)典RNN所列出的公式中計算輸出,其他的也類似。

(4)Attention機制

在Encoder-Decoder結構中,Encoder把所有的輸入序列都編碼成一個統(tǒng)一的語義特征c后再進行解碼,當輸入序列較長時,c很可能無法勝任存儲輸入序列所有信息的任務。

Attention機制很好地解決了上述問題。它在Decoder每一步輸入不同的c:

其中,c根據(jù)Encoder中的h生成:

aij代表Encoder中第j階段的hj和Decoder中第i階段的相關性。

那么這些權重aij該如何確定呢?aij自然也是從模型中學得的,我們一般認為它與Encoder的第j個階段的隱狀態(tài)和Decoder的第i-1階段的隱狀態(tài)有關。

比如我們要計算a1j:

然后我們需要計算a2j:

以此類推

(5)最后任務:法語翻譯成英語

有了前面的鋪墊,相信大家都能看懂官網(wǎng)的教程。

在這里我們僅做簡單的介紹,詳細的建模和實現(xiàn)過程可以參考我翻譯的官方文檔。

Encoder網(wǎng)絡為:

Decoder網(wǎng)絡為:

其中,encoder最后一個隱藏狀態(tài)作為decoder的初始隱藏狀態(tài)。attention機制的權重計算類似(4)中所述。GRU網(wǎng)絡的結構為:

GRU網(wǎng)絡結構在此就不作詳細的介紹了,篇幅太長的話估計沒人看得下去吧,就先這樣了~~~

在相關文件中我也提供了4篇相關的論文供感興趣者閱讀與研究。(T_T純英文的~~~)

結果展示

在cmd窗口運行Translation.py文件即可。

誤差曲線:

訓練過程中cmd窗口的輸出:

模型測試:

作為對比:

和最后一個測試結果一模一樣有木有?。?!

當然,有些翻譯結果就不怎么理想了。因為模型和訓練數(shù)據(jù)過于簡單了(T_T這里就不舉例了)~~~

最后四句話的attention圖:

That's all~~~


更多

感興趣的同學可以進一步修改模型來獲得更好的結果,當然也可以找找其他數(shù)據(jù)集制作諸如中翻英之類的模型~~~

0 人點贊