逐行讲解Transformer的代码实现和原理讲解:前馈神经网络

视频详细讲解(一行一行代码讲解实现过程):

1 前馈神经网络处理视图

2 神经元

3 Relu激活函数

Relu激活函数作用是将小于或者等于0的数据,转换成0,正数不变。

假设我们有一个简单的神经网络层,该层有3个神经元,每个神经元在前向传播过程中计算出的输出分别为:-2、0、4。接下来,我们将使用ReLU激活函数来处理这些输出值。

ReLU激活函数的定义:

这意味着,对于任何输入值x,如果x大于0,则输出为𝑥本身;如果x小于或等于0,则输出为0。

4 其它激活函数类型

5 线性变换概述

经过Transformer的12个块处理完之后,4批文本数据得到了一个矩阵[4, 8, 16],也就是每批数据都训练出了一个结果,在训练阶段,这个结果的作用是跟目标标签计算损失值,然后通过反向传播更新各个权重向量;在推理阶段就是输出每个字的向量表,目的是拿着这个向量表计算一个概率值,最大概率值就是输出结果了。

【训练数据】

【线性变换数据】

5 线性变换原理

5.1线性变换的作用

nn.Linear 层的作用就是:

  1. 通过乘法(权重)来调整输入数据。
  2. 通过加法(偏置)来添加一个基础值。

这样,输入数据经过简单的数学运算后,变成一个更有意义的输出数据。这个过程在神经网络中反复进行,最终帮助我们做出准确的预测。

5.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中的一个模块(类),用于创建一个线性变换的层,通常在神经网络中作为全连接层来使用。

  1. 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开始的)。
  2. 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转换成概率分布,以便进行采样或选择最有可能的输出。

5.3 线性变换原理

5.3.1 线性变换计算公式

矩阵乘法加上偏置项。有一个输入向量 x,经过一个线性层 L 后,得到的输出向量 y 可以表示为:

y=Wx+b

其中:

  • W是一个权重矩阵,它的尺寸是输出特征数乘以输入特征数。
  • x是输入向量,它的尺寸是输入特征数。
  • b是一个偏置向量,它的尺寸是输出特征数。
  • y是输出向量,它的尺寸是输出特征数。

权重矩阵 W会在训练过程中不断更新。权重矩阵 W和偏置向量 b都是神经网络中的可学习参数。它们会在训练过程中通过优化算法(如梯度下降或其变种)进行更新,以最小化损失函数。

以下是权重矩阵如何更新的一个简要流程:

  1. 初始化

    • 在训练开始时,权重矩阵 W 和偏置向量 b通常会被随机初始化(如使用正态分布或均匀分布)。
  2. 前向传播

    • 在每个训练步骤中,输入数据通过神经网络进行前向传播,生成预测输出。
  3. 计算损失

    • 使用损失函数(如均方误差、交叉熵等)来衡量预测输出与真实标签之间的差距。
  4. 反向传播

    • 通过反向传播算法计算损失函数相对于每个权重的梯度。这意味着计算每个权重对损失的影响程度。
    • 反向传播本质上是应用链式法则来计算梯度,从输出层一直回传到输入层。
  5. 权重更新

    • 根据计算出的梯度和选择的优化算法(如随机梯度下降SGD、Adam等),这里使用的是Adam,更新权重矩阵 W 和偏置向量 b

5.3.2 具体步骤:

  1. 输入数据:假设你有一批数据,每条数据是一个长度为 input_features 的向量。
  2. 权重矩阵nn.Linear 模块内部维护一个权重矩阵 W,尺寸为 [output_features, input_features]
  3. 偏置向量:同样,nn.Linear 模块内部还有一个偏置向量 b,尺寸为 [output_features]
  4. 矩阵乘法:每个输入向量 x与权重矩阵 W进行矩阵乘法。
  5. 加上偏置:将上述结果与偏置向量 b相加,得到最终的输出向量 y。

