google 出品, 基于 encoder-decoder 架构的 seq2seq 自然语言翻译模型. paper 见参考[1].
创新之处是弃用 RNN,CNN 这样的结构, 采用 self-attention 与 positional-encoding 来简化结构, 加速训练, 并提升效果, 取得了 SOTA 成绩.
BLEU, BiLingual Evaluation Understudy , (译作双向语言评估替工) , 一种自动评测机器翻译的方法.
翻译讲究信达雅, 算是主观题. 之所以采用BLEU评估有两点考虑.
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}. 看命中效果.
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(dkQKT)V(1)
图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}} WO∈Rhdv×dmodel
除了 source_seq 与 target_seq 各自的 self_attrntion 之外, 还有二者之间的 vanilla_attention. 对应图1 transformer 架构图中, decoder内的第二个 sub-layer. 此时有 vanilla_attention(decoder_Q,encoder_memory_K, encoder_memory_V)
.
decoder中有个特别点就是masking, masking 的作用就是防止在训练的时候 使用未来的输出的单词。比如训练时,第一个单词是不能参考第二个单词的生成结果的。Masking就会把这个信息变成0,用来保证预测位置 i 的信息只能基于比 i 小的输出。
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,...,yi−1)
where C C C 为 source sentence 的语义编码.
官方基于tf, 又搞了 tensor2tensor 库, 内含transformer的实现. github 有人基于tf给出了实现, 见参考 [3].
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,)
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)
基于双向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