MLP(Multilayer Perceptron, 多层感知机)是一种人工神经网络模型,属于前馈神经网络的一种形式。它是由多个神经元(或称为节点)组成的,每个神经元都通过权重与其他神经元连接。MLP 是深度学习中的基础结构之一,通常用于解决分类、回归等问题。
MLP 的结构
MLP 由三种主要的层组成:
-
输入层(Input Layer): 输入层是网络的第一层,每个神经元接收来自外部数据的输入(例如,图像的像素值、文本的特征等)。每个神经元对应一个输入特征。
-
隐藏层(Hidden Layers): 隐藏层是输入层和输出层之间的层。MLP 可以有多个隐藏层,这些层通过加权和偏置进行计算,每一层的输出都通过激活函数进行处理。隐藏层可以捕捉输入数据的复杂模式,进行非线性转换。
-
输出层(Output Layer): 输出层产生最终的预测结果,输出层的神经元数量通常取决于任务类型。例如,对于分类任务,输出层的神经元数可能等于类别数,而对于回归任务,输出层通常只有一个神经元。
MLP 的工作原理
MLP 的工作原理可以通过以下步骤进行描述:
-
前向传播(Forward Propagation):
-
输入数据通过输入层传入网络。
-
输入数据在每个隐藏层进行加权和偏置计算,并通过激活函数(如 ReLU、Sigmoid、Tanh 等)进行非线性变换。
-
最终,数据传递到输出层,得到网络的预测结果。
-
-
损失函数(Loss Function):
-
网络输出结果与真实标签之间的差距通过损失函数计算出来,常见的损失函数有均方误差(MSE)和交叉熵损失(Cross-Entropy Loss)等。
-
-
反向传播(Backpropagation):
-
根据损失函数的结果,通过反向传播算法计算每一层的梯度。
-
使用梯度下降优化算法(如SGD、Adam等)更新权重和偏置,优化网络的性能。
-
MLP 的特点
-
全连接结构:每一层的每个神经元都与前一层的所有神经元相连接,因此也叫全连接层(Fully Connected Layer)。
-
非线性映射:通过激活函数的引入,MLP 能够学习和表示输入数据的非线性关系。
-
适用性广:MLP 可用于分类、回归等多种任务,尤其在输入数据结构较为简单时表现较好。
示例:简单的 MLP 结构
假设我们有一个包含 3 个输入特征的数据集,并且任务是二分类问题。一个简单的 MLP 结构可以如下所示:
-
输入层:3 个神经元(每个对应一个输入特征)
-
隐藏层:2 个神经元
-
输出层:1 个神经元(输出0或1,表示二分类结果)
公式:
假设在某一隐藏层的输出为:
其中:
-
w 是权重矩阵
-
x 是输入数据
-
b 是偏置项
-
σ是激活函数(如 ReLU、Sigmoid 等)
在输出层,最终的输出可以表示为:
y=σ(W′h+b′)
下面是一个简单的 Multilayer Perceptron (MLP) 示例代码,使用 PyTorch 来实现一个多层感知机进行手写数字分类任务(使用MNIST数据集)。
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader# 定义一个简单的多层感知机(MLP)类
class MLP(nn.Module):def __init__(self, input_size, hidden_size, output_size):super(MLP, self).__init__()# 定义第一层隐藏层self.fc1 = nn.Linear(input_size, hidden_size)# 定义第二层隐藏层self.fc2 = nn.Linear(hidden_size, hidden_size)# 定义输出层self.fc3 = nn.Linear(hidden_size, output_size)# 定义激活函数self.relu = nn.ReLU()def forward(self, x):# 前向传播过程x = self.relu(self.fc1(x)) # 第一层 + 激活函数x = self.relu(self.fc2(x)) # 第二层 + 激活函数x = self.fc3(x) # 输出层return x# 超参数设置
input_size = 28 * 28 # 每张图片是28x28像素
hidden_size = 128 # 隐藏层神经元数量
output_size = 10 # MNIST 数据集有10个数字类别
batch_size = 64 # 每个batch的大小
learning_rate = 0.001 # 学习率
epochs = 5 # 训练5轮# 加载MNIST数据集
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)
test_loader = DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)# 创建MLP模型
model = MLP(input_size, hidden_size, output_size)# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss() # 分类任务使用交叉熵损失
optimizer = optim.Adam(model.parameters(), lr=learning_rate)# 训练过程
for epoch in range(epochs):model.train() # 设置模型为训练模式running_loss = 0.0correct = 0total = 0for inputs, labels in train_loader:# 将输入数据转换为适合MLP的形状(batch_size, input_size)inputs = inputs.view(inputs.size(0), -1)# 清零梯度optimizer.zero_grad()# 前向传播outputs = model(inputs)# 计算损失loss = criterion(outputs, labels)# 反向传播loss.backward()# 更新参数optimizer.step()# 累积损失和正确预测数running_loss += loss.item()_, predicted = torch.max(outputs, 1)correct += (predicted == labels).sum().item()total += labels.size(0)epoch_loss = running_loss / len(train_loader)epoch_accuracy = 100 * correct / totalprint(f'Epoch [{epoch+1}/{epochs}], Loss: {epoch_loss:.4f}, Accuracy: {epoch_accuracy:.2f}%')# 测试过程
model.eval() # 设置模型为评估模式
correct = 0
total = 0with torch.no_grad():for inputs, labels in test_loader:inputs = inputs.view(inputs.size(0), -1)outputs = model(inputs)_, predicted = torch.max(outputs, 1)correct += (predicted == labels).sum().item()total += labels.size(0)test_accuracy = 100 * correct / total
print(f'Test Accuracy: {test_accuracy:.2f}%')
我们定义了一个包含两个隐藏层的多层感知机模型。每一层都使用 ReLU
激活函数进行非线性映射。模型的结构是:输入层 -> 隐藏层1 -> 隐藏层2 -> 输出层。
使用 Adam优化器 和 交叉熵损失函数 来训练模型。在每一轮训练中,我们会遍历所有训练数据,并根据损失反向传播更新网络参数。在训练完成后,我们在测试集上评估模型的准确率。
pip install torch torchvision
Epoch [1/5], Loss: 0.3012, Accuracy: 91.12%
Epoch [2/5], Loss: 0.1551, Accuracy: 95.09%
Epoch [3/5], Loss: 0.1134, Accuracy: 96.83%
Epoch [4/5], Loss: 0.0861, Accuracy: 97.83%
Epoch [5/5], Loss: 0.0692, Accuracy: 98.33%
Test Accuracy: 97.99%
本文所讨论的全连接神经网络(FCN)即为只包含全连接层的MLP。对于批量输入,每个全连接层中的基本操作包括密集的矩阵乘法和激活函数(例如sigmoid函数)。这些操作被串联起来,以实现神经网络的过滤过程。图中展示了全连接神经网络中串联操作的过程。图中的FCN包含了4层:输入层、两个隐藏层和输出层。输入层有356个输入,第一隐藏层有30个神经元,第二隐藏层有20个神经元,输出层有5个输出。每一层的激活函数都是sigmoid函数,并且输入是批量处理的。这个神经网络的实现涉及三个串联操作,也就是说前一个操作的结果将成为下一个操作的输入。第一个操作为C1 = Sigm(IN1 * W1 + Bias1),它发生在数据从输入层传递到第一隐藏层时。第二个操作为C2 = Sigm(C1 * W2 + Bias2),发生在第一隐藏层和第二隐藏层之间。最后一个操作为C3 = Sigm(C2 * W3 + Bias3),发生在第二隐藏层和输出层之间。这里,Sigm表示sigmoid函数。输入矩阵IN1是由批量输入向量形成的,批量大小用batches表示。每层的权重矩阵分别为W1、W2和W3,偏置矩阵分别为Bias1、Bias2和Bias3。结果矩阵(例如C1和C2)作为输入矩阵用于下一个操作。这就形成了一个操作链。
https://xilinx.github.io/Vitis_Libraries/hpc/2021.1/user_guide/L1/mlp_intr.html