你的第一个神经网络项目:用BP网络搞定鸢尾花分类(附完整Python代码与结果分析)
2026/6/3 5:34:45 网站建设 项目流程

你的第一个神经网络项目:用BP网络搞定鸢尾花分类(附完整Python代码与结果分析)

第一次接触神经网络时,很多人会被各种数学公式和抽象概念吓退。但事实上,当你亲手实现一个能解决实际问题的神经网络时,那些看似复杂的理论会突然变得清晰起来。今天我们就用经典的鸢尾花数据集,带你完整走一遍BP神经网络的实战流程——从数据加载到模型评估,每个步骤都有可运行的代码和直观的结果展示。

这个项目特别适合刚学完机器学习基础,想通过实践加深理解的朋友。不需要高深的数学功底,只要会基本的Python编程就能跟上。我们将重点关注如何用代码实现理论,而不是推导公式。最终你会得到一个能准确分类三种鸢尾花的神经网络,并理解每个设计决策背后的实际意义。

1. 环境准备与数据理解

在开始构建神经网络前,我们需要准备好Python环境和数据集。推荐使用Anaconda创建新的Python 3.8+环境,并安装以下必要库:

pip install numpy pandas matplotlib scikit-learn

鸢尾花(Iris)数据集包含150个样本,每个样本有4个特征:

  • 花萼长度(sepal length)
  • 花萼宽度(sepal width)
  • 花瓣长度(petal length)
  • 花瓣宽度(petal width)

目标是将花朵分类到三个品种之一:

  • Iris Setosa
  • Iris Versicolour
  • Iris Virginica

先让我们加载数据并快速查看其结构:

from sklearn.datasets import load_iris import pandas as pd iris = load_iris() df = pd.DataFrame(iris.data, columns=iris.feature_names) df['target'] = iris.target print(df.head())

输出示例:

sepal length (cm) sepal width (cm) ... petal width (cm) target 0 5.1 3.5 ... 0.2 0 1 4.9 3.0 ... 0.2 0 2 4.7 3.2 ... 0.2 0

注意:原始目标值是数字编码,0/1/2分别对应三种鸢尾花。我们需要将其转换为one-hot编码格式,这是多分类问题的标准处理方式。

2. 数据预处理关键步骤

神经网络的性能很大程度上取决于数据预处理的质量。我们需要完成以下几个关键步骤:

2.1 特征标准化

不同特征的数值范围差异很大(比如花萼长度通常在4-8cm,而花瓣宽度在0.1-2.5cm)。这会导致梯度下降时各维度更新速度不一致,影响训练效率。使用MinMaxScaler将所有特征缩放到[0,1]范围:

from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler() X = scaler.fit_transform(iris.data)

2.2 标签编码转换

将简单的类别编号转换为one-hot编码,这是多分类问题的标准做法:

from keras.utils import to_categorical y = to_categorical(iris.target) print(y[:5]) # 查看转换后的前5个样本

输出示例:

[[1. 0. 0.] [1. 0. 0.] [1. 0. 0.] [1. 0. 0.] [1. 0. 0.]]

2.3 数据集划分

按7:3比例分割训练集和测试集:

from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=42)

3. 构建BP神经网络模型

现在进入核心环节——设计我们的BP神经网络结构。我们将使用Keras库来简化实现过程。

3.1 网络结构设计

根据经验公式,隐藏层节点数可估算为: $$ h = \sqrt{m+n} + a $$ 其中m=4(输入特征),n=3(输出类别),a取5得到h≈7.6,我们取整为8。

from keras.models import Sequential from keras.layers import Dense model = Sequential([ Dense(8, activation='tanh', input_shape=(4,)), # 隐藏层 Dense(3, activation='softmax') # 输出层 ])

这里做了几个关键选择:

  • 激活函数:隐藏层使用tanh,相比sigmoid有更好的梯度特性
  • 输出层:使用softmax确保三个类别的概率之和为1
  • 初始化:默认使用Glorot均匀初始化,适合tanh激活函数

3.2 模型编译配置

model.compile( optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'] )

选择Adam优化器是因为它能自动调整学习率,比标准梯度下降更高效。损失函数使用分类交叉熵,这是多分类问题的标准选择。

4. 模型训练与评估

4.1 训练过程监控

设置20%的训练数据作为验证集,监控过拟合情况:

history = model.fit( X_train, y_train, epochs=200, batch_size=16, validation_split=0.2, verbose=1 )

绘制训练曲线观察学习过程:

import matplotlib.pyplot as plt plt.plot(history.history['accuracy'], label='训练准确率') plt.plot(history.history['val_accuracy'], label='验证准确率') plt.xlabel('Epoch') plt.ylabel('Accuracy') plt.legend() plt.show()

4.2 测试集评估

最终在测试集上评估模型性能:

loss, accuracy = model.evaluate(X_test, y_test) print(f'测试集损失: {loss:.4f}, 准确率: {accuracy:.4f}')

典型输出结果:

测试集损失: 0.1023, 准确率: 0.9778

4.3 与逻辑回归对比

为了展示神经网络的优越性,我们与简单的逻辑回归比较:

from sklearn.linear_model import LogisticRegression lr = LogisticRegression(max_iter=200) lr.fit(X_train, y_train.argmax(axis=1)) print("逻辑回归测试准确率:", lr.score(X_test, y_test.argmax(axis=1)))

对比结果通常显示:

  • 逻辑回归准确率:约93-95%
  • 神经网络准确率:约97-98%

虽然在这个简单数据集上差距不大,但随着问题复杂度增加,神经网络的优势会更加明显。

5. 关键参数调优指南

通过这个基础实现后,你可以尝试以下优化策略进一步提升性能:

5.1 学习率调整

在model.compile中尝试不同的学习率:

from keras.optimizers import Adam model.compile( optimizer=Adam(learning_rate=0.001), # 默认0.001 loss='categorical_crossentropy', metrics=['accuracy'] )

5.2 批量大小影响

调整batch_size参数,常见选择有16、32、64:

history = model.fit( X_train, y_train, epochs=200, batch_size=32, # 尝试不同值 validation_split=0.2 )

5.3 早停法防止过拟合

当验证集性能不再提升时自动停止训练:

from keras.callbacks import EarlyStopping early_stop = EarlyStopping( monitor='val_loss', patience=20, restore_best_weights=True ) model.fit( X_train, y_train, epochs=500, # 设置更大的epochs callbacks=[early_stop] )

在实际项目中,这些调优技巧常常能带来明显的性能提升。鸢尾花数据集虽然简单,但完整走完这个流程后,你已经掌握了实现BP神经网络的核心方法论。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询