BP神经网络实战:从零实现鸢尾花分类(附完整代码)

1次阅读
没有评论

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

image.webp

背景介绍

BP 神经网络(Backpropagation Neural Network)是一种使用反向传播算法进行训练的多层前馈神经网络。它的核心思想是通过不断调整网络中的权重和偏置,使得网络的输出尽可能接近真实值。这个过程包括前向传播计算输出和反向传播调整参数两个阶段。

BP 神经网络实战:从零实现鸢尾花分类(附完整代码)

鸢尾花数据集(Iris dataset)是机器学习中最经典的数据集之一,包含 150 个样本,每个样本有 4 个特征(花萼长度、花萼宽度、花瓣长度、花瓣宽度)和 1 个类别标签(Setosa、Versicolor、Virginica 三类)。这个数据集非常适合用来演示分类任务。

数据预处理

在开始训练之前,我们需要对数据进行预处理。主要包括以下几个步骤:

  1. 加载数据集:从 sklearn 库中直接导入鸢尾花数据集
  2. 数据标准化:将特征值缩放到 0 - 1 之间,避免某些特征值过大影响训练
  3. 标签编码:将类别标签转换为 one-hot 编码形式
  4. 数据集划分:将数据分为训练集和测试集

为什么需要标准化?因为神经网络对输入数据的范围很敏感,不同特征的数值范围差异过大会导致训练困难。

网络架构设计

对于鸢尾花分类这个相对简单的任务,我们设计一个 2 层隐藏层的 BP 神经网络:

  1. 输入层:4 个神经元,对应 4 个特征
  2. 第一个隐藏层:10 个神经元,使用 ReLU 激活函数
  3. 第二个隐藏层:8 个神经元,使用 ReLU 激活函数
  4. 输出层:3 个神经元(对应 3 个类别),使用 Softmax 激活函数

选择 ReLU 作为隐藏层激活函数是因为它计算简单且能有效缓解梯度消失问题。输出层使用 Softmax 是因为这是一个多分类问题,需要输出每个类别的概率。

完整代码实现

下面是使用 Python 和 TensorFlow 实现的完整代码:

import numpy as np
import tensorflow as tf
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler, OneHotEncoder
import matplotlib.pyplot as plt

# 加载数据集
iris = datasets.load_iris()
X = iris.data
y = iris.target.reshape(-1, 1)

# 数据预处理
scaler = MinMaxScaler()
X_scaled = scaler.fit_transform(X)

encoder = OneHotEncoder()
y_onehot = encoder.fit_transform(y).toarray()

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y_onehot, test_size=0.2, random_state=42)

# 定义模型
model = tf.keras.Sequential([tf.keras.layers.Dense(10, activation='relu', input_shape=(4,)),
    tf.keras.layers.Dense(8, activation='relu'),
    tf.keras.layers.Dense(3, activation='softmax')
])

# 编译模型
model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# 训练模型
history = model.fit(X_train, y_train, epochs=100, batch_size=16, validation_split=0.1)

# 评估模型
test_loss, test_acc = model.evaluate(X_test, y_test)
print(f'Test accuracy: {test_acc:.4f}')

# 可视化训练过程
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'], label='Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.legend()
plt.title('Accuracy Curve')

plt.subplot(1, 2, 2)
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.legend()
plt.title('Loss Curve')
plt.show()

调优技巧

在训练神经网络时,有几个关键的超参数需要注意:

  1. 学习率:控制参数更新的步长。太大的学习率可能导致震荡,太小则收敛慢。建议从 0.001 开始尝试
  2. Batch size:影响训练速度和模型泛化能力。较小的 batch size(如 16、32)通常效果更好
  3. 迭代次数(epochs):太少会导致欠拟合,太多会导致过拟合。可以观察验证集准确率变化来决定
  4. 网络结构:隐藏层神经元数量可以尝试调整,但要注意不是越多越好

避坑指南

新手在使用 BP 神经网络时容易犯以下错误:

  1. 忘记数据标准化:这会导致训练困难甚至无法收敛
  2. 使用不合适的激活函数:比如在输出层错误使用 ReLU 而不是 Softmax
  3. 学习率设置不当:太大或太小都会影响训练效果
  4. 忽略过拟合问题:可以通过添加 Dropout 层或正则化来缓解
  5. 没有验证集:训练过程中无法监控模型在未见数据上的表现

延伸思考

如果你已经成功实现了基础版本,可以尝试以下改进:

  1. 增加网络深度:尝试添加更多隐藏层,观察效果变化
  2. 尝试不同优化器:比如 SGD、RMSprop 等,比较它们的表现
  3. 添加正则化:使用 L2 正则化或 Dropout 来防止过拟合
  4. 数据增强:通过现有数据生成新的训练样本
  5. 交叉验证:更可靠地评估模型性能

现在,你已经掌握了 BP 神经网络实现鸢尾花分类的基本方法。建议你尝试修改网络结构或超参数,观察模型性能的变化,这会帮助你更深入地理解神经网络的工作原理。

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