5.3.3 示例

假设你有以下参数:

  • 输入特征数 input_features = 10
  • 输出特征数 output_features = 5

那么,nn.Linear 层将接收一个形状为 [batch_size, 10] 的输入张量,并输出一个形状为 [batch_size, 5] 的张量。

5.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)来获得概率分布。

5.4 线性变换通俗原理

假设你要调制饮料

你正在调制一杯饮料,你需要根据不同的配料来调整饮料的味道。你有两样主要的配料:糖和柠檬汁。

输入

  • 你有一个杯子,里面已经有了一定量的水。
  • 你准备往里面加入糖和柠檬汁。

线性变换

你想要通过加糖和柠檬汁来调整饮料的味道。具体来说:

  1. 糖的比例:每加一勺糖,会让甜度增加 2 分。
  2. 柠檬汁的比例:每加一勺柠檬汁,会让酸度增加 1 分。

此外,你还希望饮料本身有一定的基础甜度和酸度。

具体步骤

  1. 糖的比例(权重):假设你加了 3 勺糖。
  2. 柠檬汁的比例(权重):假设你加了 2 勺柠檬汁。
  3. 基础甜度和酸度(偏置):假设饮料本身就有 1 分甜度和 1 分酸度。

计算

  • 甜度 = (糖的量 × 糖的比例)+ 基础甜度
  • 酸度 = (柠檬汁的量 × 柠檬汁的比例)+ 基础酸度

具体来说:

  • 甜度 = (3 × 2) + 1 = 7 分
  • 酸度 = (2 × 1) + 1 = 3 分

结果

最终,你的饮料有 7 分甜度和 3 分酸度。

类比 nn.Linear

nn.Linear 层中:

  • 糖的比例和柠檬汁的比例 相当于权重矩阵 W。
  • 基础甜度和酸度 相当于偏置向量 b。
  • 加糖和柠檬汁 相当于输入向量 x。
  • 最终的甜度和酸度 相当于输出向量 y。

数学表达

用数学公式表示就是:

y=Wx+b

在这个例子中:

通过简单的乘法和加法,你得到了最终的甜度和酸度。

6 什么是前向传播

想象一下你在玩一个很长的流水线游戏。在这个游戏中,你有一个球,你需要通过一系列的障碍物来让这个球到达终点。这些障碍物就像是游戏中的不同关卡,而你的目标就是通过每一关,最后让球顺利到达目的地。

在神经网络中,数据就像是那个球,而每一层神经网络就像游戏中的一个关卡。前向传播就是让数据从网络的开始一直传递到结束的过程,就像让球从游戏的第一个关卡一直滚到最后一个关卡一样。

具体来说:

  • 输入层:这是起点,你把球(即数据)放在这里。
  • 隐藏层:这些是中间的关卡,每一个关卡都会改变球的状态。比如,球的颜色可能会变,或者球的形状可能会变。在神经网络中,每一层都会对数据做一些数学运算,改变数据的样子,让它变得更符合我们需要的形式。
  • 输出层:这是终点,球经过所有关卡后到达的地方。在这里,球已经变成了我们想要的样子,比如它可能代表了一个预测结果。

所以,前向传播就是让数据通过神经网络的所有层,从输入层开始,一层接一层地传递,直到输出层,得到最终的结果。这个过程不需要人为干预,数据会自动按照每层设定好的规则流动。

在训练过程中,我们会比较最终的结果与实际需要的结果之间的差异,然后调整整个游戏(神经网络)的规则(权重),使得下一次前向传播时,球能更接近正确的目标位置。这就是为什么我们要进行前向传播的主要原因——为了得到预测结果,并且在训练过程中不断改进这些结果。

 7 学习率、梯度下降

学习率会在梯度下降时用到,如果学习率太低,会导致梯度下降太慢,学习时间太长;如果学习率太高,会导致梯度跳动太大,无法收敛。

  • 20
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值