用自己语言理解transform原理

67 阅读4分钟

先说结构,再说里面最重要的注意力机制,需要经过前馈神经网络层( FeedForward )/残差/归一化等处理,得到输出下一个词的概率。transformer通过自注意力机制,找到语义关系。

45c9cbd67d0f8e3b3ec43c800e09b46c.jpg

transformer的原理:通过头部文件超参数实现encoder decoder,encoder 是转换为向量,每一轮decoder都会把encoder 的输出结果加入到某个隐藏层,decoder的输出会作为下一轮decoder的输入。

decoder中有多头注意力机制,然后经过liner softmax输出结果。

里面最重要的注意力机制:head 可以当做注意力机制的一个“量词”,一个head 就是一组QKV计算

单头注意力的计算方法: 第1步,初始化输入


>>> head_size = 16 # 人为定义的注意力维度
>>> x = torch.randn(1, 8, 16)  # 单批次 (B=1), 8个token, 每个token 16维特征
>>> B, T, C = x.shape  # B=1, T=8, C=16

第2步:计算 Key/Query/Value 第3步:计算注意力分数 (Q·Kᵀ) 并缩放 第4步:应用掩码 第5步:Softmax 归一化 第6步:聚合 Value

总结:公式如下 image.png

  • 图片是查询矩阵,维度为图片,n是查询数量;

  • 图片是键矩阵,维度为图片,m是键的数量;

  • 图片是值矩阵,维度为图片,m是值的数量(与键的数量相同);

  • 图片是键和查询的维度;

  • 图片是缩放因子,用于防止点积过大导致梯度消失;

根据得到的张量,我们可以预测“下一个token”,比如out[1] 是用token1 ~ 2的信息计算而来,用来预测token3 。

multi-head只是对多个head的concat 操作、

引入FeedForward(FFN通过ReLU激活引入非线性,使模型能拟合更复杂的函数)、

残差神经网络:直接把输入x跨层传递到后续层,解决训练中出现的梯度消失问题。 Add指 X+MultiHeadAttention(X),是一种残差连接,通常用于解决多层网络训练的问题,可以让网络只关注当前差异的部分,在 ResNet 中经常用到.

投影(Projection):是一种将输入数据从当前向量空间映射到另一个向量空间的操作,在我们的实现中,就是简单的一个线性层。

层归一化(Layer Normalization, LayerNorm ) :就是Norm,神经网络中,层归一化(Layer Normalization, LayerNorm) 是一种用于加速训练、提升模型稳定性的重要技术,LayerNorm 对单个样本的所有特征进行归一化,使其均值为0、方差为1,再通过可学习的参数调整分布。

Dropout:是一种广泛使用的正则化技术,旨在防止神经网络过拟合。它通过随机丢掉部分神经元的结果,来迫使模型学习更鲁棒的特征表示.

为什么必须用Linear和Softmax这两层?

Linear层:从抽象特征到词语分数的映射

image.png

类比解释
假设模型在处理句子“我想吃__”,解码器输出一个向量表示“期待食物类词语”。Linear层将这个向量与所有词语的嵌入向量做点积,计算出每个词的匹配分数(如“苹果”=9.5,“跑步”=1.2)。

  • Linear的必要性:

解码器输出的向量是抽象语义,需转换为具体词语的匹配度。 直接输出词嵌入空间的点积效率更高(比计算5万次相似度快)。

  • Softmax的必要性:

模型需要概率形式的输出来支持交叉熵损失计算(如预测“苹果”概率90% vs 标签100%,计算损失)。 概率化后的结果可直接用于贪婪解码(选最高概率)或采样(按概率随机选)。

“Linear层把模型的抽象思考转成词语分数,Softmax层将分数变为概率,二者共同决定了Transformer最终说出的词。”

Softmax层:从分数到概率的终极转换

image.png

核心作用: 将Linear层输出的分数转换为概率分布,使所有词语的概率和为1,并放大高分值的优势。

指数运算:将分数差异放大(例如  9.5→exp(9.5)=13,360,1.2→exp(1.2)=3.32)。

归一化:计算每个词的概率占比(如“苹果”概率为13,360/(13,360+3.32+...其他词)≈99%)。

超参数

比如

-batch_size = 32 # 每个批次的大小
-block_size = 8 # 每个序列的最大长度
-learning_rate = 1e-2 # 学习率
-n_embed = 32 # 嵌入层的维度
-n_head = 4 # 多头注意力的头数
-n_layer = 3# block的数量
+batch_size = 64 # 每个批次的大小
+block_size = 256 # 每个序列的最大长度
+learning_rate = 3e-4 # 学习率
+n_embed = 384 # 嵌入层的维度
+n_head = 6 # 多头注意力的头数
+n_layer = 6# block的数量

调整参数,可以确定多大的模型,比如: 调整前,是一个3层、4头、32维度,参数量为437,764的“K级超小模型”。

调整后,是一个6层、6头、384维度,参数量为15,466,756的“15M模型”,至少也能用B做单位了,是一个“0.0155B”的模型

参考:mp.weixin.qq.com/s/4eiuLipNX…

blog.csdn.net/qq_52099920…