资讯动态

BP神经网络分类鸢尾花与红酒数据集:从源码到答辩PPT

发布时间:2026/9/13 23:33:14 来源:尧图企业网站定制
简介基于Python的BP神经网络分类项目围绕鸢尾花和红酒两个经典数据集完成分类建模覆盖数据读取、预处理、网络训练、评估与可视化全流程适用于机器学习初学者巩固理论也适合期末大作业、课程设计及毕业设计参考。压缩包内共21个文件核心包括iris_classify.py、winquality_classify.py、BP.py三个源码文件两个Jupyter Notebook便于交互调试另有Word实验报告、答辩PPT、Excel数据集和项目配置文件整体大小仅1.37MB部署轻量。目前已有286人学习下载。源码注释详尽关键步骤均有说明三份实验报告阐述算法原理与结果分析PPT凝练核心内容可支撑答辩展示。从代码到报告再到汇报该资源提供了完整的高分项目模板能帮助快速理解BP神经网络在有监督分类任务中的应用。1. BP神经网络分类鸢尾花与红酒数据集从源码、实验报告到答辩PPT鸢尾花数据集只有 4 个特征红酒数据集却带 13 个特征两者样本量分别是 150 和 178。不少课程设计拿到这两个公开数据集会误以为要写两套模型。实际上 BP 神经网络的输入端本来就跟随特征数变化只需要把输入层节点从 4 改成 13隐藏层和训练逻辑可以原样复用。所以做这类 Python 神经网络实验从业者常走的路子是只维护一套基于 NumPy 的 BP 分类器将鸢尾花、红酒分别标准化后丢进同一个训练循环再单独评估各自准确率。下面的内容按这个顺序展开先把 BP 的结构、反向传播和关键参数讲清再给出能直接跑的源码随后讨论实验报告里的评估指标与可视化怎么写最后落到答辩 PPT 的页面安排和现场追问。目标是让正在做课程设计或刚入门神经网络的工程师不用去翻几百页教材也能把项目落地。2. BP神经网络结构、反向传播与参数设定2.1 输入层、隐层、输出层节点数怎么定BP 神经网络是典型的多层前馈网络由输入层、若干隐层、输出层组成。分类任务中输入层节点数必须等于特征数量输出层节点数必须等于类别数量这个约束不随数据集变化。鸢尾花数据集包含花萼长度、花萼宽度、花瓣长度、花瓣宽度共 4 个特征类别是 3 种鸢尾花因此输入层取 4输出层取 3。红酒数据集包含酒精、苹果酸、灰分等 13 个化学成分特征类别同样是 3 种所以输入层取 13输出层取 3。隐层节点数则没有固定公式。常见的工程做法是取输入节点数和输出节点数之间的中值或者用(n_in n_out) / 2附近的值做起点。鸢尾花数据线性可分程度较高我一般取 6 个隐层节点就能达到不错效果红酒数据特征维度更高隐层节点太少会欠拟合因此取 10 个更稳妥。答辩时如果被问“隐层为什么是 6 或 10”正确的回答不是背公式而是展示一组隐层节点数从 4 到 16 的对比实验让曲线替你回答。需要注意隐层节点越多模型参数越多训练集准确率会上升但测试集准确率可能下跌这就是过拟合。课程设计报告里如果只写最终精度不写模型容量变化过程答辩老师很容易看出参数是拍脑袋定的。建议在同一章里附带一张“隐层节点数-准确率”对照表即使结论只是“节点数达到 8 后曲线不再明显上升”也能说明你做过系统性验证。2.2 前向传播与反向传播交叉熵损失和梯度更新BP 的训练过程分成两步。前向传播时输入数据经过权重矩阵和激活函数逐层变换最后在输出层得到属于每个类别的概率。对多分类问题输出层用 softmax 将数值压缩成概率分布隐藏层则常用 sigmoid 或 ReLU 引入非线性。反向传播时先算出输出概率与真实标签之间的误差梯度再按照损失函数对各层权重的偏导数从输出层往输入层逐层更新 W 和 b。以三层网络为例前向公式为z1 X * W1 b1 a1 sigmoid(z1) z2 a1 * W2 b2 a2 softmax(z2)损失函数使用交叉熵时输出层反向传播的误差梯度有个非常简洁的形式dz2 a2 - y_onehot。这个式子的意思是输出层的梯度等于预测概率减去独热编码的真实标签预测越准梯度越接近 0更新幅度越小。随后把梯度传回隐藏层经过sigmoid的导数a1 * (1 - a1)继续向前传播最终得到每一层权重需要调整的方向和步长。这种手写实现的好处是每一步数值都可被打印、检查方便在实验报告中解释“训练轮次增加时 loss 如何下降”。如果在答辩前仍对反向传播的链式法则没底至少要把“输出层误差告诉隐层隐层按导数分配责任”这句话背下来绝大部分追问都会被这句话化解。2.3 必调参数对照学习率、训练轮数、隐层大小BP 神经网络在鸢尾花、红酒这类小规模数据集上的表现受参数影响相当大。下面是一张我经常直接发给学生的参数表覆盖了入门实验最常见的几个位置参数常见取值调参方向学习率0.01 到 0.1过大时 loss 震荡过小时收敛极慢训练轮数500 到 2000观察 loss 曲线平缓后即可停止隐层节点数4 到 16测试准确率下降说明过拟合需要减小权重初始化均值为 0 的正态分布乘以 0.1避免初始权重过大导致的梯度问题数据标准化StandardScaler特征尺度不一致时网络可能无法收敛红酒数据集中部分特征的值域能到几百甚至上千例如脯氨酸含量和酒精浓度差异巨大。如果不做标准化大数值特征会主导权重更新模型收敛很慢甚至梯度爆炸。所以无论跑哪个数据集我都建议先做StandardScaler标准化再划分训练集和测试集。这属于实验报告里必须写的预处理步骤同时也是答辩中被问到时最简单的送分题。3. 用Python实现BP分类器鸢尾花、红酒数据集的完整代码3.1 加载数据集并做标准化先准备好鸢尾花和红酒两个公开数据集。它们都可以通过 scikit-learn 直接加载不需要额外下载文件。加载后统一做标准化然后按 8:2 的比例切分训练集和测试集from sklearn.datasets import load_iris, load_wine from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler def load_split_data(): datasets { iris: load_iris(), wine: load_wine() } splits {} for name, data in datasets.items(): X StandardScaler().fit_transform(data.data) y data.target X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42 ) splits[name] (X_train, X_test, y_train, y_test) print(f{name} 训练集: {X_train.shape}, 测试集: {X_test.shape}) return splits标准化要放在切分之前还是切分之后这个问题常被追问。严谨做法是先切分再用训练集的均值与方差转换测试集防止测试集信息提前泄漏进预处理过程。不过对于课程设计这种规模的数据集直接对全集标准化造成的影响非常小写报告时说明你的做法即可。如果你希望严谨可以将StandardScaler改为在训练集上fit再对测试集transform。3.2 Python手写BPClassifier核心类不依赖深度学习框架直接用 NumPy 实现一个三层 BP 分类器。代码虽然比调用 Keras 多但每一行都能对应到上一章提到的公式便于调试和答辩展示import numpy as np class BPClassifier: def __init__(self, n_in, n_hidden, n_out, learning_rate0.1): self.lr learning_rate self.W1 np.random.randn(n_in, n_hidden) * 0.1 self.b1 np.zeros(n_hidden) self.W2 np.random.randn(n_hidden, n_out) * 0.1 self.b2 np.zeros(n_out) def _sigmoid(self, z): return 1 / (1 np.exp(-z)) def _softmax(self, z): exp_z np.exp(z - np.max(z, axis1, keepdimsTrue)) return exp_z / np.sum(exp_z, axis1, keepdimsTrue) def forward(self, X): self.z1 X self.W1 self.b1 self.a1 self._sigmoid(self.z1) self.z2 self.a1 self.W2 self.b2 self.a2 self._softmax(self.z2) return self.a2 def backward(self, X, y_onehot, probs): m X.shape[0] dz2 probs - y_onehot dW2 self.a1.T dz2 / m db2 np.sum(dz2, axis0) / m da1 dz2 self.W2.T dz1 da1 * self.a1 * (1 - self.a1) dW1 X.T dz1 / m db1 np.sum(dz1, axis0) / m self.W2 - self.lr * dW2 self.b2 - self.lr * db2 self.W1 - self.lr * dW1 self.b1 - self.lr * db1 def predict(self, X): probs self.forward(X) return np.argmax(probs, axis1)权重的初始化方式在初始化函数中体现使用randn再乘以 0.1保证初始权重处于较小范围避免 sigmoid 因输入过大立刻进入饱和区。b1和b2初始化为零向量不会破坏对称性因为输入经过随机权重W1后已经被打散。_softmax中对输入减去最大值是为了防止np.exp出现数值溢出这一行在特征值和权重偏大时至关重要丢了它可能导致 loss 变成 NaN。反向传播中dz2 probs - y_onehot正是上一章提到的交叉熵简化梯度。除以样本数m是求均值梯度保证更新步长不随训练集大小变化。如果以后改用 Batch 训练只需把m换成当前批次样本数这段逻辑无需改动。3.3 训练流程一套代码跑两个数据集训练函数接收数据集名称、特征数和类别数其他逻辑完全复用同一个网络类。两个数据集的差异只体现在n_in这个参数上from sklearn.preprocessing import OneHotEncoder from sklearn.metrics import accuracy_score def train_and_evaluate(name, X_train, X_test, y_train, y_test): n_in X_train.shape[1] n_out len(np.unique(y_train)) model BPClassifier(n_in, n_hidden10, n_outn_out, learning_rate0.1) encoder OneHotEncoder(sparse_outputFalse) y_onehot encoder.fit_transform(y_train.reshape(-1, 1)) for epoch in range(1000): probs model.forward(X_train) loss -np.mean(np.sum(y_onehot * np.log(probs 1e-8), axis1)) model.backward(X_train, y_onehot, probs) if epoch % 200 0: print(f{name} epoch {epoch}, loss {loss:.4f}) pred model.predict(X_test) acc accuracy_score(y_test, pred) print(f{name} 测试集准确率: {acc:.4f}) return model, pred损失计算中加入1e-8是为了防止概率出现 0 导致对数运算报错。训练轮数取 1000学习率取 0.1在两个数据集上都能在较短时间内收敛。鸢尾花的测试集准确率通常可以达到 0.93 以上红酒的测试集准确率一般在 0.88 到 0.97 之间浮动具体值受随机种子影响。所以实验报告里最好固定random_state并在文档中写明使用了random_state42这样结果可复现答辩时也经得起验证。训练完成后按相同方式对红酒数据集执行train_and_evaluate只需把数据换成葡萄酒对应的切分结果。若后续要给别人讲解代码建议把n_hidden也提取成参数放到函数入参中这样可以顺带完成不同隐层节点数的对比实验。4. 实验报告模型评估指标、混淆矩阵和参数实验4.1 实验报告的结构从数据描述到误差分析实验报告不是代码注释的堆叠而是从问题出发说明“为什么用 BP、怎么调参数、最终效果如何”。课程设计报告我建议按下述结构展开问题背景和数据说明、算法原理、实验环境、预处理方法、模型实现细节、结果分析、结论与改进点。其中实验环境要写清楚 Python 版本和依赖库版本例如 Python 3.10、NumPy 1.24、scikit-learn 1.3方便他人复现。结果分析是报告的核心至少包含测试集准确率、每类别的精确率和召回率、混淆矩阵以及参数变化对结果的影响。很多学生把全部注意力放在准确率这一个数字上忽略了类别间的差异。红酒数据集的类别分布并不完全均衡某一类样本量偏少时整体准确率可能看起来不错但小类别的召回率很低。这个问题在报告里主动写出来比被答辩老师指出要好得多。4.2 评估指标与混淆矩阵可视化对三个类别的分类任务只报告准确率不够建议补充classification_report和混淆矩阵。以下是可直接写入报告使用的绘图代码import matplotlib.pyplot as plt import seaborn as sns from sklearn.metrics import classification_report, confusion_matrix cm confusion_matrix(y_test, pred) plt.figure(figsize(6, 5)) sns.heatmap(cm, annotTrue, fmtd, cmapBlues, xticklabelsload_wine().target_names, yticklabelsload_wine().target_names) plt.xlabel(预测类别) plt.ylabel(真实类别) plt.title(红酒数据集混淆矩阵) plt.show() print(classification_report(y_test, pred))混淆矩阵能直观显示哪些类别容易被混淆。红酒数据集里 class_0 和 class_1 在特征空间上有一定重叠测试样本少时容易出现交叉误判。报告中放一张混淆矩阵图能比整页文字更清楚地说明误差来源。classification_report输出的精确率、召回率和 F1 值应以宏平均或加权平均写入总结段落避免只提准确率。4.3 参数对照实验的记录表参数实验是实验报告中最容易被扣分也最容易得分的位置。以隐层节点数为例可以固定学习率和训练轮数分别设置n_hidden为 4、6、8、10、12、16记录每个配置下训练集和测试集的准确率。整理成的表格可参考隐层节点数训练准确率测试准确率训练耗时观察结论40.940.89约 0.8 秒表达力不足欠拟合80.980.94约 1.0 秒表现适中120.990.94约 1.2 秒提升有限160.990.92约 1.5 秒出现过拟合迹象上表中的训练耗时可以运行程序后填写不必追求精确到毫秒。表格的价值在于给出一个完整趋势证明你比较过不同模型容量。若训练集准确率持续上升但测试集准确率下降应该在结论部分写明“模型发生了过拟合最终选择 8 个隐层节点作为折中方案”。这段分析逻辑是答辩时最能体现工程判断力的内容。5. 答辩PPT准备页面安排和现场追问应对5.1 答辩PPT的页面结构答辩 PPT 的目的是在几分钟内讲清“我做了什么、代码怎么实现的、效果如何”页面数量控制在 8 到 10 页即可。以下是我给题目为鸢尾花、红酒 BP 分类的项目设计的常见页面布局页码页面内容说明1标题页写清项目题目、姓名、学号、指导老师2数据集介绍描述两个数据集的维度、类别数和样本量3算法原理BP 结构图 前向、反向公式4代码实现亮点核心类截图、训练代码段5实验结果准确率表格加混淆矩阵6参数实验隐层节点数对比曲线7项目总结遇到的问题和解决办法8谢谢写“请老师们批评指正”第 3 页不建议贴全部公式只放关键的两行交叉熵损失函数和输出层梯度dz2 probs - y_onehot。第 4 页代码展示要截取最有逻辑的一段不要整屏粘贴几十行。每页重点限制在三个以内文字越少越好剩下的靠你开口解释。5.2 答辩中常被追问的三个问题奇怪的是答辩现场最常被问的不是模型原理而是“这个代码是不是你写的”。为应对这种性质的问题你必须能拿着代码现场指出每个方法的输入输出构造函数负责初始化权重forward保存了中间层输出backward依据链式法则计算梯度并更新参数。熟练走通这段流程比背诵多少页 PPT 都有说服力。第二个高频问题是“为什么不用 KNN 或决策树偏要选 BP 神经网络”。正确的回答不是贬低其他算法而是承认这是一个验证神经网络基础的课程设计重点在理解反向传播机制同时可以补充BP 在高维特征下比 KNN 更具泛化潜力。第三个高频问题是“红酒数据集有哪些特征对分类影响最大”。这份代码暂时没有做特征重要性分析你可以说这是后续改进方向并提一句“可以通过计算每个特征的方差贡献或训练后 W1 的权重分布来判断”。把改进方向主动说成未来计划会给答辩老师留下更完整的印象。最后一个实用技巧PPT 里特意放一张“训练集准确率高但测试集准确率略有下降”的图表主动解释这是过拟合现象并提出调小隐层节点数后的对比结果。敢于展示坏结果并给出分析比所有图表都是满分更有可信度。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价