機(jī)器翻譯(machine translation, MT)是用計(jì)算機(jī)來(lái)實(shí)現(xiàn)不同語(yǔ)言之間翻譯的技術(shù)。被翻譯的語(yǔ)言通常稱(chēng)為源語(yǔ)言(source language),翻譯成的結(jié)果語(yǔ)言稱(chēng)為目標(biāo)語(yǔ)言(target language)。機(jī)器翻譯即實(shí)現(xiàn)從源語(yǔ)言到目標(biāo)語(yǔ)言轉(zhuǎn)換的過(guò)程,是自然語(yǔ)言處理的重要研究領(lǐng)域之一。 早期機(jī)器翻譯系統(tǒng)多為基于規(guī)則的翻譯系統(tǒng),需要由語(yǔ)言學(xué)家編寫(xiě)兩種語(yǔ)言之間的轉(zhuǎn)換規(guī)則,再將這些規(guī)則錄入計(jì)算機(jī)。該方法對(duì)語(yǔ)言學(xué)家的要求非常高,而且我們幾乎無(wú)法總結(jié)一門(mén)語(yǔ)言會(huì)用到的所有規(guī)則,更何況兩種甚至更多的語(yǔ)言。因此,傳統(tǒng)機(jī)器翻譯方法面臨的主要挑戰(zhàn)是無(wú)法得到一個(gè)完備的規(guī)則集合[1]。 為解決以上問(wèn)題,統(tǒng)計(jì)機(jī)器翻譯(Statistical Machine Translation, SMT)技術(shù)應(yīng)運(yùn)而生。在統(tǒng)計(jì)機(jī)器翻譯技術(shù)中,轉(zhuǎn)化規(guī)則是由機(jī)器自動(dòng)從大規(guī)模的語(yǔ)料中學(xué)習(xí)得到的,而非我們?nèi)酥鲃?dòng)提供規(guī)則。因此,它克服了基于規(guī)則的翻譯系統(tǒng)所面臨的知識(shí)獲取瓶頸的問(wèn)題,但仍然存在許多挑戰(zhàn):1)人為設(shè)計(jì)許多特征(feature),但永遠(yuǎn)無(wú)法覆蓋所有的語(yǔ)言現(xiàn)象;2)難以利用全局的特征;3)依賴(lài)于許多預(yù)處理環(huán)節(jié),如詞語(yǔ)對(duì)齊、分詞或符號(hào)化(tokenization)、規(guī)則抽取、句法分析等,而每個(gè)環(huán)節(jié)的錯(cuò)誤會(huì)逐步累積,對(duì)翻譯的影響也越來(lái)越大。 近年來(lái),深度學(xué)習(xí)技術(shù)的發(fā)展為解決上述挑戰(zhàn)提供了新的思路。將深度學(xué)習(xí)應(yīng)用于機(jī)器翻譯任務(wù)的方法大致分為兩類(lèi):1)仍以統(tǒng)計(jì)機(jī)器翻譯系統(tǒng)為框架,只是利用神經(jīng)網(wǎng)絡(luò)來(lái)改進(jìn)其中的關(guān)鍵模塊,如語(yǔ)言模型、調(diào)序模型等(見(jiàn)圖1的左半部分);2)不再以統(tǒng)計(jì)機(jī)器翻譯系統(tǒng)為框架,而是直接用神經(jīng)網(wǎng)絡(luò)將源語(yǔ)言映射到目標(biāo)語(yǔ)言,即端到端的神經(jīng)網(wǎng)絡(luò)機(jī)器翻譯(End-to-End Neural Machine Translation, End-to-End NMT)(見(jiàn)圖1的右半部分),簡(jiǎn)稱(chēng)為NMT模型。
本教程主要介紹NMT模型,以及如何用PaddlePaddle來(lái)訓(xùn)練一個(gè)NMT模型。 效果展示以中英翻譯(中文翻譯到英文)的模型為例,當(dāng)模型訓(xùn)練完畢時(shí),如果輸入如下已分詞的中文句子: 這些 是 希望 的 曙光 和 解脫 的 跡象 . 0 -5.36816 These are signs of hope and relief . <e> 1 -6.23177 These are the light of hope and relief . <e> 2 -7.7914 These are the light of hope and the relief of hope . <e> <e> 表示句子的結(jié)尾,<unk> 表示未登錄詞(unknown word),即未在訓(xùn)練字典中出現(xiàn)的詞。
模型概覽本節(jié)依次介紹GRU(Gated Recurrent Unit,門(mén)控循環(huán)單元),雙向循環(huán)神經(jīng)網(wǎng)絡(luò)(Bi-directional Recurrent Neural Network),NMT模型中典型的編碼器-解碼器(Encoder-Decoder)框架和注意力(Attention)機(jī)制,以及柱搜索(beam search)算法。 GRU我們已經(jīng)在情感分析一章中介紹了循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)及長(zhǎng)短時(shí)間記憶網(wǎng)絡(luò)(LSTM)。相比于簡(jiǎn)單的RNN,LSTM增加了記憶單元(memory cell)、輸入門(mén)(input gate)、遺忘門(mén)(forget gate)及輸出門(mén)(output gate),這些門(mén)及記憶單元組合起來(lái)大大提升了RNN處理遠(yuǎn)距離依賴(lài)問(wèn)題的能力。 GRU[2]是Cho等人在LSTM上提出的簡(jiǎn)化版本,也是RNN的一種擴(kuò)展,如下圖所示。GRU單元只有兩個(gè)門(mén): - 重置門(mén)(reset gate):如果重置門(mén)關(guān)閉,會(huì)忽略掉歷史信息,即歷史不相干的信息不會(huì)影響未來(lái)的輸出。 - 更新門(mén)(update gate):將LSTM的輸入門(mén)和遺忘門(mén)合并,用于控制歷史信息對(duì)當(dāng)前時(shí)刻隱層輸出的影響。如果更新門(mén)接近1,會(huì)把歷史信息傳遞下去。
一般來(lái)說(shuō),具有短距離依賴(lài)屬性的序列,其重置門(mén)比較活躍;相反,具有長(zhǎng)距離依賴(lài)屬性的序列,其更新門(mén)比較活躍。另外,Chung等人[3]通過(guò)多組實(shí)驗(yàn)表明,GRU雖然參數(shù)更少,但是在多個(gè)任務(wù)上都和LSTM有相近的表現(xiàn)。 雙向循環(huán)神經(jīng)網(wǎng)絡(luò)我們已經(jīng)在語(yǔ)義角色標(biāo)注一章中介紹了一種雙向循環(huán)神經(jīng)網(wǎng)絡(luò),這里介紹Bengio團(tuán)隊(duì)在論文[2,4]中提出的另一種結(jié)構(gòu)。該結(jié)構(gòu)的目的是輸入一個(gè)序列,得到其在每個(gè)時(shí)刻的特征表示,即輸出的每個(gè)時(shí)刻都用定長(zhǎng)向量表示到該時(shí)刻的上下文語(yǔ)義信息。 具體來(lái)說(shuō),該雙向循環(huán)神經(jīng)網(wǎng)絡(luò)分別在時(shí)間維以順序和逆序——即前向(forward)和后向(backward)——依次處理輸入序列,并將每個(gè)時(shí)間步RNN的輸出拼接成為最終的輸出層。這樣每個(gè)時(shí)間步的輸出節(jié)點(diǎn),都包含了輸入序列中當(dāng)前時(shí)刻完整的過(guò)去和未來(lái)的上下文信息。下圖展示的是一個(gè)按時(shí)間步展開(kāi)的雙向循環(huán)神經(jīng)網(wǎng)絡(luò)。該網(wǎng)絡(luò)包含一個(gè)前向和一個(gè)后向RNN,其中有六個(gè)權(quán)重矩陣:輸入到前向隱層和后向隱層的權(quán)重矩陣(W1,W3),隱層到隱層自己的權(quán)重矩陣(W2,W5),前向隱層和后向隱層到輸出層的權(quán)重矩陣(W4,W6)。注意,該網(wǎng)絡(luò)的前向隱層和后向隱層之間沒(méi)有連接。
編碼器-解碼器框架編碼器-解碼器(Encoder-Decoder)[2]框架用于解決由一個(gè)任意長(zhǎng)度的源序列到另一個(gè)任意長(zhǎng)度的目標(biāo)序列的變換問(wèn)題。即編碼階段將整個(gè)源序列編碼成一個(gè)向量,解碼階段通過(guò)最大化預(yù)測(cè)序列概率,從中解碼出整個(gè)目標(biāo)序列。編碼和解碼的過(guò)程通常都使用RNN實(shí)現(xiàn)。
編碼器編碼階段分為三步:
第3步也可以使用雙向循環(huán)神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)更復(fù)雜的句編碼表示,具體可以用雙向GRU實(shí)現(xiàn)。前向GRU按照詞序列(x1,x2,...,xT)的順序依次編碼源語(yǔ)言端詞,并得到一系列隱層狀態(tài)(→h1,→h2,...,→hT)。類(lèi)似的,后向GRU按照(xT,xT?1,...,x1)的順序依次編碼源語(yǔ)言端詞,得到(←h1,←h2,...,←hT)。最后對(duì)于詞xi,通過(guò)拼接兩個(gè)GRU的結(jié)果得到它的隱層狀態(tài),即hi=[→hTi,←hTi]T。
解碼器機(jī)器翻譯任務(wù)的訓(xùn)練過(guò)程中,解碼階段的目標(biāo)是最大化下一個(gè)正確的目標(biāo)語(yǔ)言詞的概率。思路是:
zi+1=?θ′(c,ui,zi)
其中?θ′是一個(gè)非線性激活函數(shù);c=qh是源語(yǔ)言句子的上下文向量,在不使用注意力機(jī)制時(shí),如果編碼器的輸出是源語(yǔ)言句子編碼后的最后一個(gè)元素,則可以定義c=hT;ui是目標(biāo)語(yǔ)言序列的第i個(gè)單詞,u0是目標(biāo)語(yǔ)言序列的開(kāi)始標(biāo)記
p(ui+1|u<i+1,x)=softmax(Wszi+1+bz)
其中Wszi+1+bz是對(duì)每個(gè)可能的輸出單詞進(jìn)行打分,再用softmax歸一化就可以得到第i+1個(gè)詞的概率pi+1。
機(jī)器翻譯任務(wù)的生成過(guò)程,通俗來(lái)講就是根據(jù)預(yù)先訓(xùn)練的模型來(lái)翻譯源語(yǔ)言句子。生成過(guò)程中的解碼階段和上述訓(xùn)練過(guò)程的有所差異,具體介紹請(qǐng)見(jiàn)柱搜索算法。 注意力機(jī)制如果編碼階段的輸出是一個(gè)固定維度的向量,會(huì)帶來(lái)以下兩個(gè)問(wèn)題:1)不論源語(yǔ)言序列的長(zhǎng)度是5個(gè)詞還是50個(gè)詞,如果都用固定維度的向量去編碼其中的語(yǔ)義和句法結(jié)構(gòu)信息,對(duì)模型來(lái)說(shuō)是一個(gè)非常高的要求,特別是對(duì)長(zhǎng)句子序列而言;2)直覺(jué)上,當(dāng)人類(lèi)翻譯一句話時(shí),會(huì)對(duì)與當(dāng)前譯文更相關(guān)的源語(yǔ)言片段上給予更多關(guān)注,且關(guān)注點(diǎn)會(huì)隨著翻譯的進(jìn)行而改變。而固定維度的向量則相當(dāng)于,任何時(shí)刻都對(duì)源語(yǔ)言所有信息給予了同等程度的關(guān)注,這是不合理的。因此,Bahdanau等人[4]引入注意力(attention)機(jī)制,可以對(duì)編碼后的上下文片段進(jìn)行解碼,以此來(lái)解決長(zhǎng)句子的特征學(xué)習(xí)問(wèn)題。下面介紹在注意力機(jī)制下的解碼器結(jié)構(gòu)。 與簡(jiǎn)單的解碼器不同,這里zi的計(jì)算公式為: zi+1=?θ′(ci,ui,zi)
可見(jiàn),源語(yǔ)言句子的編碼向量表示為第i個(gè)詞的上下文片段ci,即針對(duì)每一個(gè)目標(biāo)語(yǔ)言中的詞ui,都有一個(gè)特定的ci與之對(duì)應(yīng)。ci的計(jì)算公式如下: ci=T∑j=1aijhj,ai=[ai1,ai2,...,aiT]
從公式中可以看出,注意力機(jī)制是通過(guò)對(duì)編碼器中各時(shí)刻的RNN狀態(tài)hj進(jìn)行加權(quán)平均實(shí)現(xiàn)的。權(quán)重aij表示目標(biāo)語(yǔ)言中第i個(gè)詞對(duì)源語(yǔ)言中第j個(gè)詞的注意力大小,aij的計(jì)算公式如下: begin{align} a_{ij}&=frac{exp(e_{ij})}{sum_{k=1}^{T}exp(e_{ik})}\e_{ij}&=align(z_i,h_j)\end{align} 其中,align可以看作是一個(gè)對(duì)齊模型,用來(lái)衡量目標(biāo)語(yǔ)言中第i個(gè)詞和源語(yǔ)言中第j個(gè)詞的匹配程度。具體而言,這個(gè)程度是通過(guò)解碼RNN的第i個(gè)隱層狀態(tài)zi和源語(yǔ)言句子的第j個(gè)上下文片段hj計(jì)算得到的。傳統(tǒng)的對(duì)齊模型中,目標(biāo)語(yǔ)言的每個(gè)詞明確對(duì)應(yīng)源語(yǔ)言的一個(gè)或多個(gè)詞(hard alignment);而在注意力模型中采用的是soft alignment,即任何兩個(gè)目標(biāo)語(yǔ)言和源語(yǔ)言詞間均存在一定的關(guān)聯(lián),且這個(gè)關(guān)聯(lián)強(qiáng)度是由模型計(jì)算得到的實(shí)數(shù),因此可以融入整個(gè)NMT框架,并通過(guò)反向傳播算法進(jìn)行訓(xùn)練。
柱搜索算法柱搜索(beam search)是一種啟發(fā)式圖搜索算法,用于在圖或樹(shù)中搜索有限集合中的最優(yōu)擴(kuò)展節(jié)點(diǎn),通常用在解空間非常大的系統(tǒng)(如機(jī)器翻譯、語(yǔ)音識(shí)別)中,原因是內(nèi)存無(wú)法裝下圖或樹(shù)中所有展開(kāi)的解。如在機(jī)器翻譯任務(wù)中希望翻譯“ 柱搜索算法使用廣度優(yōu)先策略建立搜索樹(shù),在樹(shù)的每一層,按照啟發(fā)代價(jià)(heuristic cost)(本教程中,為生成詞的log概率之和)對(duì)節(jié)點(diǎn)進(jìn)行排序,然后僅留下預(yù)先確定的個(gè)數(shù)(文獻(xiàn)中通常稱(chēng)為beam width、beam size、柱寬度等)的節(jié)點(diǎn)。只有這些節(jié)點(diǎn)會(huì)在下一層繼續(xù)擴(kuò)展,其他節(jié)點(diǎn)就被剪掉了,也就是說(shuō)保留了質(zhì)量較高的節(jié)點(diǎn),剪枝了質(zhì)量較差的節(jié)點(diǎn)。因此,搜索所占用的空間和時(shí)間大幅減少,但缺點(diǎn)是無(wú)法保證一定獲得最優(yōu)解。 使用柱搜索算法的解碼階段,目標(biāo)是最大化生成序列的概率。思路是:
注意:zi+1和pi+1的計(jì)算公式同解碼器中的一樣。且由于生成時(shí)的每一步都是通過(guò)貪心法實(shí)現(xiàn)的,因此并不能保證得到全局最優(yōu)解。 數(shù)據(jù)介紹本教程使用WMT-14數(shù)據(jù)集中的bitexts(after selection)作為訓(xùn)練集,dev+test data作為測(cè)試集和生成集。 數(shù)據(jù)預(yù)處理我們的預(yù)處理流程包括兩步:
- 將每個(gè)源語(yǔ)言到目標(biāo)語(yǔ)言的平行語(yǔ)料庫(kù)文件合并為一個(gè)文件:
- 合并每個(gè) 示例數(shù)據(jù)因?yàn)橥暾臄?shù)據(jù)集數(shù)據(jù)量較大,為了驗(yàn)證訓(xùn)練流程,PaddlePaddle接口paddle.dataset.wmt14中默認(rèn)提供了一個(gè)經(jīng)過(guò)預(yù)處理的較小規(guī)模的數(shù)據(jù)集。 該數(shù)據(jù)集有193319條訓(xùn)練數(shù)據(jù),6003條測(cè)試數(shù)據(jù),詞典長(zhǎng)度為30000。因?yàn)閿?shù)據(jù)規(guī)模限制,使用該數(shù)據(jù)集訓(xùn)練出來(lái)的模型效果無(wú)法保證。 流程說(shuō)明paddle初始化# 加載 paddle的python包 import sys import paddle.v2 as paddle # 配置只使用cpu,并且使用一個(gè)cpu進(jìn)行訓(xùn)練 paddle.init(use_gpu=False, trainer_count=1) # 訓(xùn)練模式False,生成模式True is_generating = False 模型結(jié)構(gòu)
src_word_id = paddle.layer.data( name='source_language_word', type=paddle.data_type.integer_value_sequence(source_dict_dim)) src_embedding = paddle.layer.embedding( input=src_word_id, size=word_vector_dim) src_forward = paddle.networks.simple_gru( input=src_embedding, size=encoder_size) src_backward = paddle.networks.simple_gru( input=src_embedding, size=encoder_size, reverse=True) encoded_vector = paddle.layer.concat(input=[src_forward, src_backward])
encoded_proj = paddle.layer.fc( act=paddle.activation.Linear(), size=decoder_size, bias_attr=False, input=encoded_vector)
backward_first = paddle.layer.first_seq(input=src_backward) decoder_boot = paddle.layer.fc( size=decoder_size, act=paddle.activation.Tanh(), bias_attr=False, input=backward_first)
def gru_decoder_with_attention(enc_vec, enc_proj, current_word): decoder_mem = paddle.layer.memory( name='gru_decoder', size=decoder_size, boot_layer=decoder_boot) context = paddle.networks.simple_attention( encoded_sequence=enc_vec, encoded_proj=enc_proj, decoder_state=decoder_mem) decoder_inputs = paddle.layer.fc( act=paddle.activation.Linear(), size=decoder_size * 3, bias_attr=False, input=[context, current_word], layer_attr=paddle.attr.ExtraLayerAttribute( error_clipping_threshold=100.0)) gru_step = paddle.layer.gru_step( name='gru_decoder', input=decoder_inputs, output_mem=decoder_mem, size=decoder_size) out = paddle.layer.mixed( size=target_dict_dim, bias_attr=True, act=paddle.activation.Softmax(), input=paddle.layer.full_matrix_projection(input=gru_step)) return out
if not is_generating: trg_embedding = paddle.layer.embedding( input=paddle.layer.data( name='target_language_word', type=paddle.data_type.integer_value_sequence(target_dict_dim)), size=word_vector_dim, param_attr=paddle.attr.ParamAttr(name='_target_language_embedding')) group_inputs.append(trg_embedding) # For decoder equipped with attention mechanism, in training, # target embeding (the groudtruth) is the data input, # while encoded source sequence is accessed to as an unbounded memory. # Here, the StaticInput defines a read-only memory # for the recurrent_group. decoder = paddle.layer.recurrent_group( name=decoder_group_name, step=gru_decoder_with_attention, input=group_inputs) lbl = paddle.layer.data( name='target_language_next_word', type=paddle.data_type.integer_value_sequence(target_dict_dim)) cost = paddle.layer.classification_cost(input=decoder, label=lbl)
if is_generating: # In generation, the decoder predicts a next target word based on # the encoded source sequence and the previous generated target word. # The encoded source sequence (encoder's output) must be specified by # StaticInput, which is a read-only memory. # Embedding of the previous generated word is automatically retrieved # by GeneratedInputs initialized by a start mark <s>. trg_embedding = paddle.layer.GeneratedInput( size=target_dict_dim, embedding_name='_target_language_embedding', embedding_size=word_vector_dim) group_inputs.append(trg_embedding) beam_gen = paddle.layer.beam_search( name=decoder_group_name, step=gru_decoder_with_attention, input=group_inputs, bos_id=0, eos_id=1, beam_size=beam_size, max_length=max_length) 注意:我們提供的配置在Bahdanau的論文[4]上做了一些簡(jiǎn)化,可參考issue #1133。 訓(xùn)練模型
訓(xùn)練開(kāi)始后,可以觀察到event_handler輸出的日志如下: Pass 0, Batch 0, Cost 148.444983, {'classification_error_evaluator': 1.0} ......... Pass 0, Batch 10, Cost 335.896802, {'classification_error_evaluator': 0.9325153231620789} ......... 生成模型
生成開(kāi)始后,可以觀察到輸出的日志如下: Les <unk> se <unk> au sujet de la largeur des sièges alors que de grosses commandes sont en jeu -19.0196 The <unk> will be rotated about the width of the seats , while large orders are at stake . <e> -19.1131 The <unk> will be rotated about the width of the seats , while large commands are at stake . <e> -19.5129 The <unk> will be rotated about the width of the seats , while large commands are at play . <e> 總結(jié)端到端的神經(jīng)網(wǎng)絡(luò)機(jī)器翻譯是近幾年興起的一種全新的機(jī)器翻譯方法。本章中,我們介紹了NMT中典型的“編碼器-解碼器”框架和“注意力”機(jī)制。由于NMT是一個(gè)典型的Seq2Seq(Sequence to Sequence,序列到序列)學(xué)習(xí)問(wèn)題,因此,Seq2Seq中的query改寫(xiě)(query rewriting)、摘要、單輪對(duì)話等問(wèn)題都可以用本教程的模型來(lái)解決。 |
|
來(lái)自: 冬城溪酒之秦文 > 《待分類(lèi)》