共计 2660 个字符,预计需要花费 7 分钟才能阅读完成。
背景痛点
鸢尾花分类是机器学习中的经典案例,传统方法如决策树或 SVM 虽然有效,但存在明显局限:

- 特征交互能力弱:花瓣和萼片的尺寸存在复杂非线性关系
- 手动特征工程依赖性强:需要人工设计决策边界规则
- 扩展性差:当新增类别时需重新调整模型结构
BP 神经网络恰好能解决这些问题:
- 自动学习特征组合:通过隐藏层捕捉多维特征间的关系
- 端到端训练:从原始数据直接输出分类结果
- 结构灵活:只需调整网络层数即可适应更复杂场景
技术实现
数据准备
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
# 加载数据
iris = load_iris()
X, y = iris.data, iris.target
# 标准化(重要!)scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
网络构建
关键设计原则:
- 输入层节点数:4 个(对应 4 个特征)
- 隐藏层节点数:经验公式
(输入 + 输出)/2取整,这里选择 8 个 - 输出层节点数:3 个(使用 softmax 输出概率分布)
from keras.models import Sequential
from keras.layers import Dense
model = Sequential([Dense(8, activation='relu', input_shape=(4,)), # 隐藏层
Dense(3, activation='softmax') # 输出层
])
模型训练
优化配置
model.compile(
optimizer='adam', # 自适应学习率优化器
loss='sparse_categorical_crossentropy', # 多分类损失
metrics=['accuracy'])
# 训练过程可视化
history = model.fit(
X_train, y_train,
epochs=200,
batch_size=16,
validation_split=0.1,
verbose=0)
训练监控
import matplotlib.pyplot as plt
plt.plot(history.history['accuracy'], label='Train')
plt.plot(history.history['val_accuracy'], label='Validation')
plt.title('Model Accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend()
plt.show()
性能评估
测试集验证
from sklearn.metrics import classification_report
y_pred = model.predict(X_test).argmax(axis=1)
print(classification_report(y_test, y_pred))
典型输出示例:
precision recall f1-score support
0 1.00 1.00 1.00 10
1 1.00 0.89 0.94 9
2 0.92 1.00 0.96 11
accuracy 0.97 30
macro avg 0.97 0.96 0.97 30
weighted avg 0.97 0.97 0.97 30
避坑指南
过拟合应对
-
添加 Dropout 层(推荐率 0.2-0.5):
from keras.layers import Dropout model.add(Dropout(0.3)) # 添加在隐藏层后 -
使用 L2 正则化:
from keras.regularizers import l2 Dense(8, activation='relu', kernel_regularizer=l2(0.01))
梯度消失对策
-
换用 LeakyReLU 激活函数:
from keras.layers import LeakyReLU model.add(Dense(8)) model.add(LeakyReLU(alpha=0.1)) -
添加 BatchNorm 层:
from keras.layers import BatchNormalization model.add(Dense(8)) model.add(BatchNormalization()) model.add(Activation('relu'))
进阶建议
-
动态学习率:
from keras.callbacks import ReduceLROnPlateau reduce_lr = ReduceLROnPlateau( monitor='val_loss', factor=0.2, patience=5) -
早停法:
from keras.callbacks import EarlyStopping es = EarlyStopping( monitor='val_accuracy', patience=10, restore_best_weights=True) -
超参数搜索:
from keras.wrappers.scikit_learn import KerasClassifier from sklearn.model_selection import GridSearchCV # 创建模型函数 def create_model(units=8): model = Sequential([...]) model.compile(...) return model # 参数网格 param_grid = {'units': [4, 8, 16]} grid = GridSearchCV(KerasClassifier(build_fn=create_model), param_grid, cv=3) grid.fit(X_train, y_train)
实践心得
通过这个项目可以发现:
- 数据标准化对神经网络训练至关重要
- 隐藏层节点不是越多越好,适当冗余即可
- Adam 优化器在大多数情况下表现稳定
- 验证集曲线是判断过拟合的最佳工具
建议尝试调整以下参数观察效果:
- 将隐藏层节点改为 16 个
- 尝试 tanh 激活函数
- 调整 batch_size 为 32
- 添加第二个隐藏层
每次修改后记录验证集准确率,你会对神经网络的特性有更直观的理解。
正文完
