书接昨日,我们说 Positional Encoding 是人工设计的,那它在原本的论文里面是怎麽设计的呢?
WHY?
我们来看看他们给的说法
We chose this function because we hypothesized it would allow the model to easily learn to attend by relative positions, since for any fixed offset k, PE(pos+k) can be represented as a linear function of PE(pos).
所以作者们认为在 embedding 里加入这样的资讯可以帮助 Transformer 学会 model 序列中的相对位置关系,实际上很难想像出这种操作有用,但反正他们是想到了而且相当有用,不过就算我们无法理解,还是可以从 TensorFlow 官方的实作上面无情的把 Code 复制过来用 XD。
def get_angles(pos, i, d_model):
angle_rates = 1 / np.power(10000, (2 * (i//2)) / np.float32(d_model))
return pos * angle_rates
def positional_encoding(position, d_model):
angle_rads = get_angles(np.arange(position)[:, np.newaxis],
np.arange(d_model)[np.newaxis, :],
d_model)
# apply sin to even indices in the array; 2i
angle_rads[:, 0::2] = np.sin(angle_rads[:, 0::2])
# apply cos to odd indices in the array; 2i+1
angle_rads[:, 1::2] = np.cos(angle_rads[:, 1::2])
pos_encoding = angle_rads[np.newaxis, ...]
return tf.cast(pos_encoding, dtype=tf.float32)
让 Transformer 用来识别序列实际的内容到哪里,因为实际上我们的训练资料长度通常都是不一样的,比较短的会把它补 0 补到一样长,但这些资讯是毫无意义的,我们必须避免让 Transformer 关注到这些位置
# padding mask 的工作就是把序列中为 0 的位置设为 1
padding_mask = tf.cast(tf.equal(seq, 0), tf.float32)
用来确保 Decoder 在进行自注意力机制时只会关注自己之前的资讯,在 "做 attention" 的时候我们的 q 跟 k 是从嵌入张量 [a1..a4] 得到的,这个张量的维度是一个 2 维矩阵,它看起来可能像是这样
[[0.01,0.02,0.03]
[0.04,0.05,0.06]
[0.07,0.08,0.09]]
我们的 Look ahead mask 就会长得像这样
[[0,1,1]
[0,0,1]
[0,0,0]]
写出来就是长这样
look_ahead_mask = 1 - tf.linalg.band_part(tf.ones((size, size)), -1, 0)
那实际上是怎麽操作的呢? 这两种 mask 是可以和在一起使用的
# 产生 comined_mask 只要把两个遮罩取大的即可
combined_mask = tf.maximum(padding_mask, look_ahead_mask)
计算一次 attention
def do_attention(q, k, v, mask):
matmul_qk = tf.matmul(q, k, transpose_b=True)
seq_k_length = tf.cast(tf.shape(k)[-1], tf.float32)
scaled_attention_logits = matmul_qk / tf.math.sqrt(seq_k_length)
# 将 mask 「加」到被丢入 softmax 前的 logits
# 这里的 mask 可以是纯 Padding mask 或是 combined_mask
if mask != None:
# (mask * -1e9) 见下方说明
scaled_attention_logits += (mask * -1e9)
# 取 softmax 是为了得到总和为 1 的比例之後对 `v` 做加权平均
attention_weights = tf.nn.softmax(scaled_attention_logits, axis=-1)
# 以注意权重对 v 做加权平均(weighted average)
return tf.matmul(attention_weights, v)
(mask * -1e9) 这件事可以让这被加上极大负值的位置变得无关紧要,(就是有 1 的地方,我们是不想关注的),在经过 softmax 以後值变会趋近於 0。
到此差不多可以准备做看看 Transformer 了,其实还有很多小细节(尤其是资料维度处理) 的以及 Multi-Head Attention 等到实际做的时候再继续讨论吧。
Transformer model for language understanding
<<: Day08:【TypeScript 学起来】物件型别 Object Types : object
>>: Day 08 - Spring Boot 常用注释(上)
再重新叙述一次问题: 假设n = 878,代表说现在给你1到878个点,在没有资讯前,你看每个点都是...
tensor简介: tensor是在pytorch运算时所使用的资料型态 就像numpy一样,可支持...
更新一下get_iv这支程序 def get_iv(nonce): sha_nonce_value ...
本文同步更新於blog 前情提要:铁路运输系统,参考范例:运输系统(工厂方法模式) <?p...
这边我想特别写出这一篇的原因是当初我在学习与操作 NiFi 的过程中,我曾感到一些疑惑,会觉得感觉...