提要:读论文感觉很乏味,主要是迷迷糊糊,还是直接看源码理解更容易懂
参考链接:Attention Is All You Need(Transformer)详解以及代码复现_all is your need transform-优快云博客
在 NLP 中,为什么用 LN 而不是 BN(面试常见!)-优快云博客
源码参考:Multi-Headed Attention (MHA)
理解attention:如何理解计算机视觉中的注意力机制? - 陈大宝的回答 - 知乎
https://www.zhihu.com/question/485458547/answer/3095487808
一、Input Embedding
1、概念
在深度学习中,嵌入(embedding)是将离散的、稀疏的输入数据(如单词、字符或其他类别数据)映射到一个低维、连续的向量空间的技术。
传统的独热编码将每个单词表示为一个高维、稀疏的向量(例如,词汇表有10,000个词汇,每个词都对应一个10,000维的独热向量,其中只有一个元素为1,[0,0,0,1,0,...]这样),向量的维度高、稀疏且不包含单词之间的语义信息。而通过嵌入层,每个单词被映射为一个较低维的密集向量,如5维或100维的连续数值向量。
nn.Embedding :是 PyTorch 中的一个模块,用于创建一个嵌入层(embedding layer)
import torch
import torch.nn as nn
# 定义词汇表大小和嵌入向量维度
vocab_size = 10 # 词汇表大小
embedding_dim = 5 # 嵌入向量维度
# 创建嵌入层:用词汇表大小和嵌入维度创建一个嵌入层
embedding_layer = nn.Embedding(num_embeddings=vocab_size, embedding_dim=embedding_dim)
# 输入张量(单词索引),假设输入是一个batch的单词索引序列
input_tensor = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.long) # 示例输入,形状为 (batch_size, sequence_length)
# 通过嵌入层得到嵌入向量
embedding_output = embedding_layer(input_tensor)
print(f"Input Tensor Shape: {input_tensor.shape}")
print(f"Embedding Output Shape: {embedding_output.shape}")
print(f"Embedding Output:\n{embedding_output}")
"""
Input Tensor Shape: torch.Size([2, 3])
Embedding Output Shape: torch.Size([2, 3, 5])
Embedding Output:
tensor([[[ 0.0069, 0.0465, -0.0205, 0.0080, -0.0114],
[-0.0244, 0.0404, 0.0452, -0.0027, -0.0307],
[ 0.0024, -0.0043, 0.0340, 0.0370, -0.0400]],
[[ 0.0057, -0.0015, -0.0154, -0.0306, -0.0375],
[ 0.0317, -0.0275, 0.0160, 0.0283, 0.0040],
[-0.0331, -0.0061, 0.0452, 0.0484, -0.0350]]], grad_fn=<EmbeddingBackward0>)
"""
小结:按照句子中单词的索引,输出这个句子排序的单词的嵌入表示。(每个句子包含 3 个单词,每个单词用一个 5 维的向量表示)
嵌入层权重矩阵:假设词汇表大小是 vocab_size
,嵌入维度是 d_model
,则嵌入层的权重矩阵大小为 (vocab_size, d_model)
。在嵌入层中,每个单词的索引会指向这矩阵中的一行,这行就作为该单词的嵌入向量。
2、论文原文
要将生成的嵌入 乘以 嵌入维度d_model 的开根号,来进行缩放(scaled)
原理:
二、Positional Encoding
1、概念
attention没有时序信息,但实际上在序列中token(词元)和token之间的位置是有用的。所以这里自己加入时序信息——序列顺序。通过引入位置编码,我们可以向神经网络提供关于单词在序列中位置的信息,从而使网络能够区分不同位置的单词并更好地处理序列数据。
2、论文原文
position encoding的维度和embedding维度一致,便于相加;
本文采用的Encoding:
举例:
pos
代表位置,i
代表维度
理解:使用正弦和余弦函数生成的向量是平滑的和连续的。这意味着相邻位置的编码向量非常相似,因此模型可以利用这种相似性来捕捉相邻单词之间的关系。PE(pos) 和PE(pos+k) 之间会有一种线性关系。总的来说,位置编码中含有相对位置信息。模型能够通过学习 PE(pos)和 PE(pos+k)之间的关系来理解单词之间的相对距离。简单来说,如果它们相似,那么模型会推断相邻的单词更可能有较强的关联。
参考: