手把手教你用Keras实现英文到中文机器翻译 seq2seq+LSTM

原文链接:https://blog.csdn.net/qq_44635691/article/details/106919244

该模型实现的是英文到中文的翻译,下图为了更好展示模型架构借用大佬的图(这里没有用到Embeddings):

本文完整代码:Github

目录

一、处理文本数据

1.获得翻译前后的句子

 2.创建关于 字符-index 和 index -字符的字典

3.对中文和英文句子One-Hot编码

二、建立模型

三、decoder预测每个字符

四、训练模型

五、展示


 



 整体由encoder和decoder两大部分组成,每部分都有一个LSTM网络,其中encoder输入原始的句子,输出状态向量;decoder输入的是含有开始符号的翻译后的句子,输出目标句子。

        具体步骤为:

1.encoder将输入序列进行编码成状态向量

2.decoder从第一个字符开始预测

3.向decoder喂入状态向量(state_h,state_c)和累计包含之前预测字符的独热编码(第一次的状态向量来自于encoder,后来预测每            目标序列的每个字符时,状态向量来源于decoder,predict出来的状态向量)

4.使用argmax预测对下一个字符的位置,再根据字典查找到对应的字符

5.将上一步骤中的字符添加到 target sequence中

6.直到预测到我们指定结束字符时结束循环

一、处理文本数据

这一步骤包含对原数据进行分割获得翻译前、后的句子,生成字符的字典,最后对翻译前后的句子进行One-Hot编码,便于处理数据。

1.获得翻译前后的句子

先看一下原数据的样式:

首先导入需要的库:

代码1.1.1import pandas as pd
import numpy as np
from keras.layers import Input, LSTM, Dense, merge,concatenate
from keras.optimizers import Adam, SGD
from keras.models import Model,load_model
from keras.utils import plot_model
from keras.models import Sequential#定义神经网络的参数
NUM_SAMPLES=3000   #训练样本的大小
batch_size = 64    #一次训练所选取的样本数
epochs = 100       #训练轮数
latent_dim = 256   #LSTM 的单元个数
用pandas读取文件,然后我们只要前两列内容代码1.1.2data_path='data/cmn.txt'
df=pd.read_table(data_path,header=None).iloc[:NUM_SAMPLES,0:2]
#添加标题栏
df.columns=['inputs','targets']
#每句中文举手加上‘\t’作为起始标志,句末加上‘\n’终止标志
df['targets']=df['targets'].apply(lambda x:'\t'+x+'\n')
最后是这样的形式:

最后是这样的形式:

