全连接神经网络,又称多层感知机(MLP),是深度学习最基础的神经网络。全连接神经网络主要由输入层、隐藏层和输出层构成。本文实现了一个通用MLP网络,包括以下功能:
- 根据输入的特征数、类别数、各隐藏层神经元数量构建一个MLP网络;
- 可以指定隐藏层的激活函数(默认为F.relu);
- 可以指定输出层的激活函数(默认回归无激活函数,分类激活函数为F.softmax)。
代码如下:
from typing import Optional
import numpy as np
from sklearn.preprocessing import StandardScaler, MinMaxScaler
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.optim import SGD, Adam
from process import classify, regress
#procss的代码见:https://blog.csdn.net/moyao_miao/article/details/141466047
# https://blog.csdn.net/moyao_miao/article/details/141497342
class MLP(nn.Module):
"""通用MLP网络
"""
def __init__(self, feature_num: int, class_num: int, *hidden_nums: int,
fc_activation: nn.Module = F.relu, output_activation: Optional[nn.Module] = None):
"""
初始化MLP网络
:param feature_num: 输入特征数
:param class_num: 输出类别数
:param hidden_nums: 隐藏层神经元数
:param fc_activation: 隐藏层激活函数,默认为F.relu
:param output_activation: 输出层激活函数,默认回归无激活函数,分类激活函数为F.softmax
"""
super().__init__()
self.feature_num = feature_num
self.class_num = class_num
self.hidden_nums = hidden_nums
self.fc_activation = fc_activation
self.output_activation = output_activation
input_num = feature_num
# 定义隐藏层
for i, hidden_num in enumerate(hidden_nums):
self.__dict__['_modules']['fc' + str(i)] = nn.Linear(input_num, hidden_num)
input_num = hidden_num
self.output = nn.Linear(input_num, class_num)
def forward(self, x):
# 定义网络的向前传播路径
for i in range(len(self.hidden_nums)):
x = self.fc_activation(self.__dict__['_modules']['fc' + str(i)](x))
if self.output_activation is not None:
x = self.output_activation(self.output(x))
else:
x = self.output(x)[..., 0] if self.class_num == 1 else F.softmax(self.output(x), dim=-1)
return x
关于隐藏层定义的详细说明见:【求助帖(已解决)】用PyTorch搭建MLP网络时遇到奇怪的问题-CSDN博客
下面举两个例子测试一下效果:
一、垃圾邮件分类
from ucimlrepo import fetch_ucirepo
spambase = fetch_ucirepo(id=94)
X = np.array(spambase.data.features)
y = np.array(spambase.data.targets.iloc[:, 0])
model = MLP(57, 2, 30, 10)
optimizer = Adam(model.parameters(), lr=0.01)
criterion = nn.CrossEntropyLoss()
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
classify(
(X, y),
model,
optimizer,
criterion,
scaler=MinMaxScaler(feature_range=(0, 1)),
batch_size=64,
epochs=10,
device=device,
)
分类效果:
二、波士顿房价预测
from sklearn.datasets import fetch_california_housing
house_data = fetch_california_housing()
model = MLP(8, 1, 100, 100, 50)
optimizer = SGD(model.parameters(), lr=0.01)
criterion = nn.MSELoss()
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
regress(
(house_data.data, house_data.target),
model,
optimizer,
criterion,
scaler=StandardScaler(),
batch_size=64,
epochs=30,
device=device,
)
预测效果: