实验目的
- 熟悉和掌握感知机神经网络
- 熟悉和掌握随机梯度下降算法
- 了解和掌握第三方机器学习库Scikit-learn中的模型调用
实验要求
- 采用Python、Matlab等高级语言进行编程,推荐优先选用Python语言
- 核心模型和算法需自主编程实现,不得直接调用Scikit-learn、PyTorch等成熟框架的第三方实现(除非实验内容明确指定调用)
- 代码可读性强:变量、函数、类等命名可读性强,包含必要的注释
实验原理
感知机(perceptron)是二分类的线性分类模型,属于监督学习算法。输入为实例的特征向量,输出为实例的类别(取+1和-1)。感知机旨在求出将输入空间中的实例划分为两类的分离超平面。为求得超平面,感知机导入了基于误分类的损失函数,利用梯度下降法对损失函数进行最优化求解。
如果训练数据集是线性可分的,则感知机一定能求得分离超平面。如果是非线性可分的数据,则无法获得超平面。
感知机具有简单而易于实现的优点,分为原始形式和对偶形式。感知机预测是用学习得到的感知机模型对新的实例进行预测的,因此属于判别模型。感知机是神经网络和支持向量机的基础。
二分类模型: $f(x)=\operatorname{sign}(w * x+b)$
损失函数: $L(w, b)=-\Sigma y_i(w *+b)$
算法:
随即梯度下降法 Stochastic Gradient Descent
随机抽取一个误分类点使其梯度下降。
$w=w+\eta y i x i$
$b=b+\eta y i$
当实例点被误分类, 即位于分离超平面的错误侧, 则调整 $\mathrm{w}, \mathrm{b}$ 的值, 使分离超平面向该无分类点的一一侧移动,直 至误分类点被正确分类拿出 iris 数据集中两个分类的数据和[sepal length, sepal width]作为特征
实验内容
感知机神经网络分类
- 从iris数据集中取出[sepal length,sepal width]两个属性作为样本特征,保持类别标记不变,训练单隐层感知机网络进行二分类实验。注意取前100个样本作为训练集,剩余的50个样本作为测试集。
- Iris数据集介绍详见:https://archive.ics.uci.edu/dataset/53/iris
- Scikit-learn库中预装了Iris数据集,安装库后采用 “from sklearn.datasets import load_iris” 可以直接读取,参考https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_iris.html
- 借助matplotlib 画出原始训练数据分布的散点图(x=“sepal length”,y=“sepal width”,点的颜色代表不同类别)
- 按照下述模型和优化目标, 构造感知机模型和损失函数:
- 模型: $f(x)=\operatorname{sign}(w \cdot x+b)$
- 优化目标: $\min {w, b} L(w, b)=-\sum{x_i \in M} y_i\left(w \cdot x_i+b\right)$
- 编写适用于感知机的随机梯度下降算法(Stochastic Gradient Descent,SGD),对单隐层的感知机进行梯度下降
- 此数据集线性可分,可以设置迭代的停止条件为“直到训练集内没有误分类样本为止”
- 学习率设置为0.1, 偏置初始化0,权重均初始化为1
- SGD 更新:
$$
\begin{aligned}
& w=w+\eta y_i x_i \\
& b=b+\eta y_i
\end{aligned}
$$
结果展示
- 将模型拟合的分类边界与上述原始数据点画到同一图中,观察训练效果
- 用训练的模型对测试数据进行分类,得到测试错误率
- 将模型拟合的分类边界与测试数据点画到同一图中,观察效果
神经网络调参
调整学习率参数取值分别为[0.01, 0.05, 0.1, 0.5]运行模型,比较模型最后的测试正确率以及模型收敛所需要的训练轮数(epoch)数。
Sciki-learn机器学习库的调用
- 直接调用机器学习库Scikit-learn中感知机模型(https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Perceptron.html ),用上述训练和测试集训练进行训练, 采用上述类似的方法可视化训练集和验证集上模型的分类结果。(调用时保持模型超参数tol的取值为默认值0.001)
- 比较自己实现的模型和调用的Scikit-learn中模型在训练集上的可视化结果图,观察有何不同,分析产生不同的原因。
实验代码和结果
1 | import pandas as pd |
学习率为0.1时,训练了13次,错误率为0.1
学习率为0.01时,训练了62次,错误率为0.1
学习率为0.05时,训练了16次,错误率为0.1
学习率为0. 5时,训练了13次,错误率为0.1
1 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.8, random_state=42) |
准确率为0.9875
结果不同可能是由于学习率设置不同,以及随机种子的差异
小结或讨论
感知器是人工神经网络中的一种典型结构, 它的主要的特点是结构简单。它是一种分类学习器,是很多复杂算法的基础。其“赏罚概念”在机器学习算法在中广为应用。在分类正确时,对正确的权重向量w奖赏,即w不变;当分类错误时,对权重向量惩罚,即将权重向量w向着争取的方向转变
Perceptron 由 Frank Rosenblatt 升发, 并于 1962 年出版的“神经动力学原理:感知器和脑机制理论”一文中所提出。当时, Rosenblatt 的文章被 Marvin Minksy 和 Seymour Papert 反对,认为神经网络有缺陷,只能解决线性分类问题。然而, 这种限制仅发生在单层神经网络中。Perceptron 可用于解决二分类问题。在传统线性可分的二分类情况下, 可以使 $w^T x>=0$ 时分类为正样本, $w^T x<0$ 分类为负样本。
算法步骤为对所有负样本乘以 -1 以方便算法流程, 即使 $w^T x>=0$ 时判断为分类正确。
随机生成初始权重向量 $w 0$, 在每轮迭代中, 若样本 $i$ 分类正确即 $w^T x_i>=0$ 时,不对 $w$ 进行修改; 当本轮迭代中, 针对样本 $i$ 出现分类错误, 即 $w^T xi<0$ 时, 对权重向量 $w$ 惩罚, 使之朝着正确的趋势改进。 $\eta$ 为学习率。如果无错误分类,则迭代结束