transformer 翻译模型

google 出品, 基于 encoder-decoder 架构的 seq2seq 自然语言翻译模型. paper 见参考[1].
创新之处是弃用 RNN,CNN 这样的结构, 采用 self-attention 与 positional-encoding 来简化结构, 加速训练, 并提升效果, 取得了 SOTA 成绩.

BLEU 评测指标

BLEU, BiLingual Evaluation Understudy , (译作双向语言评估替工) , 一种自动评测机器翻译的方法.
翻译讲究信达雅, 算是主观题. 之所以采用BLEU评估有两点考虑.

  1. 人力评估成本大.
  2. 便于多个翻译模型之间做对比.

B L E U ∈ ( 0 , 1 ) BLEU\in (0,1) BLEU(0,1), 越大表示翻译越精准. 基本思想是 预测结果的 n-gram 与 测试数据的 n-gram 作对比, n ∈ { 1 , 2 , 3 } n\in \{1,2,3\} n{1,2,3}. 看命中效果.

网络结构

transformer 翻译模型_第1张图片

self-attention

source 与 target 是两个sequence, self-attention 是指对同一sequence内, 各个token间的关联做计算.
论文中把提出的attention 叫 Scaled Dot-Product Attention.
引入三个共享参数矩阵, Query,Key,Value, 对 embedding 后的token做表达的学习.
所谓attention, 就是这么一个映射关系, o u t p u t = f ( q u e r y , { k e y _ v a l u e } ) output=f(query, \{key\_value\} ) output=f(query,{key_value}).
(1) A t t e n t i o n ( Q , K , V ) = s o f t m a x ( Q K T d k ) V Attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt{d_k}})V \tag 1 Attention(Q,K,V)=softmax(dk QKT)V(1)
transformer 翻译模型_第2张图片
图2. o u t p u t = f ( q u e r y , { k e y _ v a l u e } ) output=f(query, \{key\_value\} ) output=f(query,{key_value})的直观图示
M u l t i H e a d ( Q , K , V ) = C o n c a t ( h e a d 1 , . . . , h e a d h ) W O MultiHead(Q,K,V)=Concat(head_1,...,head_h)W^O MultiHead(Q,K,V)=Concat(head1,...,headh)WO
where h e a d i = A t t e n t i o n ( Q W i Q , K W i K , V W i V ) head_i=Attention(QW_i^Q,KW_i^K,VW_i^V) headi=Attention(QWiQ,KWiK,VWiV), W O ∈ R h d v × d m o d e l W^O\in \mathbb R^{hd_v\times d_{model}} WORhdv×dmodel

vanilla attention

除了 source_seq 与 target_seq 各自的 self_attrntion 之外, 还有二者之间的 vanilla_attention. 对应图1 transformer 架构图中, decoder内的第二个 sub-layer. 此时有 vanilla_attention(decoder_Q,encoder_memory_K, encoder_memory_V).

Positional Encoding

mask

decoder中有个特别点就是masking, masking 的作用就是防止在训练的时候 使用未来的输出的单词。比如训练时,第一个单词是不能参考第二个单词的生成结果的。Masking就会把这个信息变成0,用来保证预测位置 i 的信息只能基于比 i 小的输出。

train/predict 不同的 inference

train 阶段, 直接输出整体的 logits #shape=(N, T2, vocab_size) , 与y_ = label_smoothing(tf.one_hot(y, depth=self.hp.vocab_size)) # (N, T2, vocab_size) 计算交叉熵.

在预测阶段, predicts y_hat auto-regressively. 即根据句子Source的中间语义表示C和之前已经生成的历史信息.
y i = g ( C , y 1 , y 2 , . . . , y i − 1 ) y_i=g(C,y_1,y2_,...,y_{i−1}) yi=g(C,y1,y2,...,yi1)
where C C C 为 source sentence 的语义编码.

tf 实现

官方基于tf, 又搞了 tensor2tensor 库, 内含transformer的实现. github 有人基于tf给出了实现, 见参考 [3].

  • 数据集
    Germany_2_English 翻译任务. 为了单机体验完整流程, 控制数据量. 训练集有 19万 样本, 验证集有 993 条样本. 英德的word加起来构成了 size=8000 的 vocabulary.
  • 超参
    v o c a b _ s i z e vocab\_size vocab_size=32000, d _ m o d e l d\_model d_model=512, m a x _ l e n _ s o u r c e = 100 max\_len\_source=100 max_len_source=100, m a x _ l e n _ t a r g e t = 100 max\_len\_target=100 max_len_target=100.
  • input/output
     	xs: tuple of
            x: int32 tensor. (N, T1) . T1为当前batch样本的最长原文长度.
            x_seqlens: int32 tensor. (N,)
            sents1: str tensor. (N,)
        ys: tuple of
            decoder_input: int32 tensor. (N, T2). T2为当前batch样本的最长译文长度.
            y: int32 tensor. (N, T2)
            y_seqlen: int32 tensor. (N, )
            sents2: str tensor. (N,)
    
    transformer 翻译模型_第3张图片
    transformer 翻译模型_第4张图片
  • 主干逻辑
def train(self, xs, ys):
    '''
    Returns
    loss: scalar.
    train_op: training operation
    global_step: scalar.
    summaries: training summary node
    '''
    # forward
    memory, sents1 = self.encode(xs)
    logits, preds, y, sents2 = self.decode(ys, memory)

    # train scheme
    y_ = label_smoothing(tf.one_hot(y, depth=self.hp.vocab_size))
    ce = tf.nn.softmax_cross_entropy_with_logits_v2(logits=logits, labels=y_)
    nonpadding = tf.to_float(tf.not_equal(y, self.token2idx[""]))  # 0: 
    loss = tf.reduce_sum(ce * nonpadding) / (tf.reduce_sum(nonpadding) + 1e-7)

bert

基于双向transformer的预训练语言表达模型.

参考

1.transformer paper, Attention Is All You Need
2. blog, 机器翻译评价指标之BLEU详细计算过程
3. github 非官方实现, transformer
4. blog, 从Encoder-Decoder(Seq2Seq)理解Attention的本质
5. github, bert-use-demo
6. blog, Seq2Seq中的Attention和self-attention

你可能感兴趣的:(NLP)