美文网首页
16Seq2Seq实战语言翻译-attention(3)

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

作者: 弟弟们的哥哥 | 来源:发表于2019-10-22 17:53 被阅读0次
    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)

          本文链接:https://www.haomeiwen.com/subject/monxvctx.html