BP神经网络实战:鸢尾花分类的简洁实现与调优指南

1次阅读
没有评论

共计 2660 个字符,预计需要花费 7 分钟才能阅读完成。

image.webp

背景痛点

鸢尾花分类是机器学习中的经典案例,传统方法如决策树或 SVM 虽然有效,但存在明显局限:

BP 神经网络实战:鸢尾花分类的简洁实现与调优指南

  • 特征交互能力弱:花瓣和萼片的尺寸存在复杂非线性关系
  • 手动特征工程依赖性强:需要人工设计决策边界规则
  • 扩展性差:当新增类别时需重新调整模型结构

BP 神经网络恰好能解决这些问题:

  1. 自动学习特征组合:通过隐藏层捕捉多维特征间的关系
  2. 端到端训练:从原始数据直接输出分类结果
  3. 结构灵活:只需调整网络层数即可适应更复杂场景

技术实现

数据准备

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

避坑指南

过拟合应对

  1. 添加 Dropout 层(推荐率 0.2-0.5):

    from keras.layers import Dropout
    
    model.add(Dropout(0.3))  # 添加在隐藏层后 

  2. 使用 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'))

进阶建议

  1. 动态学习率:

    from keras.callbacks import ReduceLROnPlateau
    
    reduce_lr = ReduceLROnPlateau(
        monitor='val_loss', 
        factor=0.2,
        patience=5)

  2. 早停法:

    from keras.callbacks import EarlyStopping
    
    es = EarlyStopping(
        monitor='val_accuracy', 
        patience=10, 
        restore_best_weights=True)

  3. 超参数搜索:

    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 优化器在大多数情况下表现稳定
  • 验证集曲线是判断过拟合的最佳工具

建议尝试调整以下参数观察效果:

  1. 将隐藏层节点改为 16 个
  2. 尝试 tanh 激活函数
  3. 调整 batch_size 为 32
  4. 添加第二个隐藏层

每次修改后记录验证集准确率,你会对神经网络的特性有更直观的理解。

正文完
 0
评论(没有评论)