0


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

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

代码文件

import numpy as np

test_point = input()

with open('cmn.txt', 'r', encoding='utf-8') as f:
    data = f.read()
data = data.split('\n')
data = data[:100]

#########begin#########
en_data = [line.split('\t')[0] for line in data]
ch_data = ['\t' + line.split('\t')[1] + '\n' for line in data]

#########end#########

print('英文数据:\n', en_data[:5])
print('\n中文数据:\n', ch_data[:5])

print('数据读取完成')

# 分别生成中英文字典

#########begin#########
en_vocab = set(''.join(en_data))
en_vocab = sorted(en_vocab)
id2en = {i: char for i, char in enumerate(en_vocab)}
en2id = {char: i for i, char in enumerate(en_vocab)}

ch_vocab = set(''.join(ch_data))
ch_vocab = sorted(ch_vocab)
id2ch = {i: char for i, char in enumerate(ch_vocab)}
ch2id = {char: i for i, char in enumerate(ch_vocab)}

#########end#########

print('\n英文字典:\n', en2id)
print('\n中文字典\n:', ch2id)
print('字典构建完成')
en_num_data = [[en2id[en] for en in line] for line in en_data]
ch_num_data = [[ch2id[ch] for ch in line] for line in ch_data]
de_num_data = [[ch2id[ch] for ch in line][1:] for line in ch_data]

import numpy as np

# 获取输入输出端的最大长度
max_encoder_seq_length = max([len(txt) for txt in en_num_data])
max_decoder_seq_length = max([len(txt) for txt in ch_num_data])

#########begin#########
# 将数据进行onehot处理
# 将数据进行onehot处理
encoder_input_data = np.zeros(
    (len(en_num_data), max_encoder_seq_length, len(en2id)), dtype='float32')
decoder_input_data = np.zeros(
    (len(ch_num_data), max_decoder_seq_length, len(ch2id)), dtype='float32')
decoder_target_data = np.zeros(
    (len(ch_num_data), max_decoder_seq_length, len(ch2id)), dtype='float32')

for i, (input_text, target_text) in enumerate(zip(en_num_data, ch_num_data)):
    for t, char in enumerate(input_text):
        encoder_input_data[i, t, char] = 1.
    for t, char in enumerate(target_text):
        decoder_input_data[i, t, char] = 1.
        # 注意:target_text是从索引1开始,因为索引0是'\t'开始标记
        if t > 0:
            # decoder_target_data是从索引0开始,结束标记是'\n'
            decoder_target_data[i, t - 1, char] = 1.

#########end#########
print(encoder_input_data[int(test_point)])
print(decoder_input_data[int(test_point)])
print(decoder_target_data[int(test_point)])

print('向量化完成')

题目描述

任务描述

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

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

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

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

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

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

\t

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

en_data

,将法语句子存入

ch_data

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

\t

开头,并以

\n

结尾。

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

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

token

所构成的集合。该

token

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

token

。所有的英文字符存储在

en_vocab

中,中文字符存储在

ch_vocab

中。词典一般使用

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” 在代码片段中,使用

encoder_input_data

,

decoder_input_data

decoder_target_data

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

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训练模型

代码文件

import data_prepare
from keras.models import Model
from keras.layers import Input, LSTM, Dense, Embedding,concatenate,TimeDistributed,RepeatVector,Bidirectional
from keras.optimizers import Adam

EN_VOCAB_SIZE = 47
CH_VOCAB_SIZE = 147
HIDDEN_SIZE = 256

LEARNING_RATE = 0.003
BATCH_SIZE = 100
EPOCHS = 200

encoder_input_data, decoder_input_data,decoder_target_data,_,_,_ = data_prepare.getdata()
# ==============encoder=============
#########begin#########

# Encoder
encoder_inputs = Input(shape=(None, EN_VOCAB_SIZE))
encoder_LSTM = LSTM(HIDDEN_SIZE, return_sequences=True, return_state=True, name='encoder')
encoder_outputs, state_h, state_c = encoder_LSTM(encoder_inputs)
encoder_states = [state_h, state_c]

#########end#########
# # ==============decoder=============

#########begin#########

