视频详细讲解:LLM模型:代码讲解Transformer运行原理(1)_哔哩哔哩_bilibili
1 概述
经过Transformer的12个块处理完之后,4批文本数据得到了一个矩阵[4, 8, 16],也就是每批数据都训练出了一个结果,在训练阶段,这个结果的作用是跟目标标签计算损失值,然后通过反向传播更新各个权重向量;在推理阶段就是输出每个字的向量表,目的是拿着这个向量表计算一个概率值,最大概率值就是输出结果了。
【训练数据】
【线性变换数据】
2 线性变换原理
2.1线性变换的作用
nn.Linear
层的作用就是:
- 通过乘法(权重)来调整输入数据。
- 通过加法(偏置)来添加一个基础值。
这样,输入数据经过简单的数学运算后,变成一个更有意义的输出数据。这个过程在神经网络中反复进行,最终帮助我们做出准确的预测。
2.2 线性变换实现
self.model_out_linear_layer = nn.Linear(model_dimension, max_token_value+1)
linear_predictions = self.model_out_linear_layer(transformer_train_data)
这段代码定义了一个线性层,并使用这个线性层对一些训练数据进行前向传播。具体来说,nn.Linear
是PyTorch中的一个模块(类),用于创建一个线性变换的层,通常在神经网络中作为全连接层来使用。
-
self.model_out_linear_layer = nn.Linear(model_dimension, max_token_value+1)
:- 这一行创建了一个
nn.Linear
实例,并将其赋值给self.model_out_linear_layer
。 nn.Linear
接受两个参数:输入特征的数量(在这里是model_dimension
)和输出特征的数量(在这里是max_token_value + 1
)。model_dimension
通常是来自模型前一层的输出维度,例如,它可能是Transformer编码器或解码器的最后一层的隐藏状态维度。max_token_value + 1
表示输出层的大小,可能对应于词汇表的大小或者你希望预测的最大值加一(因为索引是从0开始的)。
- 这一行创建了一个
-
linear_predictions = self.model_out_linear_layer(transformer_train_data)
:- 这一行使用之前定义的线性层对
transformer_train_data
进行前向传播。 transformer_train_data
应该是具有与model_dimension
相同特征数量的数据,这通常是Transformer模型的输出。self.model_out_linear_layer
将这些输入映射到一个新的空间,其维度为max_token_value + 1
。linear_predictions
是线性层的输出,可以被看作是对下一个词或其他目标的未归一化的概率(即原始分数或logits)。
- 这一行使用之前定义的线性层对
通常情况下,在训练阶段之后,这些线性预测会被传递给一个损失函数(比如交叉熵损失函数)以计算模型的误差,并且在推理阶段,可能会应用softmax函数将logits转换成概率分布,以便进行采样或选择最有可能的输出。
2.3 线性变换原理
2.3.1 线性变换计算公式
矩阵乘法加上偏置项。有一个输入向量 x,经过一个线性层 L 后,得到的输出向量 y 可以表示为:
y=Wx+b
其中:
- W是一个权重矩阵,它的尺寸是输出特征数乘以输入特征数。
- x是输入向量,它的尺寸是输入特征数。
- b是一个偏置向量,它的尺寸是输出特征数。
- y是输出向量,它的尺寸是输出特征数。
权重矩阵 W会在训练过程中不断更新。权重矩阵 W和偏置向量 b都是神经网络中的可学习参数。它们会在训练过程中通过优化算法(如梯度下降或其变种)进行更新,以最小化损失函数。
以下是权重矩阵如何更新的一个简要流程:
-
初始化:
- 在训练开始时,权重矩阵 W 和偏置向量 b通常会被随机初始化(如使用正态分布或均匀分布)。
-
前向传播:
- 在每个训练步骤中,输入数据通过神经网络进行前向传播,生成预测输出。
-
计算损失:
- 使用损失函数(如均方误差、交叉熵等)来衡量预测输出与真实标签之间的差距。
-
反向传播:
- 通过反向传播算法计算损失函数相对于每个权重的梯度。这意味着计算每个权重对损失的影响程度。
- 反向传播本质上是应用链式法则来计算梯度,从输出层一直回传到输入层。
-
权重更新:
- 根据计算出的梯度和选择的优化算法(如随机梯度下降SGD、Adam等),这里使用的是Adam,更新权重矩阵 W 和偏置向量 b
2.3.2 具体步骤:
- 输入数据:假设你有一批数据,每条数据是一个长度为
input_features
的向量。 - 权重矩阵:
nn.Linear
模块内部维护一个权重矩阵W
,尺寸为[output_features, input_features]
。 - 偏置向量:同样,
nn.Linear
模块内部还有一个偏置向量b
,尺寸为[output_features]
。 - 矩阵乘法:每个输入向量 x与权重矩阵 W进行矩阵乘法。
- 加上偏置:将上述结果与偏置向量 b相加,得到最终的输出向量 y。
2.3.3 示例
假设你有以下参数:
- 输入特征数
input_features = 10
- 输出特征数
output_features = 5
那么,nn.Linear
层将接收一个形状为 [batch_size, 10]
的输入张量,并输出一个形状为 [batch_size, 5]
的张量。
2.3.4 代码示例
1import torch
2import torch.nn as nn
3
4# 假设输入特征数为10,输出特征数为5
5model_dimension = 10
6max_token_value = 4 # 词汇表大小为5
7
8# 创建线性层
9linear_layer = nn.Linear(model_dimension, max_token_value + 1)
10
11# 假设有一个批次的训练数据,batch_size为3
12transformer_train_data = torch.randn(3, model_dimension)
13
14# 前向传播
15output = linear_layer(transformer_train_data)
16
17print(output.shape) # 应该输出 (3, 5)
在这个例子中:
transformer_train_data
是一个形状为[3, 10]
的张量,表示有3个样本,每个样本有10个特征。- 经过
nn.Linear
层后,输出的张量形状为[3, 5]
,表示每个样本现在有5个特征(或说5个输出值)。
这个输出可以被看作是对每个样本的一组预测值或原始分数(logits),通常用于后续的处理,如应用激活函数(如softmax)来获得概率分布。
2.4 线性变换通俗原理
假设你要调制饮料
你正在调制一杯饮料,你需要根据不同的配料来调整饮料的味道。你有两样主要的配料:糖和柠檬汁。
输入
- 你有一个杯子,里面已经有了一定量的水。
- 你准备往里面加入糖和柠檬汁。
线性变换
你想要通过加糖和柠檬汁来调整饮料的味道。具体来说:
- 糖的比例:每加一勺糖,会让甜度增加 2 分。
- 柠檬汁的比例:每加一勺柠檬汁,会让酸度增加 1 分。
此外,你还希望饮料本身有一定的基础甜度和酸度。
具体步骤
- 糖的比例(权重):假设你加了 3 勺糖。
- 柠檬汁的比例(权重):假设你加了 2 勺柠檬汁。
- 基础甜度和酸度(偏置):假设饮料本身就有 1 分甜度和 1 分酸度。
计算
- 甜度 = (糖的量 × 糖的比例)+ 基础甜度
- 酸度 = (柠檬汁的量 × 柠檬汁的比例)+ 基础酸度
具体来说:
- 甜度 = (3 × 2) + 1 = 7 分
- 酸度 = (2 × 1) + 1 = 3 分
结果
最终,你的饮料有 7 分甜度和 3 分酸度。
类比 nn.Linear
在 nn.Linear
层中:
- 糖的比例和柠檬汁的比例 相当于权重矩阵 W。
- 基础甜度和酸度 相当于偏置向量 b。
- 加糖和柠檬汁 相当于输入向量 x。
- 最终的甜度和酸度 相当于输出向量 y。
数学表达
用数学公式表示就是:
y=Wx+b
在这个例子中:
通过简单的乘法和加法,你得到了最终的甜度和酸度。
3 什么是前向传播
想象一下你在玩一个很长的流水线游戏。在这个游戏中,你有一个球,你需要通过一系列的障碍物来让这个球到达终点。这些障碍物就像是游戏中的不同关卡,而你的目标就是通过每一关,最后让球顺利到达目的地。
在神经网络中,数据就像是那个球,而每一层神经网络就像游戏中的一个关卡。前向传播就是让数据从网络的开始一直传递到结束的过程,就像让球从游戏的第一个关卡一直滚到最后一个关卡一样。
具体来说:
- 输入层:这是起点,你把球(即数据)放在这里。
- 隐藏层:这些是中间的关卡,每一个关卡都会改变球的状态。比如,球的颜色可能会变,或者球的形状可能会变。在神经网络中,每一层都会对数据做一些数学运算,改变数据的样子,让它变得更符合我们需要的形式。
- 输出层:这是终点,球经过所有关卡后到达的地方。在这里,球已经变成了我们想要的样子,比如它可能代表了一个预测结果。
所以,前向传播就是让数据通过神经网络的所有层,从输入层开始,一层接一层地传递,直到输出层,得到最终的结果。这个过程不需要人为干预,数据会自动按照每层设定好的规则流动。
在训练过程中,我们会比较最终的结果与实际需要的结果之间的差异,然后调整整个游戏(神经网络)的规则(权重),使得下一次前向传播时,球能更接近正确的目标位置。这就是为什么我们要进行前向传播的主要原因——为了得到预测结果,并且在训练过程中不断改进这些结果。