16Seq2Seq实战语言翻译-attention(3)

image.png

数据预处理部分和上一篇一样,就不啰嗦了。重点看一下模型构造:
1. Attention层:核心在于对encoder端隐层权重进行计算

比如我们准备生成“machine”这个词:

  • s_prev是"love"输出的隐层状态
  • s_prev与Bi-LSTM隐层状态蓝色框a一起concat后,通过激活函数softmax输出权重红色框α(此时看到α3“机器”的attention线最粗)
  • 再和Bi-LSTM隐层状态蓝色框a进行加权求和,得到“machine”的context vector(就是我们之前说的向量S)
  • 最后将这个context vector(向量S)给Decoder进行处理
# 将s_prev复制Tx次
s_prev = repeator(s_prev)
# 拼接BiRNN隐层状态与s_prev
concat = concatenator([a, s_prev])
# 计算energies
e = densor_tanh(concat)
energies = densor_relu(e)
# 计算weights
alphas = activator(energies)
# 加权得到Context Vector
context = dotor([alphas, a])

return context

2.Embedding层:Embedding层是将输入的序列数字编码转化为词向量,能够使Encoder捕捉到句子的语义信息

# 加载预训练好的glove词向量
with open("data/glove.6B.100d.txt", 'r') as f:
    words = set()
    word_to_vec_map = {}
    for line in f:
        line = line.strip().split()
        curr_word = line[0]
        words.add(curr_word)
        word_to_vec_map[curr_word] = np.array(line[1:], dtype=np.float64)

构造Embedding层并加载预训练好的词向量(这里使用的是100维)

vocab_len = len(source_vocab_to_int) + 1        # Keras Embedding的API要求+1
emb_dim = word_to_vec_map["the"].shape[0]

# 初始化embedding矩阵
emb_matrix = np.zeros((vocab_len, emb_dim))

# 用词向量填充embedding矩阵
for word, index in source_vocab_to_int.items():
    word_vector = word_to_vec_map.get(word, np.zeros(emb_dim))
    emb_matrix[index, :] = word_vector

# 定义Embedding层,并指定不需要训练该层的权重
embedding_layer = Embedding(vocab_len, emb_dim, trainable=False)

# build
embedding_layer.build((None,))

# set weights
embedding_layer.set_weights([emb_matrix])

return embedding_layer

获取embedding_layer

# 获取Embedding layer
embedding_layer = pretrained_embedding_layer(word_to_vec_map, source_vocab_to_int)

3.模型构造

  • 在Encoder端,对输入句子进行学习,求得当前的Context Vector,并将其传递给Decoder处理;
  • 在Decoder端,以t-1的输出和当前Context Vector作为LSTM输入,翻译得到结果。
# 定义输入层
X = Input(shape=(Tx,))
# Embedding层
embed = embedding_layer(X)
# Decoder端LSTM的初始状态
s0 = Input(shape=(n_s,), name='s0')
c0 = Input(shape=(n_s,), name='c0')

# Decoder端LSTM的初始输入
out0 = Input(shape=(target_vocab_size, ), name='out0')
out = reshapor(out0)

s = s0
c = c0

# 模型输出列表,用来存储翻译的结果
outputs = []

# 定义Bi-LSTM
a = Bidirectional(LSTM(n_a, return_sequences=True))(embed)

# Decoder端,迭代Ty轮,每轮生成一个翻译结果
for t in range(Ty):

    # 获取Context Vector
    context = one_step_attention(a, s)

    # 将Context Vector与上一轮的翻译结果进行concat
    context = concator([context, reshapor(out)])
    s, _, c = decoder_LSTM_cell(context, initial_state=[s, c])

    # 将LSTM的输出结果与全连接层链接
    out = output_layer(s)

    # 存储输出结果
    outputs.append(out)

model = Model([X, s0, c0, out0], outputs)

return model

4. 预测与评估
这里使用的是BLEU: Bilingual Evaluation Understudy.是一种反映翻译文本和参考文本相似度的评估指标。

from nltk.translate.bleu_score import sentence_bleu
 # 计算BLEU分数
    score = sentence_bleu([reference.split()], pred.split())
image.png

你可能感兴趣的:(16Seq2Seq实战语言翻译-attention(3))