0


广西民族大学高级人工智能课程—头歌实践教学实践平台—机器翻译--English to Chinese

第1关:迈出第一步----数据预处理

代码文件

  1. import numpy as np
  2. test_point = input()
  3. with open('cmn.txt', 'r', encoding='utf-8') as f:
  4. data = f.read()
  5. data = data.split('\n')
  6. data = data[:100]
  7. #########begin#########
  8. en_data = [line.split('\t')[0] for line in data]
  9. ch_data = ['\t' + line.split('\t')[1] + '\n' for line in data]
  10. #########end#########
  11. print('英文数据:\n', en_data[:5])
  12. print('\n中文数据:\n', ch_data[:5])
  13. print('数据读取完成')
  14. # 分别生成中英文字典
  15. #########begin#########
  16. en_vocab = set(''.join(en_data))
  17. en_vocab = sorted(en_vocab)
  18. id2en = {i: char for i, char in enumerate(en_vocab)}
  19. en2id = {char: i for i, char in enumerate(en_vocab)}
  20. ch_vocab = set(''.join(ch_data))
  21. ch_vocab = sorted(ch_vocab)
  22. id2ch = {i: char for i, char in enumerate(ch_vocab)}
  23. ch2id = {char: i for i, char in enumerate(ch_vocab)}
  24. #########end#########
  25. print('\n英文字典:\n', en2id)
  26. print('\n中文字典\n:', ch2id)
  27. print('字典构建完成')
  28. en_num_data = [[en2id[en] for en in line] for line in en_data]
  29. ch_num_data = [[ch2id[ch] for ch in line] for line in ch_data]
  30. de_num_data = [[ch2id[ch] for ch in line][1:] for line in ch_data]
  31. import numpy as np
  32. # 获取输入输出端的最大长度
  33. max_encoder_seq_length = max([len(txt) for txt in en_num_data])
  34. max_decoder_seq_length = max([len(txt) for txt in ch_num_data])
  35. #########begin#########
  36. # 将数据进行onehot处理
  37. # 将数据进行onehot处理
  38. encoder_input_data = np.zeros(
  39. (len(en_num_data), max_encoder_seq_length, len(en2id)), dtype='float32')
  40. decoder_input_data = np.zeros(
  41. (len(ch_num_data), max_decoder_seq_length, len(ch2id)), dtype='float32')
  42. decoder_target_data = np.zeros(
  43. (len(ch_num_data), max_decoder_seq_length, len(ch2id)), dtype='float32')
  44. for i, (input_text, target_text) in enumerate(zip(en_num_data, ch_num_data)):
  45. for t, char in enumerate(input_text):
  46. encoder_input_data[i, t, char] = 1.
  47. for t, char in enumerate(target_text):
  48. decoder_input_data[i, t, char] = 1.
  49. # 注意:target_text是从索引1开始,因为索引0是'\t'开始标记
  50. if t > 0:
  51. # decoder_target_data是从索引0开始,结束标记是'\n'
  52. decoder_target_data[i, t - 1, char] = 1.
  53. #########end#########
  54. print(encoder_input_data[int(test_point)])
  55. print(decoder_input_data[int(test_point)])
  56. print(decoder_target_data[int(test_point)])
  57. print('向量化完成')

题目描述

任务描述

本关任务:基于机器学习的思想,是一种数据驱动的研究思想,因此首先要对准备研究的数据进行处理。对于机器翻译模型,数据预处理主要分为两个方面:

  • 标准化自然语言语句的格式
  • 构建训练所用的语言词典
  • 将语词转化为向量
相关知识

为了完成本关任务,你需要掌握:

  1. 读取原始数据并对其进行标准化整理
  2. 根据自然语言语句数据,构建英语和法语两个词典。
  3. 将自然语言向量化
数据整理

本实训提供20,000个英语句子和其相对应的20,000个翻译好的法语句子。数据的原始格式如下:

每一行包含一句英语句子和其对应的法语句子,它们中间用

  1. \t

