Transformer (Google 机器翻译模型)

本文深入解析Transformer模型,探讨其如何结合卷积神经网络和循环神经网络的优势,利用注意力机制实现序列依赖的并行化捕捉,大幅减少训练时间。文章还详细介绍了Transformer的架构,包括多头注意力层、位置前馈网络、层归一化等关键组件。
双壁合一

卷积神经网络(CNNS)

CNNs 易于并行化,却不适合捕捉变长序列内的依赖关系。

循环神经网络(RNNS)

RNNs 适合捕捉长距离变长序列的依赖,但是自身的recurrent特性却难以实现并行化处理序列。

整合CNN和RNN的优势,Vaswani et al., 2017 创新性地使用注意力机制设计了 Transformer 模型。


该模型利用 attention 机制实现了并行化捕捉序列依赖,并且同时处理序列的每个位置的 tokens ,上述优势使得 Transformer 模型在性能优异的同时大大减少了训练时间。


如图展示了 Transformer 模型的架构,与机器翻译及其相关技术介绍中介绍的 seq2seq 相似,Transformer同样基于编码器-解码器架构,其区别主要在于以下三点:

  1. Transformer blocks: 循 环 网 络 s e q 2 s e q 模 型 循环网络_{seq2seq模型} seq2seq–> Transformer Blocks

    Transform Blocks模块包含一个多头注意力层(Multi-head Attention Layers)以及两个 position-wise feed-forward networks(FFN)。对于解码器来说,另一个多头注意力层被用于接受编码器的隐藏状态。
  2. Add and norm:多头注意力层和前馈网络的输出被送到两个“add and norm”层进行处理
    该层包含残差结构以及层归一化
  3. Position encoding:由于自注意力层并没有区分元素的顺序,所以一个位置编码层被用于向序列元素里添加位置信息。

Fig. 10.3.1 The Transformer architecture.

T r a n s f o r m e r 架 构 . Transformer 架构. Transformer.

鉴于新子块第一次出现,在此前 CNNS 和 RNNS 的基础上,实现 Transform 子模块,并且就机器翻译及其相关技术介绍中的英法翻译数据集实现一个新的机器翻译模型。

Transformer

import os
import math
import numpy as np
import torch 
import torch.nn as nn
import torch.nn.functional as F
import sys
sys.path.append('path to file storge d2lzh1981')
import d2l

masked softmax

参考 注 意 力 机 制 和 S e q 2 s e q 模 型 工 具 1 注意力机制和Seq2seq模型_{工具1} Seq2seq1

def SequenceMask(X, X_len,value=-1e6):
    maxlen = X.size(1)
    X_len = X_len.to(X.device)
    #print(X.size(),torch.arange((maxlen),dtype=torch.float)[None, :],'\n',X_len[:, None] )
    mask = torch.arange((maxlen), dtype=torch.float, device=X.device)
    mask = mask[None, :] < X_len[:, None]
    #print(mask)
    X[~mask]=value
    return X

def masked_softmax(X, valid_length):
    # X: 3-D tensor, valid_length: 1-D or 2-D tensor
    softmax = nn.Softmax(dim=-1)
    if valid_length is None:
        return softmax(X)
    else:
        shape = X.shape
        if valid_length.dim() == 1:
            try:
                valid_length = torch.FloatTensor(valid_length.numpy().repeat(shape[1], axis=0))#[2,2,3,3]
            except:
                valid_length = torch.FloatTensor(valid_length.cpu().numpy().repeat(shape[1], axis=0))#[2,2,3,3]
        else:
            valid_length = valid_length.reshape((-1,))
        # fill masked elements with a large negative, whose exp is 0
        X = SequenceMask(X.reshape((-1, shape[-1])), valid_length)
 
        return softmax(X).reshape(shape)

# Save to the d2l package.
class DotProductAttention(nn.Module): 
    def __init__(self, dropout, **kwargs):
        super(DotProductAttention, self).__init__(**kwargs)
        self.dropout = nn.Dropout(dropout)

    # query: (batch_size, #queries, d)
    # key: (batch_size, #kv_pairs, d)
    # value: (batch_size, #kv_pairs, dim_v)
    # valid_length: either (batch_size, ) or (batch_size, xx)
    def forward(self, query, key, value, valid_length=None):
        d = query.shape[-1]
        # set transpose_b=True to swap the last two dimensions of key
        scores = torch.bmm(query, key.transpose(1,2)) / math.sqrt(d)
        attention_weights = self.dropout(masked_softmax(scores, valid_length))
        return torch.bmm(attention_weights, value)