# Decoder
decoder_inputs = Input(shape=(None, CH_VOCAB_SIZE))
decoder_LSTM = LSTM(HIDDEN_SIZE, return_sequences=True, return_state=True, name='decoder')
decoder_outputs, _, _ = decoder_LSTM(decoder_inputs, initial_state=encoder_states)
decoder_dense = Dense(CH_VOCAB_SIZE, activation='softmax', name='dense')
decoder_outputs = decoder_dense(decoder_outputs)

#########end#########

#
#
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
opt = Adam(lr=LEARNING_RATE, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()

# model.fit([encoder_input_data, decoder_input_data], decoder_target_data,
#           batch_size=BATCH_SIZE,
#           epochs=EPOCHS,
#           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单元,维度设置为

HIDDEN_SIZE

return_sequences

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

return_states

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

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

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

encoder_state_h

 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的输出,我们使用一个全连接层,并使用

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部分还可以使用注意力机制:

该方法通过一个

attention

层,将

Encoder

部分的每一步的输出与

decoder_inputs

联系起来作为

decoder

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

c

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

c

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

Decoder

结构。

训练seq2seq模型

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

optimizer

选择优化器,

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)

其中

x

为输入的数据,

y

为输出的数据。

batch_size

为每一批处理的序列数,

epochs

为训练的迭代次数,

validation_split

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

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

测试说明

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

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


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

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

代码文件

import data_prepare
from keras.models import Model
from keras.layers import Input, LSTM, Dense, Embedding, concatenate, TimeDistributed, RepeatVector, Bidirectional
from keras.optimizers import Adam
import numpy as np

# Existing code for setting up the model
EN_VOCAB_SIZE = 47
CH_VOCAB_SIZE = 147
HIDDEN_SIZE = 256
LEARNING_RATE = 0.003
BATCH_SIZE = 100
EPOCHS = 100
encoder_input_data, decoder_input_data, decoder_target_data, ch2id, id2ch, en_data = data_prepare.getdata()

# ==============encoder=============
encoder_inputs = Input(shape=(None, EN_VOCAB_SIZE))
encoder_h, encoder_state_h, encoder_state_c = LSTM(HIDDEN_SIZE, return_sequences=True, return_state=True, name='encoder')(encoder_inputs)

# ==============decoder=============
decoder_inputs = Input(shape=(None, CH_VOCAB_SIZE))
decoder = LSTM(HIDDEN_SIZE, return_sequences=True, return_state=True, name='decoder')
decoder_dense = Dense(CH_VOCAB_SIZE, activation='softmax', name='dense')
decoder_h, _, _ = decoder(decoder_inputs, initial_state=[encoder_state_h, encoder_state_c])
decoder_outputs = decoder_dense(decoder_h)
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
opt = Adam(lr=LEARNING_RATE, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])
model.fit([encoder_input_data, decoder_input_data], decoder_target_data, batch_size=BATCH_SIZE, epochs=EPOCHS, validation_split=0.2, verbose=0)

# Encoder Inference Model
encoder_model = Model(encoder_inputs, [encoder_state_h, encoder_state_c])

# Decoder Inference Model
decoder_state_input_h = Input(shape=(HIDDEN_SIZE,))
decoder_state_input_c = Input(shape=(HIDDEN_SIZE,))
decoder_h, state_h, state_c = decoder(decoder_inputs, initial_state=[decoder_state_input_h, decoder_state_input_c])
decoder_outputs = decoder_dense(decoder_h)
decoder_model = Model([decoder_inputs, decoder_state_input_h, decoder_state_input_c], [decoder_outputs, state_h, state_c])

for k in range(40, 50):
    test_data = encoder_input_data[k:k + 1]
    h, c = encoder_model.predict(test_data)
    target_seq = np.zeros((1, 1, CH_VOCAB_SIZE))
    target_seq[0, 0, ch2id['\t']] = 1
    outputs = []

    while True:
        output_tokens, h, c = decoder_model.predict([target_seq, h, c])
        sampled_token_index = np.argmax(output_tokens[0, -1, :])
        outputs.append(sampled_token_index)
        if sampled_token_index == ch2id['\n'] or len(outputs) > 20:
            break
        target_seq = np.zeros((1, 1, CH_VOCAB_SIZE))
        target_seq[0, 0, sampled_token_index] = 1

    print(en_data[k])
    print(''.join([id2ch[i] for i in outputs if i not in [ch2id['\t'], ch2id['\n']]])+'\n')

题目描述

任务描述

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

相关知识

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

建立推断模型

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

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”的评论:

还没有评论