深度学习6. 多层感知机及PyTorch实现
- 一、概念
- 1. MLP
- 2. 前向传播
- 3. 反向传播
- 4. 评估模式与训练模式
- 二、模型定义
- 1. 加载数据集
- 2. 定义MLP层
- 3. 前向传播
- 4. 优化器
- 5. 反向传播
- 三、训练
- 四、测试与预测
- 五、预测
- 六、完整代码
一、概念
1. MLP
多层感知机(Multilayer Perceptron)缩写为MLP,也称作前馈神经网络(Feedforward Neural Network)。它是一种基于神经网络的机器学习模型,通过多层非线性变换对输入数据进行高级别的抽象和分类。
与单层感知机相比,MLP有多个隐藏层,每个隐藏层由多个神经元组成,每个神经元通过对上一层的输入进行加权和处理,再通过激活函数进行非线性映射。
MLP的输出层通常是一个 softmax 层,用于多分类任务,或者是一个 sigmoid 层,用于二分类任务。
由于它的强大表达能力和灵活性,MLP被广泛应用于各种机器学习任务中。
2. 前向传播
由于有多个层,参数需要在这些层之间传递。首先需要实现的就是参数的前向传播,计算过程如下:
- 将输入数据传递给第一个隐藏层的神经元;
- 对于每个神经元,计算其加权和,即将输入与对应的权重相乘并求和,再加上偏置项;
- 将加权和输入到激活函数中,得到激活值,作为该神经元的输出;
- 将每个神经元的输出传递到下一层的神经元,直至输出层。
在这个过程中,数据和权重是前向传播的主要传播内容。
3. 反向传播
利用链式法则对网络中的参数进行梯度更新。在训练神经网络时,通常需要定义一个损失函数(loss function),用于评估模型预测结果与真实标签之间的差距。反向传播算法的目标就是最小化这个损失函数。
在反向传播过程中,算法首先计算损失函数对最后一层的输出的梯度,然后根据链式法则逐层向前计算各层的梯度,并利用梯度下降法更新网络中的参数。具体地,算法会先将损失函数对输出的梯度传回网络最后一层,然后依次向前计算各层的梯度。在计算梯度的过程中,算法会利用反向传播公式来计算当前层的梯度,然后将这个梯度传递到前一层。在更新网络参数时,算法会根据计算出的梯度和学习率来更新网络中的权重和偏置。
通过不断地反复迭代前向传播和反向传播两个阶段,可以不断地更新网络中的参数,从而逐渐提高模型的性能。
下面是一个Python计算反向传播的示例:
4. 评估模式与训练模式
- 在训练阶段,需要调用
model.train()
来指定模型为训练模式,以便启用训练中需要的特性,如 dropout
和 batch normalization
等。 - 如果在训练过程中需要评估模型的性能,可以在评估前调用
model.eval()
,以确保模型处于评估模式,而不是训练模式。 - 在测试阶段,需要调用
model.eval()
来指定模型为评估模式,以便禁用 dropout
和 batch normalization
等特性,以及启用测试中需要的特性,如在计算中间层的输出等。 - 在预测阶段,需要调用 model.eval() 来指定模型为预测模式,以便禁用
dropout
和 batch normalization
等特性,并且只计算模型的前向传播,以生成模型的输出,而不更新模型的权重。
二、模型定义
1. 加载数据集
本示例使用 MNIST 数据集。
2. 定义MLP层
下面定义一个有三个层的MLP。
对于这个MLP,它接收一个num_i的输入,输出为num_o的预测值。 隐藏层有2层,每层大小为num_h。
层的定义如下:
- self.linear1:输入层到第一层隐藏层的线性转换,其中num_i为输入的特征数,num_h为第一层隐藏层的特征数。
- self.relu:第一层隐藏层的激活函数,采用ReLU。
- self.linear2:第一层隐藏层到第二层隐藏层的线性转换,其中num_h为第一层隐藏层的特征数,num_h为第二层隐藏层的特征数。
- self.relu2:第二层隐藏层的激活函数,采用ReLU。
- self.linear3:第二层隐藏层到输出层的线性转换,其中num_h为第二层隐藏层的特征数,num_o为输出的特征数(或者说类别数)。
3. 前向传播
在前向传播时,输入x先通过第一层的线性转换,然后经过第一层隐藏层的激活函数,
再通过第二层的线性转换,再经过第二层隐藏层的激活函数,
最后输出预测值。
4. 优化器
本文将使用PyTorch的优化器工具用于反向传播 。
优化器(optimizer)是一个用于更新模型参数的工具,根据训练集的损失函数(loss function)和反向传播算法(backpropagation algorithm)计算梯度,并使用梯度下降算法(gradient descent algorithm)更新模型参数,以最小化损失函数的值。
PyTorch提供了许多常用的优化器,如随机梯度下降法(SGD)、Adam、Adagrad、RMSprop等。
这些优化器使用不同的更新策略,根据不同的训练任务和数据集选择合适的优化器可以提高训练效率和性能。
5. 反向传播
本文使用和PyTorch优化器的一个实例: torch.optim.Adam()
,它使用反向传播算法计算梯度并更新模型的权重,从而调整模型参数以最小化损失函数。
三、训练
四、测试与预测
五、预测
在神经网络模型的推断(inference)阶段中,我们不需要进行反向传播,也不需要计算梯度,使用 with torch.no_grad()
: 上下文管理器可以有效地减少内存消耗和计算时间
-
output
是模型在给定输入数据后的输出结果,每一行对应一个输入数据样本,每一列对应一个可能的输出类别。 -
output.data
提取出了output
中的数据部分,然后使用max()
函数沿着第1个维度(即列)找到每一行中最大的值以及对应的索引。 -
keepdim=True
参数使得输出结果保持和输入数据output
相同的维度。因此,pred
包含每个输入样本的预测类别,是一个包含预测标签索引的一维张量
六、完整代码