文章目录
- What(是什么)
- Where(用在哪)
- How(怎么用)
- 多层感知机解决分类问题(以`minist`分类为例)
- 多层感知机解决回归问题
- 多层感知机解决噪声处理的问题
What(是什么)
多层感知机(Multilayer Perceptron,MLP)是一种基本的前馈人工神经网络,由多层神经元组成。它是一种全连接(fully connected)的神经网络
多层感知机的特点:
- 多层结构: MLP 至少包含三层:输入层(Input Layer)、至少一个隐藏层(Hidden Layer)、输出层(Output Layer)。隐藏层可以有多个,通常在两个以上。
- 全连接: 每一层的神经元与上一层的所有神经元都有连接。这意味着每个神经元都接收上一层所有神经元的输入,并将自己的输出传递给下一层的所有神经元。
- 非线性激活函数: 在每个隐藏层和输出层的神经元上使用非线性激活函数,如ReLU(Rectified Linear Unit)、sigmoid 或 tanh(双曲正切函数),以使神经网络能够学习复杂的非线性关系。
- 训练方法: MLP 使用反向传播算法(Backpropagation)和优化器(如随机梯度下降)来训练网络,通过最小化损失函数来调整网络参数
一个典型的多层感知机:
可以看到,感知机的每一层之间采用全连接的方式连接,且感知机最少具有1个隐藏层。
Where(用在哪)
多层感知机的应用场景非常广泛,包括但不限于以下场景:
-
非线性分类问题:与简单的感知机不同,MLP 可以通过多个隐藏层和非线性激活函数来学习和表示复杂的非线性决策边界。这使得它能够处理那些线性不可分的数据集,如手写数字识别(MNIST 数据集)和图像分类。
-
回归问题:MLP 可以用来预测连续值,例如股票价格预测、房价预测等。输出层可以是一个或多个神经元,根据具体问题的需求。
-
模式识别和特征学习:MLP 在处理复杂的模式识别任务时表现出色,例如语音识别、人脸识别等。通过多层的特征提取和组合,MLP 能够学习到更高级的数据表示。
-
序列数据处理:虽然传统的 MLP 不适合处理序列数据,但可以通过一些变种结构(如循环神经网络或者结合卷积神经网络)来处理时间序列数据、文本数据等。
-
噪声数据的处理:MLP 可以通过训练来适应并处理部分噪声存在的数据,使得在实际应用中能够更加鲁棒地处理各种复杂场景。
How(怎么用)
多层感知机解决分类问题(以minist
分类为例)
方式1:调用torch.nn手动构建全连接网络模型来实现MLP模型
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):
super(MLP, self).__init__()
self.fc1 = nn.Linear(28 * 28, 128) # 输入大小为图像大小 28x28,输出大小为128
self.fc2 = nn.Linear(128, 64) # 隐藏层大小为64
self.fc3 = nn.Linear(64, 10) # 输出层大小为10,对应10个数字类别
def forward(self, x):
x = x.view(-1, 28 * 28) # 将图像展平成向量
x = torch.relu(self.fc1(x)) # 第一层:ReLU激活函数
x = torch.relu(self.fc2(x)) # 第二层:ReLU激活函数
x = self.fc3(x) # 输出层,不用激活函数,因为后面会用CrossEntropyLoss
return x
# 设置训练参数
batch_size = 64
learning_rate = 0.001
num_epochs = 10
# 加载MNIST数据集
train_dataset = datasets.MNIST(root='./data', train=True, transform=transforms.ToTensor(), download=True)
test_dataset = datasets.MNIST(root='./data', train=False, transform=transforms.ToTensor())
train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)
# 初始化模型、损失函数和优化器
model = MLP()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
# 训练模型
for epoch in range(num_epochs):
for batch_idx, (data, targets) in enumerate(train_loader):
optimizer.zero_grad()
outputs = model(data)
loss = criterion(outputs, targets)
loss.backward()
optimizer.step()
if (batch_idx + 1) % 100 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Step [{batch_idx+1}/{len(train_loader)}], Loss: {loss.item():.4f}')
# 在测试集上评估模型
model.eval()
with torch.no_grad():
correct = 0
total = 0
for data, targets in test_loader:
outputs = model(data)
_, predicted = torch.max(outputs.data, 1)
total += targets.size(0)
correct += (predicted == targets).sum().item()
print(f'Accuracy on test set: {100 * correct / total:.2f}%')
方式2:使用sklearn自动构建MLP模型
from sklearn.neural_network import MLPClassifier
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 加载MNIST数据集
mnist = fetch_openml('mnist_784', version=1)
X, y = mnist['data'], mnist['target']
# 数据预处理和划分
X = X / 255.0 # 将像素值缩放到 [0, 1] 区间
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 定义MLP分类器模型
mlp_clf = MLPClassifier(hidden_layer_sizes=(100, 50), max_iter=10, alpha=1e-4,
solver='adam', verbose=10, random_state=42,
learning_rate_init=0.001)
# 训练模型
mlp_clf.fit(X_train, y_train)
# 预测并评估模型
y_pred = mlp_clf.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy on test set: {accuracy * 100:.2f}%')
多层感知机解决回归问题
from sklearn.neural_network import MLPRegressor
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
# 生成一个简单的回归数据集
X, y = make_regression(n_samples=1000, n_features=10, noise=0.1, random_state=42)
# 划分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 定义MLP回归模型
mlp_reg = MLPRegressor(hidden_layer_sizes=(50, 25), max_iter=500, alpha=0.001,
solver='adam', random_state=42)
# 训练模型
mlp_reg.fit(X_train, y_train)
# 预测并评估模型
y_pred = mlp_reg.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
print(f'Mean Squared Error on test set: {mse:.2f}')
多层感知机解决噪声处理的问题
MLP去噪的实质,是使用多层感知机的回归模型,通过训练数据来拟合一条回归曲线,来实现去噪的功能。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neural_network import MLPRegressor
# 生成带噪声的信号数据
np.random.seed(0)
X = np.linspace(0, 10, 100).reshape(-1, 1)
y_true = np.sin(X).ravel()
noise = np.random.normal(0, 0.1, y_true.shape)
y_noisy = y_true + noise
# 划分数据集为训练集和测试集
X_train, X_test, y_train, y_test = X[:80], X[80:], y_noisy[:80], y_noisy[80:]
# 定义MLP回归模型
mlp_reg = MLPRegressor(hidden_layer_sizes=(50, 25), max_iter=500, alpha=0.001,
solver='adam', random_state=42)
# 训练模型
mlp_reg.fit(X_train, y_train)
# 预测并评估模型
y_pred_train = mlp_reg.predict(X_train)
y_pred_test = mlp_reg.predict(X_test)
# 绘制结果
plt.figure(figsize=(10, 6))
plt.scatter(X_train, y_train, color='blue', label='Training data with noise')
plt.plot(X_train, y_true[:80], color='green', linestyle='--', linewidth=2, label='True underlying function')
plt.plot(X_train, y_pred_train, color='red', linewidth=2, label='MLP predicted function (train)')
plt.plot(X_test, y_pred_test, color='orange', linewidth=2, label='MLP predicted function (test)')
plt.title('MLP for Noise Removal')
plt.legend()
plt.xlabel('X')
plt.ylabel('y')
plt.show()