多头注意力层


引入:自注意力(self-attention)

自注意力模型是一个正规的注意力模型,序列的每一个元素对应的key,value,query是完全一致的。

与循环神经网络相比,自注意力对每个元素输出的计算是并行的,所以我们可以高效的实现这个模块。

Fig. 10.3.2 自注意力结构

自 注 意 力 结 构 自注意力结构

输 出 了 一 个 与 输 入 长 度 相 同 的 表 征 序 列 输出了一个与输入长度相同的表征序列


多头注意力层包含 h h h并行的自注意力层,每一个这种层被成为一个head。

对每个头来说,在进行注意力计算之前,我们会将query、key和value用三个现行层进行映射,这 h h h个注意力头的输出将会被拼接之后输入最后一个线性层进行整合。

Image Name

多 头 注 意 力 多头注意力

假设query,key和value的维度分别是 d q d_q dq d k d_k dk d v d_v dv。那么对于每一个头 i = 1 , … , h i=1,\ldots,h i=1,,h,我们可以训练相应的模型权重 W q ( i ) ∈ R p q × d q W_q^{(i)} \in \mathbb{R}^{p_q\times d_q} Wq(i)Rpq×dq W k ( i ) ∈ R p k × d k W_k^{(i)} \in \mathbb{R}^{p_k\times d_k} Wk(i)Rpk×dk W v ( i ) ∈ R p v × d v W_v^{(i)} \in \mathbb{R}^{p_v\times d_v} W

去年,谷歌发布了 Google Neural Machine Translation (GNMT),即谷歌神经机器翻译,一个 sequence-to-sequence (“seq2seq”)模型。现在,它已经用于谷歌翻译的产品系统。   虽然消费者感受到的提升并不十分明显,谷歌宣称,GNMT 对翻译质量带来了巨大飞跃。   但谷歌想做的显然不止于此。其在官方博客表示:“由于外部研究人员无法获取训练这些模型的框架,GNMT 的影响力受到了束缚。”   如何把该技术的影响力最大化?答案只有一个——开源。   因而,谷歌于昨晚发布了 tf-seq2seq —— 基于 TensorFlow 的 seq2seq 框架。谷歌表示,它使开发者试验 seq2seq 模型变得更方便,更容易达到一流的效果。另外,tf-seq2seq 的代码库很干净并且模块化,保留了全部的测试覆盖,并把所有功能写入文件。   该框架支持标准 seq2seq 模型的多种配置,比如码器/解码器的深度、注意力机制(attention mechanism)、RNN 单元类型以及 beam size。这样的多功能性,能帮助研究人员找到最优的超参数,也使它超过了其他框架。详情请参考谷歌论文《Massive Exploration of Neural Machine Translation Architectures》。   上图所示,是一个从中文到英文的 seq2seq 翻译模型。每一个时间步骤,码器接收一个汉字以及它的上一个状态(黑色箭头),然后生成输出矢量(蓝色箭头)。下一步,解码器一个词一个词地生成英语翻译。在每一个时间步骤,解码器接收上一个字词、上一个状态、所有码器的加权输出和,以生成下一个英语词汇。雷锋网(公众号:雷锋网)提醒,在谷歌的执行中,他们使用 wordpieces 来处理生僻字词。   据雷锋网了解,除了机器翻译,tf-seq2seq 还能被应用到其他 sequence-to-sequence 任务上;即任何给定输入顺序、需要学习输出顺序的任务。这包括 machine summarization、图像抓取、语音识别、对话建模。谷歌自承,在设计该框架时可以说是十分地仔细,才能维持这个层次的广适性,并提供人性化的教程、预处理数据以及其他的机器翻译功能。   谷歌在博客表示: “我们希望,你会用 tf-seq2seq 来加速(或起步)你的深度学习研究。我们欢迎你对 GitHub 资源库的贡献。有一系列公开的问题需要你的帮助!”   GitHub 地址:https://github.com/google/seq2seq   GitHub 资源库:https://google.github.io/seq2seq/nmt/ 标签:tensorflow  seq2seq  谷歌  机器学习
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值