MultilayerPerceptron:一个简单的多层神经网络
多层感知器(一种前馈人工神经网络)的实现。
from mlxtend.classifier import MultiLayerPerceptron
概述
尽管代码功能齐全,可用于常见的分类任务,但此实现并非以效率为导向,而是以清晰性为导向——原始代码是为演示目的而编写的。
基本架构
神经元和表示偏置单元(, ).
上标表示第层,下标 j 表示相应单元的索引。例如,指代第二层(此处为:隐藏层)中紧随偏置单元之后的第一个激活单元(即第 2 个激活单元)
多层感知器(一个有向图)中的每一层与下一层完全连接。我们将连接第层的第单元到层中的第单元的权重系数写作.
例如,连接单元
的权重系数将写成.
激活
在当前实现中,隐藏层的激活通过逻辑(sigmoid)函数计算
(有关逻辑函数的更多详细信息,请参阅 classifier.LogisticRegression
;有关不同激活函数的概述,请参阅此处。)
此外,MLP 在输出层使用 softmax 函数。有关 softmax 函数的更多详细信息,请参阅 classifier.SoftmaxRegression
。
参考文献
- D. R. G. H. R. Williams 和 G. Hinton。Learning representations by back-propagating errors. Nature, 页码 323–533, 1986。
- C. M. Bishop。Neural networks for pattern recognition. Oxford University Press, 1995。
- T. Hastie, J. Friedman 和 R. Tibshirani。The Elements of Statistical Learning, 第二卷. Springer, 2009。
示例 1 - 对鸢尾花进行分类
加载 Iris 的 2 个特征(花瓣长度和花瓣宽度)用于可视化
from mlxtend.data import iris_data
X, y = iris_data()
X = X[:, [0, 3]]
# standardize training data
X_std = (X - X.mean(axis=0)) / X.std(axis=0)
训练神经网络处理 3 个输出类别('Setosa', 'Versicolor', 'Virginica'),使用常规梯度下降(minibatches=1
),30 个隐藏单元,无正则化。
梯度下降
将 minibatches
设置为 1
将导致梯度下降训练;详细信息请参阅 梯度下降 vs. 随机梯度下降。
from mlxtend.classifier import MultiLayerPerceptron as MLP
nn1 = MLP(hidden_layers=[50],
l2=0.00,
l1=0.0,
epochs=150,
eta=0.05,
momentum=0.1,
decrease_const=0.0,
minibatches=1,
random_seed=1,
print_progress=3)
nn1 = nn1.fit(X_std, y)
Iteration: 150/150 | Cost 0.06 | Elapsed: 0:00:00 | ETA: 0:00:00
from mlxtend.plotting import plot_decision_regions
import matplotlib.pyplot as plt
fig = plot_decision_regions(X=X_std, y=y, clf=nn1, legend=2)
plt.title('Multi-layer Perceptron w. 1 hidden layer (logistic sigmoid)')
plt.show()
import matplotlib.pyplot as plt
plt.plot(range(len(nn1.cost_)), nn1.cost_)
plt.ylabel('Cost')
plt.xlabel('Epochs')
plt.show()
print('Accuracy: %.2f%%' % (100 * nn1.score(X_std, y)))
Accuracy: 96.67%
随机梯度下降
将 minibatches
设置为 n_samples
将导致随机梯度下降训练;详细信息请参阅 梯度下降 vs. 随机梯度下降。
nn2 = MLP(hidden_layers=[50],
l2=0.00,
l1=0.0,
epochs=5,
eta=0.005,
momentum=0.1,
decrease_const=0.0,
minibatches=len(y),
random_seed=1,
print_progress=3)
nn2.fit(X_std, y)
plt.plot(range(len(nn2.cost_)), nn2.cost_)
plt.ylabel('Cost')
plt.xlabel('Epochs')
plt.show()
Iteration: 5/5 | Cost 0.11 | Elapsed: 00:00:00 | ETA: 00:00:00
继续训练 25 个 epoch...
nn2.epochs = 25
nn2 = nn2.fit(X_std, y)
Iteration: 25/25 | Cost 0.07 | Elapsed: 0:00:00 | ETA: 0:00:00
plt.plot(range(len(nn2.cost_)), nn2.cost_)
plt.ylabel('Cost')
plt.xlabel('Epochs')
plt.show()
示例 2 - 对 MNIST 10% 子集中的手写数字进行分类
加载 MNIST 数据集 的5000 样本子集(如果您想下载并读取完整的 MNIST 数据集,请参阅 data.loadlocal_mnist
)。
from mlxtend.data import mnist_data
from mlxtend.preprocessing import shuffle_arrays_unison
X, y = mnist_data()
X, y = shuffle_arrays_unison((X, y), random_seed=1)
X_train, y_train = X[:500], y[:500]
X_test, y_test = X[500:], y[500:]
可视化 MNIST 数据集中的一个样本,检查是否正确加载
import matplotlib.pyplot as plt
def plot_digit(X, y, idx):
img = X[idx].reshape(28,28)
plt.imshow(img, cmap='Greys', interpolation='nearest')
plt.title('true label: %d' % y[idx])
plt.show()
plot_digit(X, y, 3500)
标准化像素值
import numpy as np
from mlxtend.preprocessing import standardize
X_train_std, params = standardize(X_train,
columns=range(X_train.shape[1]),
return_params=True)
X_test_std = standardize(X_test,
columns=range(X_test.shape[1]),
params=params)
初始化神经网络以识别 10 个不同的数字(0-10),使用 300 个 epoch 和 mini-batch 学习。
nn1 = MLP(hidden_layers=[150],
l2=0.00,
l1=0.0,
epochs=100,
eta=0.005,
momentum=0.0,
decrease_const=0.0,
minibatches=100,
random_seed=1,
print_progress=3)
学习特征,同时打印进度以了解可能需要的时间。
import matplotlib.pyplot as plt
nn1.fit(X_train_std, y_train)
plt.plot(range(len(nn1.cost_)), nn1.cost_)
plt.ylabel('Cost')
plt.xlabel('Epochs')
plt.show()
Iteration: 100/100 | Cost 0.01 | Elapsed: 0:00:17 | ETA: 0:00:00
print('Train Accuracy: %.2f%%' % (100 * nn1.score(X_train_std, y_train)))
print('Test Accuracy: %.2f%%' % (100 * nn1.score(X_test_std, y_test)))
Train Accuracy: 100.00%
Test Accuracy: 84.62%
请注意,这个神经网络仅在 MNIST 数据的 10% 上进行训练,用于技术演示目的,因此预测性能较差。
API
MultilayerPerceptron(eta=0.5, epochs=50, hidden_layers=[50], n_classes=None, momentum=0.0, l1=0.0, l2=0.0, dropout=1.0, decrease_const=0.0, minibatches=1, random_seed=None, print_progress=0)
具有逻辑 sigmoid 激活的多层感知器分类器
参数
-
eta
: 浮点数 (默认值: 0.5)学习率(介于 0.0 和 1.0 之间)
-
epochs
: 整数 (默认值: 50)遍历训练数据集的次数。在每个 epoch 之前,如果
minibatches > 1
,数据集会被打乱以防止随机梯度下降中的循环。 -
hidden_layers
: 列表 (默认值: [50])每个隐藏层的单元数。默认情况下,第一个隐藏层有 50 个单元。目前仅支持 1 个隐藏层。
-
n_classes
: 整数 (默认值: None)一个正整数,用于声明类别标签的数量,如果部分训练集中不包含所有类别标签。如果为 None,则自动获取类别标签的数量。
-
l1
: 浮点数 (默认值: 0.0)L1 正则化强度
-
l2
: 浮点数 (默认值: 0.0)L2 正则化强度
-
momentum
: 浮点数 (默认值: 0.0)动量常数。与前一个 epoch t-1 的梯度相乘的因子,用于提高学习速度 w(t) := w(t) - (grad(t) + momentum * grad(t-1))
-
decrease_const
: 浮点数 (默认值: 0.0)衰减常数。通过 eta / (1 + epoch*decrease_const) 在每个 epoch 后缩小学习率。
-
minibatches
: 整数 (默认值: 1)将训练数据划分为 k 个 mini-batch,以加速随机梯度下降学习。如果
minibatches
= 1,则为梯度下降学习;如果minibatches
= len(y),则为随机梯度下降学习;如果minibatches
> 1,则为 mini-batch 学习。 -
random_seed
: 整数 (默认值: None)设置用于打乱和初始化权重的随机状态。
-
print_progress
: 整数 (默认值: 0)在拟合过程中打印进度到标准错误流。0:无输出 1:已用 epoch 数和代价 2:1 加已用时间 3:2 加估计完成时间
属性
-
w_
: 二维数组, 形状=[特征数, 类别数]拟合后的权重。
-
b_
: 一维数组, 形状=[类别数]拟合后的偏置单元。
-
cost_
: 列表浮点数列表;每个 epoch 后的平均分类交叉熵代价。
示例
有关使用示例,请参阅 https://mlxtend.cn/mlxtend/user_guide/classifier/MultiLayerPerceptron/
方法
fit(X, y, init_params=True)
从训练数据中学习模型。
参数
-
X
: {类数组对象, 稀疏矩阵}, 形状 = [样本数, 特征数]训练向量,其中 n_samples 是样本数量,n_features 是特征数量。
-
y
: 类数组对象, 形状 = [样本数]目标值。
-
init_params
: 布尔值 (默认值: True)在拟合之前重新初始化模型参数。设置为 False 以使用先前模型拟合的权重继续训练。
返回值
self
: 对象
predict(X)
从 X 预测目标。
参数
-
X
: {类数组对象, 稀疏矩阵}, 形状 = [样本数, 特征数]训练向量,其中 n_samples 是样本数量,n_features 是特征数量。
返回值
-
target_values
: 类数组对象, 形状 = [样本数]预测的目标值。
predict_proba(X)
从网络输入预测 X 的类别概率。
参数
-
X
: {类数组对象, 稀疏矩阵}, 形状 = [样本数, 特征数]训练向量,其中 n_samples 是样本数量,n_features 是特征数量。
返回值
类别概率
: 类数组对象, 形状= [样本数, 类别数]
score(X, y)
计算预测准确度
参数
-
X
: {类数组对象, 稀疏矩阵}, 形状 = [样本数, 特征数]训练向量,其中 n_samples 是样本数量,n_features 是特征数量。
-
y
: 类数组对象, 形状 = [样本数]目标值(真实类别标签)。
返回值
-
acc
: 浮点数预测准确度,一个介于 0.0 和 1.0 之间的浮点数(完美分数为 1.0)。
python