全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

中高端软件定制开发服务商

与我们取得联系

13245491521     13245491521

2018-07-08_教程 | 入门Python神经机器翻译,这是一篇非常精简的实战指南

您的位置:首页 >> 新闻 >> 行业资讯

教程 | 入门Python神经机器翻译,这是一篇非常精简的实战指南 选自Medium 作者:Susan Li 机器之心编译 参与:Huiyuan Zhuo、思源 机器翻译(MT)是一项极具挑战性的任务,其研究如何使用计算机将文本或是语音从一种语言翻译成另一种语言。本文借助 Keras 从最基本的文本加载与数据预处理开始,并讨论了在循环神经网络与编码器解码器框架下如何才能构建一个可接受的神经翻译系统,本教程所有的代码已在 GitHub 开源。 传统意义上来说,机器翻译一般使用高度复杂的语言知识开发出的大型统计模型,但是近来很多研究使用深度模型直接对翻译过程建模,并在只提供原语数据与译文数据的情况下自动学习必要的语言知识。这种基于深度神经网络的翻译模型目前已经获得了最佳效果。 项目地址:https://github.com/susanli2016/NLP-with-Python/blob/master/machine_translation.ipynb 接下来,我们将使用深度神经网络来解决机器翻译问题。我们将展示如何开发一个将英文翻译成法文的神经网络机器翻译模型。该模型将接收英文文本输入同时返回法语译文。更确切地说,我们将构建 4 个模型,它们是: 一个简单的 RNN; 一个带词嵌入的 RNN; 一个双向 RNN; 一个编码器—解码器模型。 训练和评估深度神经网络是一项计算密集型的任务。作者使用 AWS EC2 实例来运行所有代码。如果你打算照着本文做,你得访问 GPU 实例。 加载库 importcollections importhelper importnumpyasnp importproject_testsastests fromkeras.preprocessing.textimportTokenizer fromkeras.preprocessing.sequenceimportpad_sequences fromkeras.modelsimportModel fromkeras.layersimportGRU,Input,Dense,TimeDistributed,Activation,RepeatVector,Bidirectional fromkeras.layers.embeddingsimportEmbedding fromkeras.optimizersimportAdam fromkeras.lossesimportsparse_categorical_crossentropy 作者使用 help.py 加载数据,同时使用 project_test.py 测试函数。 数据 该数据集包含一个相对较小的词汇表,其中 small_vocab_en 文件包含英文语句,small_vocab_fr 包含对应的法文翻译。 数据集下载地址:https://github.com/susanli2016/NLP-with-Python/tree/master/data 加载数据 english_sentences=helper.load_data('data/small_vocab_en') french_sentences=helper.load_data('data/small_vocab_fr') print('DatasetLoaded') 语句样本 small_vocab_en 中的每行包含一个英文语句,同时其法文翻译位于 small_vocab_fr 中对应的每行。 forsample_iinrange(2): print('small_vocab_enLine{}:{}'.format(sample_i+1,english_sentences[sample_i])) print('small_vocab_frLine{}:{}'.format(sample_i+1,french_sentences[sample_i])) 词汇表 问题的复杂性取决于词汇表的复杂性。一个更复杂的词汇表意味着一个更复杂的问题。对于将要处理的数据集,让我们看看它的复杂性。 english_words_counter=collections.Counter([wordforsentenceinenglish_sentencesforwordinsentence.split()]) french_words_counter=collections.Counter([wordforsentenceinfrench_sentencesforwordinsentence.split()]) print('{}Englishwords.'.format(len([wordforsentenceinenglish_sentencesforwordinsentence.split()]))) print('{}uniqueEnglishwords.'.format(len(english_words_counter))) print('10MostcommonwordsintheEnglishdataset:') print('"'+'""'.join(list(zip(*english_words_counter.most_common(10)))[0])+'"') print() print('{}Frenchwords.'.format(len([wordforsentenceinfrench_sentencesforwordinsentence.split()]))) print('{}uniqueFrenchwords.'.format(len(french_words_counter))) print('10MostcommonwordsintheFrenchdataset:') print('"'+'""'.join(list(zip(*french_words_counter.most_common(10)))[0])+'"') 预处理 我们将使用以下预处理方法将文本转化为整数序列: 1. 将词转化为 id 表达; 2. 加入 padding 使得每个序列一样长。 Tokensize(标记字符串) 使用 Keras 的 Tokenizer 函数将每个语句转化为一个单词 id 的序列。使用该函数来标记化英文语句和法文语句。 函数 tokenize 返回标记化后的输入和类。 deftokenize(x): x_tk=Tokenizer(char_level=False) x_tk.fit_on_texts(x) returnx_tk.texts_to_sequences(x),x_tk text_sentences=[ 'Thequickbrownfoxjumpsoverthelazydog.', 'ByJove,myquickstudyoflexicographywonaprize.', 'Thisisashortsentence.'] text_tokenized,text_tokenizer=tokenize(text_sentences) print(text_tokenizer.word_index) print() forsample_i,(sent,token_sent)inenumerate(zip(text_sentences,text_tokenized)): print('Sequence{}inx'.format(sample_i+1)) print('Input:{}'.format(sent)) print('Output:{}'.format(token_sent)) Padding 通过使用 Keras 的 pad_sequences 函数在每个序列最后添加零以使得所有英文序列具有相同长度,所有法文序列具有相同长度。 defpad(x,length=None): iflengthisNone: length=max([len(sentence)forsentenceinx]) returnpad_sequences(x,maxlen=length,padding='post') tests.test_pad(pad) #PadTokenizedoutput test_pad=pad(text_tokenized) forsample_i,(token_sent,pad_sent)inenumerate(zip(text_tokenized,test_pad)): print('Sequence{}inx'.format(sample_i+1)) print('Input:{}'.format(np.array(token_sent))) print('Output:{}'.format(pad_sent)) 预处理流程 实现预处理函数: defpreprocess(x,y): preprocess_x,x_tk=tokenize(x) preprocess_y,y_tk=tokenize(y) preprocess_x=pad(preprocess_x) preprocess_y=pad(preprocess_y) #Keras'ssparse_categorical_crossentropyfunctionrequiresthelabelstobein3dimensions preprocess_y=preprocess_y.reshape(*preprocess_y.shape,1) returnpreprocess_x,preprocess_y,x_tk,y_tk preproc_english_sentences,preproc_french_sentences,english_tokenizer,french_tokenizer=\ preprocess(english_sentences,french_sentences) max_english_sequence_length=preproc_english_sentences.shape[1] max_french_sequence_length=preproc_french_sentences.shape[1] english_vocab_size=len(english_tokenizer.word_index) french_vocab_size=len(french_tokenizer.word_index) print('DataPreprocessed') print("MaxEnglishsentencelength:",max_english_sequence_length) print("MaxFrenchsentencelength:",max_french_sequence_length) print("Englishvocabularysize:",english_vocab_size) print("Frenchvocabularysize:",french_vocab_size) 模型 在本节中,我们将尝试各种神经网络结构。我们将训练 4 个相对简单的结构作为开始: 模型 1 是一个简单的 RNN; 模型 2 是一个带词嵌入的 RNN; 模型 3 是一个双向 RNN; 模型 4 是两个 RNN 组成的编码器—解码器架构。 在尝试了 4 种简单的结构之后,我们将构建一个更深的模型,其性能要优于以上 4 种模型。 id 重新转化为文本 神经网络将输入转化为单词 id,但这不是我们最终想要的形式,我们想要的是法文翻译。logits_to_text 函数弥补了从神经网络输出的 logits 到法文翻译之间的缺口,我们将使用该函数更好地理解神经网络的输出。 deflogits_to_text(logits,tokenizer): index_to_words={id:wordforword,idintokenizer.word_index.items()} index_to_words[0]='PAD' return''.join([index_to_words[prediction]forpredictioninnp.argmax(logits,1)]) print('`logits_to_text`functionloaded.') 模型 1:RNN 我们构建一个基础的 RNN 模型,该模型是将英文翻译成法文序列的良好基准。 defsimple_model(input_shape,output_sequence_length,english_vocab_size,french_vocab_size): learning_rate=1e-3 input_seq=Input(input_shape[1:]) rnn=GRU(64,return_sequences=True)(input_seq) logits=TimeDistributed(Dense(french_vocab_size))(rnn) model=Model(input_seq,Activation('softmax')(logits)) model.compile(loss=sparse_categorical_crossentropy, optimizer=Adam(learning_rate), metrics=['accuracy']) returnmodel tests.test_simple_model(simple_model) tmp_x=pad(preproc_english_sentences,max_french_sequence_length) tmp_x=tmp_x.reshape((-1,preproc_french_sentences.shape[-2],1)) #Traintheneuralnetwork simple_rnn_model=simple_model( tmp_x.shape, max_french_sequence_length, english_vocab_size, french_vocab_size) simple_rnn_model.fit(tmp_x,preproc_french_sentences,batch_size=1024,epochs=10,validation_split=0.2) #Printprediction(s) print(logits_to_text(simple_rnn_model.predict(tmp_x[:1])[0],french_tokenizer)) 基础 RNN 模型的验证集准确度是 0.6039。 模型 2:词嵌入 词嵌入是在 n 维空间中近义词距离相近的向量表示,其中 n 表示嵌入向量的大小。我们将使用词嵌入来构建一个 RNN 模型。 fromkeras.modelsimportSequential defembed_model(input_shape,output_sequence_length,english_vocab_size,french_vocab_size): learning_rate=1e-3 rnn=GRU(64,return_sequences=True,activation="tanh") embedding=Embedding(french_vocab_size,64,input_length=input_shape[1]) logits=TimeDistributed(Dense(french_vocab_size,activation="softmax")) model=Sequential() #emcanonlybeusedinfirstlayer--KerasDocumentation model.add(embedding) model.add(rnn) model.add(logits) model.compile(loss=sparse_categorical_crossentropy, optimizer=Adam(learning_rate), metrics=['accuracy']) returnmodel tests.test_embed_model(embed_model) tmp_x=pad(preproc_english_sentences,max_french_sequence_length) tmp_x=tmp_x.reshape((-1,preproc_french_sentences.shape[-2])) embeded_model=embed_model( tmp_x.shape, max_french_sequence_length, english_vocab_size, french_vocab_size) embeded_model.fit(tmp_x,preproc_french_sentences,batch_size=1024,epochs=10,validation_split=0.2) print(logits_to_text(embeded_model.predict(tmp_x[:1])[0],french_tokenizer)) 嵌入式模型的验证集准确度是 0.8401。 模型 3:双向 RNN defbd_model(input_shape,output_sequence_length,english_vocab_size,french_vocab_size): learning_rate=1e-3 model=Sequential() model.add(Bidirectional(GRU(128,return_sequences=True,dropout=0.1), input_shape=input_shape[1:])) model.add(TimeDistributed(Dense(french_vocab_size,activation='softmax'))) model.compile(loss=sparse_categorical_crossentropy, optimizer=Adam(learning_rate), metrics=['accuracy']) returnmodel tests.test_bd_model(bd_model) tmp_x=pad(preproc_english_sentences,preproc_french_sentences.shape[1]) tmp_x=tmp_x.reshape((-1,preproc_french_sentences.shape[-2],1)) bidi_model=bd_model( tmp_x.shape, preproc_french_sentences.shape[1], len(english_tokenizer.word_index)+1, len(french_tokenizer.word_index)+1) bidi_model.fit(tmp_x,preproc_french_sentences,batch_size=1024,epochs=20,validation_split=0.2) #Printprediction(s) print(logits_to_text(bidi_model.predict(tmp_x[:1])[0],french_tokenizer)) 双向 RNN 模型的验证集准确度是 0.5992。 模型 4:编码器—解码器框架 编码器构建一个语句的矩阵表示,而解码器将该矩阵作为输入并输出预测的翻译。 defencdec_model(input_shape,output_sequence_length,english_vocab_size,french_vocab_size): learning_rate=1e-3 model=Sequential() model.add(GRU(128,input_shape=input_shape[1:],return_sequences=False)) model.add(RepeatVector(output_sequence_length)) model.add(GRU(128,return_sequences=True)) model.add(TimeDistributed(Dense(french_vocab_size,activation='softmax'))) model.compile(loss=sparse_categorical_crossentropy, optimizer=Adam(learning_rate), metrics=['accuracy']) returnmodel tests.test_encdec_model(encdec_model) tmp_x=pad(preproc_english_sentences) tmp_x=tmp_x.reshape((-1,preproc_english_sentences.shape[1],1)) encodeco_model=encdec_model( tmp_x.shape, preproc_french_sentences.shape[1], len(english_tokenizer.word_index)+1, len(french_tokenizer.word_index)+1) encodeco_model.fit(tmp_x,preproc_french_sentences,batch_size=1024,epochs=20,validation_split=0.2) print(logits_to_text(encodeco_model.predict(tmp_x[:1])[0],french_tokenizer)) 编码器—解码器模型的验证集准确度是 0.6406。 模型 5:自定义深度模型 构建一个将词嵌入和双向 RNN 合并到一个模型中的 model_final。 至此,我们需要需要做一些实验,例如将 GPU 参数改为 256,将学习率改为 0.005,对模型训练多于(或少于)20 epochs 等等。 defmodel_final(input_shape,output_sequence_length,english_vocab_size,french_vocab_size): model=Sequential() model.add(Embedding(input_dim=english_vocab_size,output_dim=128,input_length=input_shape[1])) model.add(Bidirectional(GRU(256,return_sequences=False))) model.add(RepeatVector(output_sequence_length)) model.add(Bidirectional(GRU(256,return_sequences=True))) model.add(TimeDistributed(Dense(french_vocab_size,activation='softmax'))) learning_rate=0.005 model.compile(loss=sparse_categorical_crossentropy, optimizer=Adam(learning_rate), metrics=['accuracy']) returnmodel tests.test_model_final(model_final) print('FinalModelLoaded') 预测 deffinal_predictions(x,y,x_tk,y_tk): tmp_X=pad(preproc_english_sentences) model=model_final(tmp_X.shape, preproc_french_sentences.shape[1], len(english_tokenizer.word_index)+1, len(french_tokenizer.word_index)+1) model.fit(tmp_X,preproc_french_sentences,batch_size=1024,epochs=17,validation_split=0.2) y_id_to_word={value:keyforkey,valueiny_tk.word_index.items()} y_id_to_word[0]='PAD' sentence='hesawaoldyellowtruck' sentence=[x_tk.word_index[word]forwordinsentence.split()] sentence=pad_sequences([sentence],maxlen=x.shape[-1],padding='post') sentences=np.array([sentence[0],x[0]]) predictions=model.predict(sentences,len(sentences)) print('Sample1:') print(''.join([y_id_to_word[np.argmax(x)]forxinpredictions[0]])) print('Ilavuunvieuxcamionjaune') print('Sample2:') print(''.join([y_id_to_word[np.argmax(x)]forxinpredictions[1]])) print(''.join([y_id_to_word[np.max(x)]forxiny[0]])) final_predictions(preproc_english_sentences,preproc_french_sentences,english_tokenizer,french_tokenizer) 我们得到了语句完美的翻译同时验证集准确度是 0.9776! 原文链接:https://medium.com/@actsusanli/neural-machine-translation-with-python-c2f0a34f7dd 本文为机器之心编译,转载请联系本公众号获得授权。 ?------------------------------------------------ 加入机器之心(全职记者 / 实习生):hr@jiqizhixin.com 投稿或寻求报道:content@jiqizhixin.com 广告 & 商务合作:bd@jiqizhixin.com

上一篇:2025-08-02_腾讯研究院AI每周关键词Top50 下一篇:2025-08-06_阿式攀登者都爱用?佳能EOS C80太懂极限拍摄了!

TAG标签:

16
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版域名注册主机空间手机网站建设网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。
项目经理在线

相关阅读 更多>>

猜您喜欢更多>>

我们已经准备好了,你呢?
2022我们与您携手共赢,为您的企业营销保驾护航!

不达标就退款

高性价比建站

免费网站代备案

1对1原创设计服务

7×24小时售后支持

 

全国免费咨询:

13245491521

业务咨询:13245491521 / 13245491521

节假值班:13245491521()

联系地址:

Copyright © 2019-2025      ICP备案:沪ICP备19027192号-6 法律顾问:律师XXX支持

在线
客服

技术在线服务时间:9:00-20:00

在网站开发,您对接的直接是技术员,而非客服传话!

电话
咨询

13245491521
7*24小时客服热线

13245491521
项目经理手机

微信
咨询

加微信获取报价