隔开。现在希望将英语和法语句子分割开来,将英语句子存入

  1. en_data

,将法语句子存入

  1. ch_data

,并且为了后续模型训练,规定英语句子保持不变,而法语每个句子都以

  1. \t

开头,并以

  1. \n

结尾。

  1. #英文句子
  2. line.split('\t')[0]
  3. #中文句子
  4. '\t' + line.split('\t')[1] + '\n'
构建词典

所谓词典,就是指在整个数据集中出现的所有

  1. token

所构成的集合。该

  1. token

可以是单词,也可以是字母。本文以字母作为

  1. token

。所有的英文字符存储在

  1. en_vocab

中,中文字符存储在

  1. ch_vocab

中。词典一般使用

  1. dictionary

数据类型,以英文为例子,英文的词典分为两个:

  • id2en,其中的key为词典的index,而value对应相应的英文字母
  • en2id,其中key为英文字母,而value为对应的词典index 例如: 1. id2en[0]2. # out: a3. en2id['a']4. # out: 0
自然语言向量化

向量化后的自然语言语句,将被用于模型的输入。对自然语言的向量化,一种常用的方法是one-hot编码。 one-hot编码,又称“独热编码”。其实就是用N位状态寄存器编码N个状态,每个状态都有独立的寄存器位,且这些寄存器位中只有一位有效。 例如一个特征“性别”,性别有“男性”、“女性”,这个特征有两个特征值,也只有两个特征值,如果这个特征进行one-hot编码,则特征值为“男性”的编码为“10”,“女性”的编码为“01” 在代码片段中,使用

  1. encoder_input_data

,

  1. decoder_input_data

  1. decoder_target_data

,分别来存储向量化的英文、中文和目标语言句子。以

  1. encoder_input_data

为例:

  1. # 三维数组,第一维度是数据集中的总句子数,第二维度为最长的
  2. # 句子长度,最后一维度为字典的长度
  3. encoder_input_data = np.zeros((len(en_num_data), max_encoder_seq_length, len(en2id)), dtype='float32')
  4. # 向量化时,根据词典将0向量的相应位置置为1
  5. for i in range(len(ch_num_data)):
  6. for t, j in enumerate(en_num_data[i]):
  7. encoder_input_data[i, t, j] = 1.
编程要求

根据提示,在右侧编辑器补充代码。完成数据的标准化处理、构建训练所用的语言词典并将语词转化为向量。

测试说明

