一文读懂「Attention is All You Need」| 附代码实现

前言

2017 年中,有两篇类似同时也是笔者非常欣赏的论文,分别是 FaceBook 的Convolutional Sequence to Sequence Learning和 Google 的Attention is All You Need,它们都算是 Seq2Seq 上的创新,本质上来说,都是抛弃了 RNN 结构来做 Seq2Seq 任务。

在本篇文章中,笔者将对Attention is All You Need做一点简单的分析。当然,这两篇论文本身就比较火,因此网上已经有很多解读了(不过很多解读都是直接翻译论文的,鲜有自己的理解),因此这里尽可能多自己的文字,尽量不重复网上各位大佬已经说过的内容。

序列编码

深度学习做 NLP 的方法,基本上都是先将句子分词,然后每个词转化为对应的词向量序列。这样一来,每个句子都对应的是一个矩阵 X=(x1,x2,…,xt),其中 xi 都代表着第 i 个词的词向量(行向量),维度为 d 维,故

。这样的话,问题就变成了编码这些序列了。


第一个基本的思路是 RNN 层,RNN 的方案很简单,递归式进行:

不管是已经被广泛使用的 LSTM、GRU 还是最近的 SRU,都并未脱离这个递归框架。RNN 结构本身比较简单,也很适合序列建模,但 RNN 的明显缺点之一就是无法并行,因此速度较慢,这是递归的天然缺陷。

另外我个人觉得RNN 无法很好地学习到全局的结构信息,因为它本质是一个马尔科夫决策过程

第二个思路是 CNN 层,其实 CNN 的方案也是很自然的,窗口式遍历,比如尺寸为 3 的卷积,就是:

在 FaceBook 的论文中,纯粹使用卷积也完成了 Seq2Seq 的学习,是卷积的一个精致且极致的使用案例,热衷卷积的读者必须得好好读读这篇文论。

CNN 方便并行,而且容易捕捉到一些全局的结构信息,笔者本身是比较偏爱 CNN 的,在目前的工作或竞赛模型中,我都已经尽量用 CNN 来代替已有的 RNN 模型了,并形成了自己的一套使用经验,这部分我们以后再谈。

Google的大作提供了第三个思路:纯 Attention,单靠注意力就可以。

阅读原文

### 关于 'Attention Is All You Need' 的源码实现 在探索《Attention Is All You Need一文中提出的Transformer模型时,多个开源项目提供了该模型的具体实现。对于希望深入理解并实践这一开创性工作的研究者而言,TensorFlow 和 PyTorch 是两个广泛使用的框架。 #### TensorFlow 实现 一份详尽的基于 TensorFlow 的实现可以在 GitHub 上找到[^2]。此版本不仅包含了完整的 Transformer 架构,还带了丰富的注释帮助读者更好地理解每一部分的功能。具体来说: - **编码器(Encoder)**: 编码输入序列中的信息; - **解码器(Decoder)**: 解析来自编码器的信息来生成目标序列; - **多头注意力机制(Multi-head Attention Mechanism)**: 提升模型捕捉不同位置间关系的能力; ```python import tensorflow as tf class MultiHeadAttention(tf.keras.layers.Layer): def __init__(self, d_model, num_heads): super(MultiHeadAttention, self).__init__() assert d_model % num_heads == 0 depth = d_model // num_heads self.wq = tf.keras.layers.Dense(d_model) self.wk = tf.keras.layers.Dense(d_model) self.wv = tf.keras.layers.Dense(d_model) self.dense = tf.keras.layers.Dense(d_model) def split_heads(self, x, batch_size): """Split the last dimension into (num_heads, depth).""" ... def call(self, v, k, q, mask=None): ... ``` 这段代码展示了如何构建一个多头自注意层,这是整个架构的核心组件之一。通过这种方式可以有效地提高模型性能,并允许更复杂的模式识别能力。 #### 输出层设计 最终,在完成所有必要的计算之后,输出层会应用 Softmax 函数以获得每个可能单词的概率分布,从而选出最有可能的结果作为预测值[^3]。 ```python def output_layer(logits): probabilities = tf.nn.softmax(logits, axis=-1) predictions = tf.argmax(probabilities, axis=-1) return predictions ``` 上述方法确保了即使面对大量候选词的情况下也能稳定地挑选出最佳选项。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值