Part 1: 机器翻译
欢迎来到本周第一个作业。你将建立一个将人类可读日期(“2009年6月25日”)转换为机器可读日期(“2009-06-25”)的神经机器翻译(NMT)模型。 你将使用注意力机制来执行此操作,这是模型序列中最尖端的一个序列。
导包
from keras.layers import Bidirectional, Concatenate, Permute, Dot, Input, LSTM, Multiply
from keras.layers import RepeatVector, Dense, Activation, Lambda
from keras.optimizers import Adam
from keras.utils import to_categorical
from keras.models import load_model, Model
import keras.backend as K
import numpy as np
from faker import Faker
import random
from tqdm import tqdm
from babel.dates import format_date
from nmt_utils import *
import matplotlib.pyplot as plt
%matplotlib inline
1 将人类可读日期翻译为机器可读日期
你将创建的模型可用于从一种语言翻译为另一种语言,如从英语翻译为印地安语。 但是,语言翻译需要大量的数据集,并且通常需要几天的GPU训练。 在不使用海量数据的情况下,为了让你有机会尝试使用这些模型,我们使用更简单的“日期转换”任务。
网络以各种可能格式(例如“1958年8月29日”,“03/30/1968”,“1987年6月24日”)写成的日期作为输入,并将它们转换成标准化的机器可读的日期(例如“1958 -08-29“,”1968-03-30“,”1987-06-24“),让网络学习以通用机器可读格式YYYY-MM-DD输出日期。
1.1 数据集
我们将在一个包含10000个可读日期的数据集及其等效的标准化机器可读日期上训练模型。 执行以下命令加载数据并查看一些示例。
m = 10000
dataset, human_vocab, machine_vocab, inv_machine_vocab = load_dataset(m)
dataset[:10]
# [('9 may 1998', '1998-05-09'),
# ('10.09.70', '1970-09-10'),
# ('4/28/90', '1990-04-28'),
# ('thursday january 26 1995', '1995-01-26'),
# ('monday march 7 1983', '1983-03-07'),
# ('sunday may 22 1988', '1988-05-22'),
# ('tuesday july 8 2008', '2008-07-08'),
# ('08 sep 1999', '1999-09-08'),
# ('1 jan 1981', '1981-01-01'),
# ('monday may 22 1995', '1995-05-22')]
其中
- dataset:一个二元组列表(人类可读日期,机器可读日期)
- human_vocab: 人类可读日期中使用到的所有字符到字典索引值的映射
- machine_vocab: 机器可读日期中使用到的所有字符到字典索引值的映射(与human_vocab的索引没必要完全一致)
- inv_machine_vocab: machine_vocab 的翻转映射,从索引映射到字符
预处理数据并将原始文本数据映射到索引。 我们还将使用 Tx=30 T x = 30 (假设它是人类可读日期的最大长度;如果得到更长的输入,将不得不截断它)并且 Ty=10 T y = 10 (因为“YYYY-MM-DD”是10个字符)
Tx = 30
Ty = 10
X, Y, Xoh, Yoh = preprocess_data(dataset, human_vocab, machine_vocab, Tx, Ty)
print("X.shape:", X.shape)
print("Y.shape:", Y.shape)
print("Xoh.shape:", Xoh.shape)
print("Yoh.shape:", Yoh.shape)
# X.shape: (10000, 30)
# Y.shape: (10000, 10)
# Xoh.shape: (10000, 30, 37)
# Yoh.shape: (10000, 10, 11)
目前已有:
- X: 经过处理的训练集中人类可读日期,其中每个字符都替换为其在human_vocab中映射到的索引。 每个日期用特殊字符进一步填充为 Tx T x 长度。 X.shape =(m, Tx T x )
- Y: 经过处理的训练集中机器可读日期,其中每个字符都替换为其在machine_vocab中映射到的索引。 你应该有Y.shape =(m,Ty)。
- Xoh:X的one-hot向量,Xoh.shape = (m,Tx,len(human_vocab))
- Yoh:Y的one-hot向量,Yoh.shape = (m,Tx,len(machine_vocab))。
这里,len(machine_vocab)= 11,因为有11个字符(’ - ‘以及0-9)。
查看预处理数据
index = 0
print("Source date:", dataset[index][0])
print("Target date:", dataset[index][1])
print()
print("Source after preprocessing (indices):", X[index])
print("Target after preprocessing (indices):", Y[index])
print()
print("Source after preprocessing (one-hot):", Xoh[index])
print("Target after preprocessing (one-hot):", Yoh[index])
# Source date: 9 may 1998
# Target date: 1998-05-09
#
# Source after preprocessing (indices): [12 0 24 13 34 0 4 12 12 11 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36
# 36 36 36 36 36]
# Target after preprocessing (indices): [ 2 10 10 9 0 1 6 0 1 10]
#
# Source after preprocessing (one-hot): [[ 0. 0. 0. ..., 0. 0. 0.]
# [ 1. 0. 0. ..., 0. 0. 0.]
# [ 0. 0. 0. ..., 0. 0. 0.]
# ...,
# [ 0. 0. 0. ..., 0. 0. 1.]
# [ 0. 0. 0. ..., 0. 0. 1.]
# [ 0. 0. 0. ..., 0. 0. 1.]]
# Target after preprocessing (one-hot): [[ 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
# [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
# [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
# [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]
# [ 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
# [ 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
# [ 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
# [ 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
# [ 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
# [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]]
2 采用注意力机制的机器翻译
如果你需要将一段法文翻译成英文,你不会阅读整段然后关闭书本再翻译。 即使在翻译过程中,您也会阅读/重读,并专注于你正在翻译的部分。
注意力机制告诉神经翻译模型什么时候应该关注什么。
2.1 注意力机制
在这一部分,你将会实现注意力机制,图中展示了注意力机制的工作原理。上图是注意力机制的模型,下图是每步注意力变量 α<t,t′> α < t , t ′ > 的计算,该变量将用于计算每步输出的 context<t> c o n t e x t < t > , 其中 (t = 1, … , Ty T y )
图一
下面是关于模型的一些属性说明:
- 模型中有两个单独的LSTM。
- 图片底部的是双向LSTM,处在关注机制之前,将其称为pre-attention Bi-LSTM。
- 图片顶部的LSTM出现在关注机制之后,将其称为post-attention LSTM。
- pre-attention Bi-LSTM经过 Tx T x 个时间步。
- post-attention LSTM经历 Ty T y 个时间步。
- post-attention LSTM将 s⟨t⟩ s ⟨ t ⟩ , c⟨t⟩ c ⟨ t ⟩ 从一个时间步传给下一个时间步。
- 在视频课程中,我们仅使用了基本的RNN作为post-attention 序列模型,因此RNN输出激活状态为 s⟨t⟩ s ⟨ t ⟩ 。
- 这里我们使用LSTM,因此LSTM具有输出激活状态 s⟨t⟩ s ⟨ t ⟩ 和隐藏单元状态 c⟨t⟩ c ⟨ t ⟩ 。
- 然而,与先前的文本生成示例(例如第1周的恐龙)不同,在该模型中,在时间t的post-activation LSTM不会将具体生成的