代码1.1.3#获取英文、中文各自的列表
input_texts=df.inputs.values.tolist()
target_texts=df.targets.values.tolist()#确定中英文各自包含的字符。df.unique()直接取sum可将unique数组中的各个句子拼接成一个长句子
input_characters = sorted(list(set(df.inputs.unique().sum())))
target_characters = sorted(list(set(df.targets.unique().sum())))#英文字符中不同字符的数量
num_encoder_tokens = len(input_characters)
#中文字符中不同字符的数量
num_decoder_tokens = len(target_characters)
#最大输入长度
INUPT_LENGTH = max([ len(txt) for txt in input_texts])
#最大输出长度
OUTPUT_LENGTH = max([ len(txt) for txt in target_texts])2.创建关于 字符-index 和 index -字符的字典
代码1.2.1input_token_index = dict( [(char, i)for i, char in enumerate(input_characters)] )
target_token_index = dict( [(char, i) for i, char in enumerate(target_characters)] )reverse_input_char_index = dict([(i, char) for i, char in enumerate(input_characters)])
reverse_target_char_index = dict([(i, char) for i, char in enumerate(target_characters)])
3.对中文和英文句子One-Hot编码
代码1.3.1#需要把每条语料转换成LSTM需要的三维数据输入[n_samples, timestamp, one-hot feature]到模型中
encoder_input_data =np.zeros((NUM_SAMPLES,INUPT_LENGTH,num_encoder_tokens))
decoder_input_data =np.zeros((NUM_SAMPLES,OUTPUT_LENGTH,num_decoder_tokens))
decoder_target_data  = np.zeros((NUM_SAMPLES,OUTPUT_LENGTH,num_decoder_tokens))for i,(input_text,target_text) in enumerate(zip(input_texts,target_texts)):for t,char in enumerate(input_text):encoder_input_data[i,t,input_token_index[char]]=1.0for t, char in enumerate(target_text):decoder_input_data[i,t,target_token_index[char]]=1.0if t > 0:# decoder_target_data 不包含开始字符,并且比decoder_input_data提前一步decoder_target_data[i, t-1, target_token_index[char]] = 1.0
二、建立模型
代码2.1#定义编码器的输入encoder_inputs=Input(shape=(None,num_encoder_tokens))#定义LSTM层,latent_dim为LSTM单元中每个门的神经元的个数,return_state设为True时才会返回最后时刻的状态h,cencoder=LSTM(latent_dim,return_state=True)# 调用编码器,得到编码器的输出(输入其实不需要),以及状态信息 state_h 和 state_cencoder_outputs,state_h,state_c=encoder(encoder_inputs)# 丢弃encoder_outputs, 我们只需要编码器的状态encoder_state=[state_h,state_c]#定义解码器的输入decoder_inputs=Input(shape=(None,num_decoder_tokens))decoder_lstm=LSTM(latent_dim,return_state=True,return_sequences=True)# 将编码器输出的状态作为初始解码器的初始状态decoder_outputs,_,_=decoder_lstm(decoder_inputs,initial_state=encoder_state)#添加全连接层decoder_dense=Dense(num_decoder_tokens,activation='softmax')decoder_outputs=decoder_dense(decoder_outputs)#定义整个模型model=Model([encoder_inputs,decoder_inputs],decoder_outputs)model的模型图:

 model的模型图:



其中decoder在每个timestep有三个输入分别是来自encoder的两个状态向量state_h,state_c和经过One-Hot编码的中文序列 

代码2.2#定义encoder模型,得到输出encoder_statesencoder_model=Model(encoder_inputs,encoder_state)decoder_state_input_h=Input(shape=(latent_dim,))decoder_state_input_c=Input(shape=(latent_dim,))decoder_state_inputs=[decoder_state_input_h,decoder_state_input_c]# 得到解码器的输出以及中间状态decoder_outputs,state_h,state_c=decoder_lstm(decoder_inputs,initial_state=decoder_state_inputs)decoder_states=[state_h,state_c]decoder_outputs=decoder_dense(decoder_outputs)decoder_model=Model([decoder_inputs]+decoder_state_inputs,[decoder_outputs]+decoder_states)plot_model(model=model,show_shapes=True)plot_model(model=encoder_model,show_shapes=True)plot_model(model=decoder_model,show_shapes=True)return model,encoder_model,decoder_model

encoder的模型图:



decoder的模型图:

三、decoder预测每个字符

首先encoder根据输入序列生成状态向量states_value 并结合由包含开始字符"\t"的编码一并传入到decoder的输入层,预测出下个字符的位置sampled_token_index ,将新预测到的字符添加到target_seq中再进行One-Hot编码,用预测上个字符生成的状态向量作为新的状态向量。

以上过程在while中不断循环,直到预测到结束字符"\n",结束循环,返回翻译后的句子。从下图可直观的看出对于decoder部分是一个一个生成翻译后的序列,注意蓝线的指向是target_squence,它是不断被填充的。

