Attention is all you need – #4.5 Tokenizer 与 Embedding
前言
OMG我忘了还要先学怎么得到正确答案和怎么把词转换成向量了,这篇博客我就来研究研究嘿嘿
Tokenizer
Tokenizer 究竟是什么呢?
Tokenizer 负责将文本拆分为 Token,并把这些 Token 转换为整数 ID。随后,Embedding 层根据这些 ID,从可训练的 Embedding 矩阵中取出对应向量,作为神经网络的输入。
比如:
vocab = {
"我": 0,
"爱": 1,
"你": 2
}
text = "我爱你"
tokens = [vocab[ch] for ch in text]
print(tokens) # [0, 1, 2]
不过这样一个一个设定也太累了,我们可以直接扫描训练语料,按照字符首次出现的顺序建立词表
corpus = "我爱你你爱我"
chars = list(dict.fromkeys(corpus))
vocab = {ch: i for i, ch in enumerate(chars)}
Embedding
Embedding 是一个形状为 V\times d 的可训练矩阵。前向传播时,根据 Token ID 查找对应行,将长度为 T 的序列转换为 T\times d 的向量矩阵。
它是一个可训练的参数矩阵,用来将离散的 Token ID 映射为连续的向量表示
其中:
- E:Embedding 矩阵
- V:词表大小(Vocabulary Size)
- d_{\text{model}}:每个 Token 对应的向量维度
- E_{i,j}:第 i 个 Token 的向量中,第 j 个分量
矩阵的每一行对应一个 Token 的向量。
假设 99GPT v0:
- 词表大小 V=4
- 向量维度 d_{\text{model}}=3
那么:
假设 Token「我」的 ID 是 2,那么:
如果有多个 Token ID ,假设输入 Token ID 序列是:
直接取出对应的三行:
于是:
其中 n 是输入序列的 Token 数量。
Embedding 矩阵不是固定的词典,而是通过反向传播不断学习的参数。
初始化时每行可以是随机向量,训练过程中根据 Loss 的梯度更新被使用的行,从而逐渐形成有用的 Token 表示。
来一道题~
假设 99GPT 的词表有 100 个 Token,每个 Token 对应 64 维向量,输入句子被编码成 5 个 Token ID。
Embedding 矩阵 E 和输出矩阵 X 的维度分别是什么?
答案是 E:100\times64,\quad X:5\times64 !
Embedding的反向传播
先记住一句话:
Embedding 的反向传播,本质上就是把输入向量的梯度累加回 Embedding 矩阵对应的行。
假设:
输入 Token ID 为:
那么前向传播:
前向传播之后不是得返回梯度嘛,梯度这时候回来了,最终传给 Embedding 输出 X 的梯度为:
因为 X 的第 0 行来自 E 的第 0 行,第 1 行来自 E 的第 2 行,因此直接把梯度放回对应位置:
从链式法则来理解
回忆你之前学习的神经网络:
Embedding 也是一样。
对于 X_{k,j}=E_{T_k,j},有:
说人话就是
某个 Token ID 在输入中出现几次,就把那些位置传回来的梯度全部累加到同一行。
比如:
如果前两个位置的梯度分别为:
那么E 的第 0 行梯度就是:
最后和神经网络一样,通过学习率更新:
这就是基本的Tokenizer和Embedding!!!
评论(1)