# NumPyMultilayerPerceptron
**Repository Path**: dreamwing-zy/NumPyMultilayerPerceptron
## Basic Information
- **Project Name**: NumPyMultilayerPerceptron
- **Description**: 一个用NumPy从零实现的多层感知机。提供几乎所有基本功能。适用于分类和回归任务。这个仓库包含一个多层感知机的框架,实现中除了一个从SciPy导入的函数外,只使用了NumPy。这个项目受到了TensorFlow和PyTorch的启发。随着你探索得越深入,你将会注意到用这个框架构建模型与TensorFlow的风格相似。另外,一些具体的实现的源码则受PyTorch的影响。
- **Primary Language**: Python
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2024-07-15
- **Last Updated**: 2025-05-13
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
[English](README.md) | 中文版
# 用NumPy从零实现多层感知机
**目录**
- [1. 简介](#sparkles-1-简介)
- [2. 一个玩具样例](#sparkles-2-一个玩具样例)
- [3. 关键模块](#sparkles-3-关键模块)
- [3.1. Activations](#31-activations)
- [3.2. 层 (Layers)](#32-层-layers)
- [3.3. 优化器 (Optimizers)](#33-优化器-optimizers)
- [3.4. 学习率调度器 (Learning Rate Scheduler)](#34-学习率调度器-learning-rate-scheduler)
- [3.5. 回调 (Callbacks)](#35-回调-callbacks)
- [4. 教程](#sparkles-4-教程)
- [5. 在一个复杂的数据集上测试](#sparkles-5-在一个复杂的数据集上测试)
- [6. 项目结构](#sparkles-6-项目结构)
- [7. 更新日志](#sparkles-7-更新日志)
多层感知机
:tada: **令人兴奋的消息!**
为了顺利的体验,我们现在将我们的项目通过启动Jupyter笔记本整合至谷歌Colab。立刻点击下方按钮探索吧!
[](https://colab.research.google.com/github/XavierSpycy/NumPyMultilayerPerceptron/blob/main/mlp_quickstart.ipynb)
:pushpin: **重要**:
为了访问我们的仓库中的所有文件,确保您运行在这个笔记本中的`Setup` 代码块。这个`Toy Example`部分展示了我们下面的玩具样例。这个`Pipeline` 部分提供了一个在`run.py`中的直接的流程。请注意,相较于我们的本地设置,Colab中的训练时间或许不同。这个完整的训练大约花费58分钟(这取决于分配的虚拟机)。如果这个时间太长,考虑减少轮次数直到训练时长令您满意。
## :sparkles: 1. 简介
这个仓库包含一个多层感知机的框架,实现中除了一个从SciPy导入的函数外,只使用了NumPy。这个项目受到了TensorFlow和PyTorch的启发。随着你探索得越深入,你将会注意到用这个框架构建模型与TensorFlow的风格相似。另外,一些具体的实现的源码则受PyTorch的影响。如果你热衷于理解这个框架的设计和用法,那我们一起深入了解吧!
## :sparkles: 2. 一个玩具样例
让我们一起探索一个玩具样例。
首先,我们需要导入必要的模块。
```python
import numpy as np
import matplotlib.pyplot as plt
from nn.mlp import MultilayerPerceptron
from nn.layers import Dense
```
接着,我们需要生成一些随机数据点。请注意,为了复现性,应该设置一个随机种子。
```python
np.random.seed(3407)
class_1 = np.hstack([np.random.normal( 1, 1, size=(500, 2)), np.ones(shape=(500, 1))])
class_2 = np.hstack([np.random.normal(-1, 1, size=(200, 2)), -np.ones(shape=(200, 1))])
dataset = np.vstack([class_1, class_2])
X, y = dataset[:,:2], dataset[:,2]
```
我们一起快速地看一下它们的样子。
```python
plt.figure(figsize=(6, 6))
plt.scatter(class_1[:,0], class_1[:,1], label='1')
plt.scatter(class_2[:,0], class_2[:,1], label='-1')
plt.grid()
plt.legend()
plt.show()
```
随机数据点
看起来很酷!我们一起构建我们的模型。
```python
layers = [
Input(2),
Dense(units=4, activation='leaky_relu', init='kaiming_normal', init_params={'mode': 'out'}),
Dense(units=3, activation='hardswish', init='xavier_normal'),
Dense(units=2, activation='relu', init='kaiming_normal', init_params={'mode': 'in'}),
Dense(units=1, activation='tanh', init='xavier_uniform')
]
mlp = MultilayerPerceptron(layers)
mlp.compile(optimizer='Adam',
metrics=['MeanSquareError'])
mlp.fit(X, y, epochs=3, batch_size=8, use_progress_bar=True)
```
当然, 在我们的实现中, 上述的过程等价于:
```python
mlp = MultilayerPerceptron()
mlp.add(Input(2))
mlp.add(Dense(units=4, activation='leaky_relu', init='kaiming_normal', init_params={'mode': 'out'}))
mlp.add(Dense(units=3, activation='hardswish', init='xavier_normal'))
mlp.add(Dense(units=2, activation='relu', init='kaiming_normal', init_params={'mode': 'in'}))
mlp.add(Dense(units=1, activation='tanh', init='xavier_uniform'))
```
我们已经完成它了。简单吧?那就是我们想要的!
我们来检查一下它随轮次的损失。
```python
mlp.plot_loss()
```
随轮次的损失
不错!它看起来如期运行。
最后,我们一起看一下我们模型的决策边界。
决策边界
**那棒极了!!**
## :sparkles: 3. 关键模块
### 3.1 Activations
因为该项目由一项作业演变而来,求导由手动完成而非自动。如有需要,可随意修改。
- 公式:
$\mathrm{Tanh}(x) = \mathrm{tanh}(x) = \frac{\mathrm{exp}(x) - \mathrm{exp}(-x)}{\mathrm{exp}(x) + \mathrm{exp}(-x)}$
- Tanhshrink
- 公式:
$\mathrm{Tanhshrink}(x) = x − \mathrm{tanh}(x)$
- Hardtanh
- Sigmoid
- 公式:
$\mathrm{Sigmoid}(x) = \sigma(x) = \frac{1}{1 + \mathrm{exp}(-x)}$
- LogSigmoid
- 公式:
$\mathrm{LogSigmoid}(x) = \mathrm{log}(\frac{1}{1 + \mathrm{exp}(-x)})$
- Hardsigmoid
- ReLU
- 公式:
$\mathrm{ReLU}(x) = \mathrm{max}(0, x)$
- ReLU6
- 公式:
$\mathrm{ReLU6}(x) = \mathrm{min}(\mathrm{max}(0,x),6)$
- Leaky relu
- 公式:
$\mathrm{LeakyReLU}(x) = \mathrm{max}(0,x) + \alpha * \mathrm{min}(0,x)$
- ELU
- CELU
- 公式:
$\mathrm{CELU}(x) = \mathrm{max}(0,x) + \mathrm{min}(0, \alpha * (\mathrm{exp}(x/\alpha) − 1))$
- SELU
- 公式:
$\mathrm{SELU}(x) = \mathrm{scale} * (\mathrm{max}(0,x) + \mathrm{min}(0, \alpha * (\mathrm{exp}(x) − 1)))$
- GELU
- 公式:
$\mathrm{GELU}(x) = 0.5 * x * (1 + \mathrm{Tanh}(\sqrt{\frac{2}{\pi}})) * (x + 0.044715 * x^3)$
- Mish
- 公式:
$\mathrm{Mish}(x) = x * \mathrm{Tanh}(\mathrm{Softplus}(x))$
- Swish
- 公式:
$\mathrm{Swish}(x) = x * \sigma(x)$
- Hardswish
- Softplus
- 公式:
$\mathrm{Softplus}(x)= \frac{1}{\beta} * \mathrm{log}(1 + \mathrm{exp}(\beta * x))$
- SoftSign
- 公式:
$\mathrm{SoftSign}(x) = \frac{x}{1 + \vert x \vert}$
- SoftShrinkage
- HardShrink
- Threshold
注意,因为GitHub的markdown不支持分段函数,一些函数的公式并未提供。
### 3.2 层 (Layers)
- **Dense**
- 稠密层 Dense Layer(全连接层 Fully Connected Layer)
- **定义**:
一个稠密层,也称为全连接层,是神经网络中的一个层,其中所有的输入节点(或神经元)与每一个输出节点连接。它冠以“全连接”或者“稠密”,是因为所有的输入和输出都是互相连接的。
- **数学表示:**:
$y = f(Wx + b)$
- **BatchNorm**
- 批量归一化(Batch Normalization)
- **定义**:
批量归一化是用于神经网络中的一项技术,以标准化给点输入层在小批量上的激活函数,它有助于标准化和加速训练过程。
- **数学表示:**:
For a given mini-batch, $B$, of size $m$, with activations $x$:
$\mu_B = \frac{1}{m}\Sigma_{i=1}^m x_i$
$\sigma_B^2 = \frac{1}{m}\Sigma_{i=1}^m (x_i - \mu_B)^2$
$\hat {x_i} = \frac{x_i - \mu_B}{\sqrt{\sigma_B^2 + \epsilon}}$
$y_i = \gamma \hat {x_i} + \beta$
- **Dropout**:
- **定义**:
丢弃法(Dropout)是一个用于神经网络中的正则化技术,其中,在训练过程中,神经元的随机子集在每次迭代中被“丢弃”(即,设为0)。这避免了网络过于依赖任意特定的神经元,促使一个更加泛化的模型。
- **Activ**:
- 激活层(Activation Layer)
- **定义**:
在神经网络中的激活层是一层将非线性函数用于它的输入,转化数据以引入非线性至模型中。这样的非线性使得网络从错误中学习并做出调整,这是学习复杂模式的关键。
### 3.3 优化器 (Optimizers)
- SGD (含 Momentum 和 Nesterov)
- 必需参数: `lr`
- 默认参数:`momentum=0.0`, `nesterov=False`, `weight_decay=0.0`
- Adagrad
- 必需参数: None
- 默认参数:`lr=1.0`, `weight_decay=0.0`, `epsilon=1e-10`
- Adadelta
- 必需参数: None
- 默认参数:`lr=1.0`, `rho=0.9`, `epsilon=1e-06`, `weight_decay=0.0`
- Adam
- 必需参数: None
- 默认参数:`lr=1e-3`, `beta1=0.9`, `beta2=0.999`, `epsilon=1e-08`, `weight_decay=0.0`
### 3.4 学习率调度器 (Learning Rate Scheduler)
状态:稳定 - 达到预期效果
- StepLR
- 必需参数:`optimizer`, `step_size`
- 默认参数:`gamma=0.1`
- ConstantLR
- 必需参数:`optimizer`
- 默认参数:`factor=1./3`, `total_iters=5`
- MultiStepLR
- 必需参数:`optimizer`, `milestones`
- 默认参数:`gamma=0.1`
### 3.5 回调 (Callbacks)
状态:稳定 - 达到预期效果(~~当前处于测试阶段~~)
- 早停法 (EarlyStopping):
- 必需参数: `criterion`
- 默认参数:`min_delta=0.0`, `patience=5`, `mode='min'`, `restore_best_weights=False`
## :sparkles: 4. 教程
### 4.1 正则化(Regularization)
在前面的玩具样例中,模型结构是:
```python
layers = [
Input(2),
Dense(units=4, activation='leaky_relu', init='kaiming_normal', init_params={'mode': 'out'}),
Dense(units=3, activation='hardswish', init='xavier_normal'),
Dense(units=2, activation='relu', init='kaiming_normal', init_params={'mode': 'in'}),
Dense(units=1, activation='tanh', init='xavier_uniform')
]
```
假设我们的训练数据相对简单,正则化并不严格必要。然而,如果模型开始过拟合,考虑应用正则化技术。在这样的情况下,层应当构建如下:
```python
from nn.layers import BatchNorm, Dropout, Activ
layers = [
Input(2),
Dense(units=4, init='kaiming_normal', init_params={'mode': 'out'}),
BatchNorm(4),
Activ('leaky_relu'),
Dropout(dropout_rate=0.2),
Dense(units=3, init='xavier_normal'),
BatchNorm(3),
Activ('hardswish'),
Dropout(dropout_rate=0.2),
Dense(units=2, init='kaiming_normal', init_params={'mode': 'in'}),
BatchNorm(2),
Activ('relu'),
Dropout(dropout_rate=0.2),
Dense(units=1, activation='tanh', init='xavier_uniform')
]
```
当使用正则化时,按照这个顺序:Linear -> BatchNorm -> Activ -> Dropout。
正则化后的决策边界
### 4.2 优化器(Optimizer)
当训练模型时,优化器在玩具样例中可以有如下定义:
```python
mlp.compile(optimizer='Adam',
metrics='MeanSquareError')
mlp.fit(X, y, epochs=3)
```
训练过程将使用默认的优化器。然而,它也是可以自定义的:
- SGD
```python
optimizer = SGD(lr=1e-2)
```
- SGD with momentum:
```python
optimizer = SGD(lr=1e-2, momentum=0.9)
```
- Nesterov SGD:
```python
optimizer = SGD(lr=1e-2, momentum=0.9, nesterov=True)
```
在定义优化器后,编译这个模型:
```python
mlp.compile(optimizer=optimizer,
metrics=['MeanSquareError'])
```
对于使用默认设置时,这两个方法是等价的:
```python
mlp.compile(optimizer='Adam',
metrics=['MeanSquareError'])
```
和
```python
mlp.compile(optimizer=Adam(),
metrics=['MeanSquareError'])
```
用SGD的损失
### 4.3 损失函数
不仅仅可以使用`MeanSquareError`,您还可以使用`CrossEntropy`。更有意思的是,独热编码作为内置方法已提供,所以您无需传入预处理后的数据给模型。但是,请确保传入模型的数据是数值编码的。
当用`CrossEntropy`编译模型时,您将看到:
用交叉熵的决策边界
### 4.4 学习率调度器(Learning Rate Scheduler)
在训练中动态调整学习率对于优化模型性能是关键的。为此目的,学习率调度器提供了一类方法。如下所示,来自`nn.schedules`的`MultiStepLR`在特定的`milestones`处调整学习率。
```python
from nn.schedules import MultiStepLR
mlp = MultilayerPerceptron(layers)
optimizer = Adam(lr=1e-3, weight_decay=0.02)
scheduler = MultiStepLR(optimizer, milestones=[100, 200, 300, 400], gamma=0.8)
mlp.compile(optimizer=optimizer,
metrics=['CrossEntropy'],
scheduler=scheduler)
```
下图提供了学习率调整的可视化表示。注意,这些`跳跃`对应了特定的`milestones`:
用MultiStepLR的随轮次的损失
正如可以从图中推断的,这个学习率调度器显著地提升了模型的性能。
### 4.5 保存和加载我们的模型
我们提供了保存和加载模型的方法。
- 如何保存?
```python
# Assume mlp is a trained model
mlp.save('mlp.pickle')
```
- 如何加载?
```python
mlp = MultilayerPerceptron.load('mlp.pickle')
```
### 4.6 进度条整合
在我们最近的更新中,我们整合了来自`tqdm` 库的`tqdm()`函数。尽管这个优化不提供训练中的实时指标,但它引入了进度条。该进度条不仅仅可视化了每个轮次的消耗时间,还预计完成的时间。
在训练过程中,以下的输出将会显示在终端:
```47%|████████████████████████████████████████████████████████████▏ | 237/500 [10:15<11:26, 2.61s/it]```
## :sparkles: 5. 在一个复杂的数据集上测试
### 5.1 数据集概况
我们的数据集,包括训练集和测试集,**极度均衡**。特征数是128,标签类别是从0至9的整数。值得注意的是,在我们的实现中,多层感知机自动对它们独热编码。每个类别在训练集中有5000个样本,在测试集中有1000个样本。**数据集已于Oct. 2, 2023的更新中发布。**
我们也已用谷歌Colab的内置数据集(MNIST & California Housing Price)进行测试。您可以在`Quick Start`部分下的Jupyter笔记本中找到更多细节。
### 5.2 按步指南
#### 步骤 1. 导入必需的库和模块
注意,如果其它的优化器或正则化方法是必要的,则确保它们也被导入。
```python
import numpy as np
from datasets.data_loader import datasets
from nn.mlp import MultilayerPerceptron
from nn.layers import Dense, Dropout
from nn.optim import Adam
from sklearn.metrics import accuracy_score as accuracy
```
#### 步骤 2. 加载数据集
确保标签被构造成一维数列,具备形状(number_of_samples, )。否则,它可能引发错误。
```python
X_train, y_train = datasets(train=True)
X_test, y_test = datasets(train=False)
print(f"The shape of X_train is {X_train.shape}, and the shape of y_train is {y_train.shape}.")
print(f"The classes in y_train are: {np.unique(y_train)}.")
```
输出:
```
The shape of X_train is (50000, 128), and the shape of y_train is (50000,).
The classes in y_train are: [0 1 2 3 4 5 6 7 8 9].
```
#### 步骤 3. 查看标签分布
对于不平衡的数据集,您可能需要使用预处理技术。
```python
train_label_dist = dict.fromkeys(np.unique(y_train), 0)
test_label_dist = dict.fromkeys(np.unique(y_test), 0)
for y in y_train:
train_label_dist[y] += 1
for y in y_test:
test_label_dist[y] += 1
print(train_label_dist)
print(test_label_dist)
```
输出:
```
{6: 5000, 9: 5000, 4: 5000, 1: 5000, 2: 5000, 7: 5000, 8: 5000, 3: 5000, 5: 5000, 0: 5000}
{3: 1000, 8: 1000, 0: 1000, 6: 1000, 1: 1000, 9: 1000, 5: 1000, 7: 1000, 4: 1000, 2: 1000}
```
#### 步骤 4. 构建多层感知机
为了确保复现性,我们在这里已经设置一个随机种子。选定的架构基于过往深度学习任务的经验。请不要犹豫实验您自己的设计。由于我们具体的实现,一些激活函数可能计算性密集。谨慎选择。
该架构
```python
np.random.seed(3407)
layers = [
Input(128),
Dense(units=120, activation='elu', init='kaiming_uniform'),
Dropout(dropout_rate=0.25),
Dense(units=112, init='kaiming_uniform'),
Dropout(dropout_rate=0.20),
Dense(units=96, activation='elu', init='kaiming_uniform'),
Dropout(dropout_rate=0.15),
Dense(units=64, activation='elu', init='kaiming_uniform'),
Dropout(dropout_rate=0.10),
Dense(units=48, activation='elu', init='kaiming_uniform'),
Dropout(dropout_rate=0.05),
Dense(units=32, activation='elu', init='kaiming_uniform'),
Dense(units=24, activation='elu', init='kaiming_uniform'),
Dense(units=16, activation='elu', init='kaiming_uniform'),
Dense(units=10, activation='softmax')
]
mlp = MultilayerPerceptron(layers)
mlp.compile(optimizer=Adam(lr=1e-3, weight_decay=0.02),
metrics=['CrossEntropy', 'Accuracy'])
```
#### 步骤 5. 训练模型并展示其指标
```python
mlp.fit(X_train, y_train, epochs=500, batch_size=32)
loss = mlp.loss_tracker()
train_time = mlp.training_time()
print(f'Training time: {train_time:.2f} second(s).')
print(f'Loss: {loss[-1]:.2f}.')
mlp.plot_loss()
```
输出:
```
Training time: 1358.89 second(s).
Loss: 1.34.
```
训练过程
#### 步骤 6. 评价模型
尽管我们在开发过程中已经考虑到为模型评价加入内置的指标,但指标随不同的任务显著变化。因此,我们推荐定义你自己的评价策略。
```python
print(f"Accuracy on the training set is: {accuracy(y_train, mlp.predict(X_train)):.2%}." )
print(f"Accuracy on the test set is: {accuracy(y_test, mlp.predict(X_test)):.2%}.")
```
输出:
```
Accuracy on the training set is: 59.72%.
Accuracy on the test set is: 55.69%.
```
如果您希望保存训练好的模型,可以使用如下的代码:
```python
mlp.save('mlp.pickle')
```
### 5.3 简化模型选择
对于那些追求仅满意但不顶级的模型,可以考虑下面的架构:
简化的架构
```python
layers = [
Input(128),
Dense(units=120, activation='elu', init='kaiming_uniform'),
Dropout(dropout_rate=0.25),
Dense(units=112, init='kaiming_uniform'),
Dropout(dropout_rate=0.20),
Dense(units=96, activation='elu', init='kaiming_uniform'),
Dropout(dropout_rate=0.15),
Dense(units=64, activation='elu', init='kaiming_uniform'),
Dropout(dropout_rate=0.10),
Dense(units=48, activation='elu', init='kaiming_uniform'),
Dropout(dropout_rate=0.05),
Dense(units=32, activation='elu', init='kaiming_uniform'),
Dense(units=24, activation='elu', init='kaiming_uniform'),
Dense(units=16, activation='elu', init='kaiming_uniform'),
Dense(units=10, activation='softmax')
]
mlp = MultilayerPerceptron(layers)
mlp.compile(optimizer=Adam(lr=2e-6, weight_decay=0.02),
loss='CrossEntropy')
mlp.fit(X_train, y_train, epochs=600, batch_size=32)
```
这个模型提供了一致性的训练和适中的性能。训练指标如下:
```
Training time: 768.38 second(s).
Loss: 1.35.
```
训练过程
```
Accuracy on the training set is: 51.95%.
Accuracy on the test set is: 49.58%.
```
### 5.4 一条流线的、完整的工作流
为了阐释,上面的步骤或许略显重复。下面的是一个更加简洁和高效的工作流,也可以在`run.py`文件中找到:
```python
import numpy as np
from datasets.data_loader import datasets
from nn.mlp import MultilayerPerceptron
from nn.layers import Input, Dense, Dropout
from nn.optim import Adam
from nn.schedules import MultiStepLR
from nn.callbacks import EarlyStopping
from sklearn.metrics import accuracy_score as accuracy
# Load the data
X_train, y_train = datasets(train=True)
X_test, y_test = datasets(train=False)
# Set the random seed
np.random.seed(3407)
# Build the model
layers = [
Input(128),
Dense(units=120, activation='elu', init='kaiming_uniform'),
Dropout(dropout_rate=0.25),
Dense(units=112, init='kaiming_uniform'),
Dropout(dropout_rate=0.20),
Dense(units=96, activation='elu', init='kaiming_uniform'),
Dropout(dropout_rate=0.15),
Dense(units=64, activation='elu', init='kaiming_uniform'),
Dropout(dropout_rate=0.10),
Dense(units=48, activation='elu', init='kaiming_uniform'),
Dropout(dropout_rate=0.05),
Dense(units=32, activation='elu', init='kaiming_uniform'),
Dense(units=24, activation='elu', init='kaiming_uniform'),
Dense(units=16, activation='elu', init='kaiming_uniform'),
Dense(units=10, activation='softmax')
]
mlp = MultilayerPerceptron(layers)
optimizer = Adam(lr=1e-3, weight_decay=0.02)
scheduler = MultiStepLR(optimizer, milestones=[100, 200, 300, 400], gamma=0.8)
mlp = MultilayerPerceptron(layers)
optimizer = Adam(lr=1e-3, weight_decay=0.2)
scheduler = MultiStepLR(optimizer, milestones=[20, 40, 60, 80], gamma=0.8)
earlystopping = EarlyStopping(accuracy, patience=10, mode='max', restore_best_weights=True, start_from_epoch=20)
mlp.compile(optimizer=optimizer,
metrics=['CrossEntropy', 'Accuracy'],
scheduler=scheduler
)
mlp.fit(X_train, y_train,
epochs=90, batch_size=128,
validation_data=(X_test, y_test), use_progress_bar=True,
callbacks=[earlystopping]
)
# Evaluate the model
loss = mlp.loss_tracker()
train_time = mlp.training_time()
print(f'Training time: {train_time:.2f} second(s).')
print(f'Loss: {loss[-1]:.2f}.')
mlp.plot_loss()
print(f"Accuracy on the training set is: {accuracy(y_train, mlp.predict(X_train)):.2%}." )
print(f"Accuracy on the test set is: {accuracy(y_test, mlp.predict(X_test)):.2%}.")
# mlp.save('mlp.pickle')
```
使用学习率调度器可以提高大约2-3%的正确率。
或者,如果您更喜欢用我们的预训练模型,参考接下来的代码块,也在文件`load.py`中提供:
```python
from datasets.data_loader import datasets
from nn.mlp import MultilayerPerceptron
from sklearn.metrics import accuracy_score as accuracy
from sklearn.metrics import precision_score
# Load the data
X_train, y_train = datasets(train=True)
X_test, y_test = datasets(train=False)
# Load the model
mlp = MultilayerPerceptron.load('model_hub/mlp.pickle')
# Evaluate the model
print(f"Accuracy on the training set is: {accuracy(y_train, mlp.predict(X_train)):.2%}." )
print(f"Accuracy on the test set is: {accuracy(y_test, mlp.predict(X_test)):.2%}.")
print(f"Precision on the training set is: {precision_score(y_train, mlp.predict(X_train), average='weighted'):.2%}." )
print(f"Precision on the test set is: {precision_score(y_test, mlp.predict(X_test), average='weighted'):.2%}.")
```
## :sparkles: 6. 项目结构
```
├── data/
| ├── train_data.npy
| ├── train_label.npy
| ├── test_data.npy
| └── test_label.npy
|
├── datasets/
| ├── data_loader.py
| └── __init__.py
|
├── model_hub/
│ └── mlp.pickle
|
├── nn/
| ├── callbacks.py
| ├── functional.py
| ├── layers.py
| ├── mlp.py
| ├── optim.py
| └── __init__.py
|
├── figures/
| ├── *.svg
│ └── *.png
|
├── eval/
| ├── metrics.py
| └── __init__.py
|
├── LICENSE
├── mlp_quickstart.ipynb
├── README.md
├── README.zh-CN.md
├── run.py
└── load.py
```
## :sparkles: 7. 更新日志
这个部分列举了对多层感知机框架做出的更改和更新。每次更新将包括版本序号,发布日期和作出更改的一个简单总结。
### 版本更新:2023-09-05
- **增加**:整合`tqdm`库中的`tqdm()`函数至训练过程中.
- **重排**:改进整个仓库结构以提高统一性和标准化。
- **提高**:提升为特定任务的多层感知机架构。
- **未来工作**:计划整合**早停**到训练过程。(已完成。)
### 仓库更新:2023-10-02
- **增加**:发布数据集。
- **修复**:修复README.md中几处笔误。
### 仓库更新:2023-10-07
- **增加**:为顺利与谷歌Colab整合,引入一个名为`mlp_quickstart.ipynb`的Jupyter笔记本。
- **提升**:为清晰和更好的用户浏览,融合表情并润色内容,以改进README.md。
- **未来工作**:计划完成各个模块的文档字符串。
### 版本和仓库更新:2023-10-18
- **模块**:流水线化并重新分解代码库以确保更清晰、更直观的用户体验。
- **增加**:顺利地整合了用谷歌Colab内置数据集的架构构建和性能测试。
- **提升**:引入新方法至`MultilayerPerceptron`,升高了它的功能性和多样性。
- **整合**:同时融合`EarlyStopping`和`LearningRateScheduler`,提供精炼的训练控制。
- **进步**:完成部分模块的文档字符串,铺平通向更清晰的开发者洞见的道路。
### 版本更新: 2023-11-22
- **简化**: 简化了部分实现,尤其是用户界面。
- **提升**: 增强了部分功能。
### 仓库更新: 2023-11-24
- **完成**: 完成了所有模块的文档字符串,增强了整个代码库的清晰度和开发者理解。