代码3.1def decode_sequence(input_seq,encoder_model,decoder_model):# 将输入序列进行编码生成状态向量states_value = encoder_model.predict(input_seq)# 生成一个size=1的空序列target_seq = np.zeros((1, 1, num_decoder_tokens))# 将这个空序列的内容设置为开始字符target_seq[0, 0, target_token_index['\t']] = 1.# 进行字符恢复# 简单起见,假设batch_size = 1stop_condition = Falsedecoded_sentence = ''while not stop_condition:output_tokens, h, c = decoder_model.predict([target_seq] + states_value)
#        print(output_tokens)这里输出的是下个字符出现的位置的概率# 对下个字符采样  sampled_token_index是要预测下个字符最大概率出现在字典中的位置sampled_token_index = np.argmax(output_tokens[0, -1, :])sampled_char = reverse_target_char_index[sampled_token_index]decoded_sentence += sampled_char# 退出条件:生成 \n 或者 超过最大序列长度if sampled_char == '\n' or len(decoded_sentence) >INUPT_LENGTH  :stop_condition = True# 更新target_seqtarget_seq = np.zeros((1, 1, num_decoder_tokens))target_seq[0, 0, sampled_token_index] = 1.# 更新中间状态states_value = [h, c]return decoded_sentence
四、训练模型
model,encoder_model,decoder_model=create_model()
#编译模型
model.compile(optimizer='rmsprop',loss='categorical_crossentropy')
#训练模型
model.fit([encoder_input_data,decoder_input_data],decoder_target_data,batch_size=batch_size,epochs=epochs,validation_split=0.2)
#训练不错的模型为了以后测试可是保存
model.save('s2s.h5')
encoder_model.save('encoder_model.h5')
decoder_model.save('decoder_model.h5')
五、展示
if __name__ == '__main__':intro=input("select train model or test model:")if intro=="train":print("训练模式...........")train()else:print("测试模式.........")while(1):test()

 

 

训练数据用了3000组 ,大部分是比较短的词组或者单词。效果不能算是太好,但是比起英语渣渣还算可以吧。

Reference:

https://blog.keras.io/a-ten-minute-introduction-to-sequence-to-sequence-learning-in-keras.html

https://towardsdatascience.com/neural-machine-translation-using-seq2seq-with-keras-c23540453c74

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/479053.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 45. 跳跃游戏 II(贪心/BFS,难)

文章目录1. 题目2. 解题2.1 贪心2.2 BFS1. 题目 给定一个非负整数数组,你最初位于数组的第一个位置。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 你的目标是使用最少的跳跃次数到达数组的最后一个位置。 示例:输入: [2,3,1,1,4] 输出: 2 解释: 跳到最…

Android官方开发文档Training系列课程中文版:连接无线设备之通过WIFI创建P2P连接

原文地址:http://android.xsoftlab.net/training/connect-devices-wirelessly/wifi-direct.html#permissions Wi-Fi peer-to-peer (P2P) APIs可以使程序与附近的设备进行直接通讯,Android的Wi-Fi P2P框架由Wi-Fi Direct™提供技术支持。WI-FI P2P技术可…

深度剖析开源分布式监控CAT

CAT(Central Application Tracking)是一个实时和接近全量的监控系统,它侧重于对Java应用的监控,基本接入了美团上海侧所有核心应用。目前在中间件(MVC、RPC、数据库、缓存等)框架中得到广泛应用&#xff0c…

论文浅尝 | ​ADRL:一个基于注意力机制的知识图谱深度强化学习框架

论文笔记整理:谭亦鸣,东南大学博士。来源:Knowledge-Based Systems 197 (2020) 105910链接:https://www.sciencedirect.com/science/article/abs/pii/S0957417419306839概要与动机知识图谱推理是图谱构建的关键技术之一&#xff0…

新年第二弹|卖萌屋私藏书单大公开

夕本尊 &夕小瑶 推荐作为一个互联网人,不仅要懂技术,还应该了解行业的基本运作原理。这其中一个重要的问题是:为什么互联网产品(基本)都是免费的,甚至纷纷给用户送钱,它们却能有这么强的盈利…

LeetCode 437. 路径总和 III(双重递归)

1. 题目 给定一个二叉树,它的每个结点都存放着一个整数值。 找出路径和等于给定数值的路径总数。 路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。 二叉树不超过…

2020年美团技术团队最受欢迎的16篇技术文章

2020年美团技术团队最受欢迎的16篇技术文章:https://tech.meituan.com/2021/01/01/2020-summary.html

论文浅尝 - ESWA | 知识图谱的自动扩充方法

论文笔记整理:谭亦鸣,东南大学博士。来源:ESWA141(2020)链接:https://www.sciencedirect.com/science/article/abs/pii/S0957417419306839为了使计算机理解人类语言,并且实现推理,人类知识需要被表示并储存…

美团大脑:知识图谱的建模方法及其应用

作为人工智能时代最重要的知识表示方式之一,知识图谱能够打破不同场景下的数据隔离,为搜索、推荐、问答、解释与决策等应用提供基础支撑。美团大脑围绕吃喝玩乐等多种场景,构建了生活娱乐领域超大规模的知识图谱,为用户和商家建立…

Android官方开发文档Training系列课程中文版:连接无线设备之通过P2P搜索网络服务

原文地址:http://android.xsoftlab.net/training/connect-devices-wirelessly/nsd-wifi-direct.html 本阶段的第一节课 Using Network Service Discovery 展示了如何搜索本地网络服务。然而,使用WI-FI P2P搜索服务可以直接搜索附近的设备,而…

全栈深度学习第2期: 开发套件与工具篇

一起追剧鸭简介Berkeley全栈深度学习追剧计划是由夕小瑶的卖萌屋发起的优质公开课打卡项目,通过微信群为同期追剧的小伙伴提供交流平台。关于该计划的详请见这里。1. Berkeley深度学习追剧群目前已有1000小伙伴加入,公众号后台回复口令 深度学习追剧 入群…

LeetCode 700. 二叉搜索树中的搜索

1. 题目 给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。 2. 解题 class Solution {//递归写法TreeNode *ans NULL; public:TreeNode* searchB…

NLP-美团技术团队(搜索-推荐-召回排序-Bert)

NLP-美团技术团队:https://tech.meituan.com/tags/nlp.html

iOS系统中导航栏的转场解决方案与最佳实践

背景 目前,开源社区和业界内已经存在一些 iOS 导航栏转场的解决方案,但对于历史包袱沉重的美团 App 而言,这些解决方案并不完美。有的方案不能满足复杂的页面跳转场景,有的方案迁移成本较大,为此我们提出了一套解决方案…

论文浅尝 - WSDM20 | 基于弱监督及逐步推理的多关系知识图谱问答

论文笔记整理:刘晓臻,东南大学计算机科学与工程学院本科生。来源:WSDM ’20链接:https://dl.acm.org/doi/abs/10.1145/3336191.3371812动机知识图谱问答(KG-QA)系统大多包含两个步骤:链接问题中的topic entity到KG&…

Android官方开发文档Training系列课程中文版:网络操作之网络连接

原文地址:http://android.xsoftlab.net/training/basics/network-ops/index.html 引言 这节课将会学习最基本的网络连接,监视网络连接状况及网络控制等内容。除此之外还会附带描述如何解析、使用XML数据。 这节课所包含的示例代码演示了最基本的网络操…

算法工程师的落地能力具体指的是什么?

文 | 桔了个仔知乎本文已获作者授权,禁止二次转载大家好,这里是桔了个仔,目前是一名Data Scientist(不太想翻译成数据科学家,毕竟感觉自己就是个工程师),过去几年在做基于机器学习的风控与合规系统&#xf…

国内外自然语言处理(NLP)研究组

2015年国内外自然语言处理(NLP)研究组: https://blog.csdn.net/wangxinginnlp/article/details/44890553 补充: 名称 地址 最近更新 HanLP https://github.com/hankcs/HanLP 2天前 腾讯开源深度学习文本分类工具 https://github.com/Tencent/NeuralNLP-…

Android官方开发文档Training系列课程中文版:网络操作之网络管理

原文地址:http://android.xsoftlab.net/training/basics/network-ops/managing.html 这节课将会学习如何对网络资源的使用情况拥有更细粒度的控制力。如果应用程序经常执行大量的网络操作,那么程序应当提供一项设置,以便用户可以控制应用的数…

LeetCode 728. 自除数

1. 题目 自除数 是指可以被它包含的每一位数除尽的数。 例如,128 是一个自除数,因为 128 % 1 0,128 % 2 0,128 % 8 0。 还有,自除数不允许包含 0 。 给定上边界和下边界数字,输出一个列表&#xff0…