平台会对你编写的代码进行测试: 测试输入: 1 预期输出(会输出对应测试输入的向量化数据):

  1. 英文数据:
  2. ['Hi.', 'Hi.', 'Run.', 'Wait!', 'Hello!']
  3. 中文数据:
  4. ['\t嗨。\n', '\t你好。\n', '\t你用跑的。\n', '\t等等!\n', '\t你好。\n']
  5. 数据读取完成
  6. 英文字典:
  7. {' ': 0, '!': 1, "'": 2, '.': 3, '?': 4,...
  8. 中文字典:
  9. {'\t': 0, '\n': 1, '!': 2, '。':...
  10. 字典构建完成
  11. [[0. 0. 0. 0.....
  12. 向量化完成

开始你的任务吧,祝你成功!

第2关: 模型训练----搭建seq2seq训练模型

代码文件

  1. import data_prepare
  2. from keras.models import Model
  3. from keras.layers import Input, LSTM, Dense, Embedding,concatenate,TimeDistributed,RepeatVector,Bidirectional
  4. from keras.optimizers import Adam
  5. EN_VOCAB_SIZE = 47
  6. CH_VOCAB_SIZE = 147
  7. HIDDEN_SIZE = 256
  8. LEARNING_RATE = 0.003
  9. BATCH_SIZE = 100
  10. EPOCHS = 200
  11. encoder_input_data, decoder_input_data,decoder_target_data,_,_,_ = data_prepare.getdata()
  12. # ==============encoder=============
  13. #########begin#########
  14. # Encoder
  15. encoder_inputs = Input(shape=(None, EN_VOCAB_SIZE))
  16. encoder_LSTM = LSTM(HIDDEN_SIZE, return_sequences=True, return_state=True, name='encoder')
  17. encoder_outputs, state_h, state_c = encoder_LSTM(encoder_inputs)
  18. encoder_states = [state_h, state_c]
  19. #########end#########
  20. # # ==============decoder=============
  21. #########begin#########
  22. # Decoder
  23. decoder_inputs = Input(shape=(None, CH_VOCAB_SIZE))
  24. decoder_LSTM = LSTM(HIDDEN_SIZE, return_sequences=True, return_state=True, name='decoder')
  25. decoder_outputs, _, _ = decoder_LSTM(decoder_inputs, initial_state=encoder_states)
  26. decoder_dense = Dense(CH_VOCAB_SIZE, activation='softmax', name='dense')
  27. decoder_outputs = decoder_dense(decoder_outputs)
  28. #########end#########
  29. #
  30. #
  31. model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
  32. opt = Adam(lr=LEARNING_RATE, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
  33. model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])
  34. model.summary()
  35. # model.fit([encoder_input_data, decoder_input_data], decoder_target_data,
  36. # batch_size=BATCH_SIZE,
  37. # epochs=EPOCHS,
  38. # validation_split=0.2)

题目描述

任务描述

本关任务:准备好数据后,就要着手搭建训练模型了。本关将完成seq2seq模型的搭建和模型的训练。

相关知识

为了完成本关任务,你需要掌握: 1.seq2seq模型基本原理 2.搭建seq2seq模型 3.训练seq2seq模型

seq2seq模型基本原理

Seq2Seq模型是RNN最重要的一个变种,这种结构又叫Encoder-Decoder模型。 由于我们遇到的大部分问题序列都是不等长的,如机器翻译中,源语言和目标语言的句子往往并没有相同的长度。

encoder-decoder结构

为此,Encoder-Decoder结构先将输入数据编码成一个上下文向量,该上下文向量通常是Encoder的最后一个隐藏状态。 Decoder将该上下文向量作为输入,对其进行解码,输出相应的目标序列。 由于Encoder-Decoder结构不限制输入和输出的序列长度,因此应用的范围非常广泛,比如:机器翻译、文本摘要、阅读理解、语音识别等。

搭建seq2seq模型
Encoder模型

首先对模型的Encoder部分进行搭建,为此我们需要考虑3个方面:

  1. Encoder模型的输入是什么样子?
  2. Encoder模型使用怎样的RNN单元?
  3. 模型的哪部分作为Decoder的输入?

模型的输入可以使用Input来设定,输入的形状要与字典长度相同:

  1. encoder_input = Input(shape=(None,len(vocabulary)))

本关模型使用LSTM单元,维度设置为

  1. HIDDEN_SIZE

  1. return_sequences

字段用来决控制是否需要每一步的输出,

  1. return_states

用来控制是否输出隐藏层状态。

  1. encoder_LSTM = LTM(HIDDEN_SIZE, return_sequences=True, return_state=True,name='encoder')

Encoder使用最后一层的隐藏状态,即

  1. encoder_state_h

  1. encoder_state_c

作为Decoder的输入:

  1. encoder_h, encoder_state_h, encoder_state_c = encoder_LSTM (encoder_input)
Decoder模型

对Decoder部分进行搭建,我们需要考虑3个方面:

  1. Decoder模型的输入是什么样子?
  2. Decoder模型使用怎样的RNN单元?
  3. 模型的输出是怎样的结构?

前两步与Encoder相似,对于Decoder的输出,我们使用一个全连接层,并使用

  1. softmax

激活函数将输出的向量映射到目标语言的字典上。

  1. lstm = LSTM(HIDDEN_SIZE, return_sequences=True, return_state=True,name='decoder')
  2. decoder_h, _, _ = lstm(decoder_inputs, initial_state=[encoder_state_h, encoder_state_c])
  3. decoder_dense = Dense(CH_VOCAB_SIZE, activation='softmax',name='dense')
  4. decoder_outputs = decoder_dense(decoder_h)

Decoder部分还可以使用注意力机制:

该方法通过一个

  1. attention

层,将

  1. Encoder

部分的每一步的输出与

  1. decoder_inputs

联系起来作为

  1. decoder

的输入。相当于根据序列的每个时间步将编码器编码为不同隐藏向量

  1. c

,在解码时,结合每个不同的

  1. c

进行解码输出,这样得到的结果会更加准确。在本实训中,请先掌握较为简单的普通

  1. Decoder

结构。

训练seq2seq模型

训练模型时,我们用Model模块将Encoder和Decoder封装,并通过

  1. optimizer

选择优化器,

  1. loss

选择损失函数。

  1. model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
  2. opt = Adam(lr=LEARNING_RATE, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
  3. model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accu\fracy'])

模型在训练时,将之前预处理好的数据输入模型,并设置相应参数即可。

  1. model.fit([encoder_input_data, decoder_input_data], decoder_target_data,
  2. batch_size=BATCH_SIZE,
  3. epochs=EPOCHS,
  4. validation_split=0.2)

其中

  1. x

为输入的数据,

  1. y

为输出的数据。

  1. batch_size

为每一批处理的序列数,

  1. epochs

为训练的迭代次数,

  1. validation_split

为训练集和验证集的比例。 ####编程要求

根据提示,在右侧编辑器补充代码,完成seq2seq模型的搭建和训练。

测试说明

平台会对你编写的代码进行测试:

模型结构与要求相符即可通过本关。


开始你的任务吧,祝你成功!

第3关:模型实践----搭建seq2seq推断模型

代码文件

  1. import data_prepare
  2. from keras.models import Model
  3. from keras.layers import Input, LSTM, Dense, Embedding, concatenate, TimeDistributed, RepeatVector, Bidirectional
  4. from keras.optimizers import Adam
  5. import numpy as np
  6. # Existing code for setting up the model
  7. EN_VOCAB_SIZE = 47
  8. CH_VOCAB_SIZE = 147
  9. HIDDEN_SIZE = 256
  10. LEARNING_RATE = 0.003
  11. BATCH_SIZE = 100
  12. EPOCHS = 100
  13. encoder_input_data, decoder_input_data, decoder_target_data, ch2id, id2ch, en_data = data_prepare.getdata()
  14. # ==============encoder=============
  15. encoder_inputs = Input(shape=(None, EN_VOCAB_SIZE))
  16. encoder_h, encoder_state_h, encoder_state_c = LSTM(HIDDEN_SIZE, return_sequences=True, return_state=True, name='encoder')(encoder_inputs)
  17. # ==============decoder=============
  18. decoder_inputs = Input(shape=(None, CH_VOCAB_SIZE))
  19. decoder = LSTM(HIDDEN_SIZE, return_sequences=True, return_state=True, name='decoder')
  20. decoder_dense = Dense(CH_VOCAB_SIZE, activation='softmax', name='dense')
  21. decoder_h, _, _ = decoder(decoder_inputs, initial_state=[encoder_state_h, encoder_state_c])
  22. decoder_outputs = decoder_dense(decoder_h)
  23. model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
  24. opt = Adam(lr=LEARNING_RATE, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
  25. model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])
  26. model.fit([encoder_input_data, decoder_input_data], decoder_target_data, batch_size=BATCH_SIZE, epochs=EPOCHS, validation_split=0.2, verbose=0)
  27. # Encoder Inference Model
  28. encoder_model = Model(encoder_inputs, [encoder_state_h, encoder_state_c])
  29. # Decoder Inference Model
  30. decoder_state_input_h = Input(shape=(HIDDEN_SIZE,))
  31. decoder_state_input_c = Input(shape=(HIDDEN_SIZE,))
  32. decoder_h, state_h, state_c = decoder(decoder_inputs, initial_state=[decoder_state_input_h, decoder_state_input_c])
  33. decoder_outputs = decoder_dense(decoder_h)
  34. decoder_model = Model([decoder_inputs, decoder_state_input_h, decoder_state_input_c], [decoder_outputs, state_h, state_c])
  35. for k in range(40, 50):
  36. test_data = encoder_input_data[k:k + 1]
  37. h, c = encoder_model.predict(test_data)
  38. target_seq = np.zeros((1, 1, CH_VOCAB_SIZE))
  39. target_seq[0, 0, ch2id['\t']] = 1
  40. outputs = []
  41. while True:
  42. output_tokens, h, c = decoder_model.predict([target_seq, h, c])
  43. sampled_token_index = np.argmax(output_tokens[0, -1, :])
  44. outputs.append(sampled_token_index)
  45. if sampled_token_index == ch2id['\n'] or len(outputs) > 20:
  46. break
  47. target_seq = np.zeros((1, 1, CH_VOCAB_SIZE))
  48. target_seq[0, 0, sampled_token_index] = 1
  49. print(en_data[k])
  50. print(''.join([id2ch[i] for i in outputs if i not in [ch2id['\t'], ch2id['\n']]])+'\n')

题目描述

任务描述

本关任务:本关将使用训练好的翻译模型,对英文句子进行翻译。

相关知识

为了完成本关任务,你需要掌握: 1.如何建立推断模型。 2.如何将模型的输出整理成最终翻译的结果

建立推断模型

推断模型的建立也分为两部分,模型Encoder部分的结构与训练时完全相同,因此只需要将原来的

  1. encoder

部分封装起来即可:

  1. # Encoder inference model
  2. encoder_model = Model(encoder_inputs, [encoder_state_h, encoder_state_c])

而Decoder部分,需要将每一步的输出作为下一步的输入:

decoder

因此需要对Decoder部分重新设计。 首先确定Decoder部分的输入与输出,输入部分的大小应与Encoder输出的大小相同。

  1. decoder_state_input_h = Input(shape=(HIDDEN_SIZE,))
  2. decoder_state_input_c = Input(shape=(HIDDEN_SIZE,))

由于我们需要每一步的输出作为下一步的输入,因此需要将Decoder的隐藏状态和输出向量都存下来以备用。

  1. decoder_h, state_h, state_c = decoder(decoder_inputs, initial_state=[decoder_state_input_h, decoder_state_input_c])
  2. decoder_outputs = decoder_dense(decoder_h)

最后将Decoder的部分封装:

  1. decoder_model = Model([decoder_inputs, decoder_state_input_h, decoder_state_input_c], [decoder_outputs, state_h, state_c])
输出整理

Decoder部分的输出是一个概率向量,它的每一位对应着字典中相应位置的概率,通常我们将输出向量中概率值最高的一位,作为预测的结果:

  1. output_tokens, h, c= decoder_model.predict([target_seq, h, c])
  2. sampled_token_index = np.argmax(output_tokens[0, -1, :])

在获得Encoder部分的输出后,我们需要设计一个程序结构,使得Decoder部分将每一步的输出送入下一步之中,并且当输出了终止符号或者超过最长输出序列长度(本实训中设置为20)时,停止程序。

  1. while True:
  2. output_tokens, h, c= decoder_model.predict([target_seq, h, c])
  3. #...
  4. target_seq = np.zeros((1, 1, CH_VOCAB_SIZE))
  5. target_seq[0, 0, sampled_token_index] = 1
  6. if sampled_token_index == ch2id['\n'] or len(outputs) > 20: break
编程要求

根据提示,在右侧编辑器补充代码,搭建推断模型,完成英语到法语的翻译模型。 ####测试说明

平台会对你编写的代码进行测试: 输入英文,输出相应的中文语句。 注意:本关需要运行模型,因此评测可能较慢,请耐心等待1-2分钟。


开始你的任务吧,祝你成功!


本文转载自: https://blog.csdn.net/gxmzuai/article/details/135368278
版权归原作者 「已注销」 所有, 如有侵权,请联系我们删除。

“广西民族大学高级人工智能课程—头歌实践教学实践平台—机器翻译--English to Chinese”的评论:

还没有评论