共计 1313 个字符,预计需要花费 4 分钟才能阅读完成。
传统方法的局限性
在机器学习领域,鸢尾花分类是一个经典的入门案例。传统方法如 KNN 或决策树虽然容易实现,但存在明显短板:

- 特征交互能力弱:花瓣和萼片的尺寸存在非线性组合特征
- 泛化性能不稳定:对噪声数据敏感且容易欠拟合
- 手动特征工程依赖性强
BP 神经网络的优势
相比传统方法,BP 神经网络通过多层非线性变换自动学习特征表示:
- 输入层(4 节点):对应花萼长度、花萼宽度、花瓣长度、花瓣宽度
- 隐藏层(6 节点):通过 sigmoid 激活引入非线性
- 输出层(3 节点):使用 softmax 输出三类鸢尾花的概率分布
核心代码实现
import numpy as np
class NeuralNetwork:
def __init__(self):
# 权重初始化(注意不能全零)self.W1 = np.random.randn(4, 6) * 0.01
self.b1 = np.zeros((1, 6))
self.W2 = np.random.randn(6, 3) * 0.01
self.b2 = np.zeros((1, 3))
def sigmoid(self, z):
return 1 / (1 + np.exp(-z))
def forward(self, X):
self.z1 = np.dot(X, self.W1) + self.b1
self.a1 = self.sigmoid(self.z1)
self.z2 = np.dot(self.a1, self.W2) + self.b2
# softmax 输出
exp_scores = np.exp(self.z2)
self.probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
反向传播推导
损失函数采用交叉熵:
$$ L = -\frac{1}{N}\sum_{i=1}^N\sum_{j=1}^3 y_{ij}\log(p_{ij}) $$
输出层梯度:
$$ \frac{\partial L}{\partial z2} = p – y $$
隐藏层梯度:
$$ \frac{\partial L}{\partial a1} = (p-y) \cdot W2^T $$
$$ \frac{\partial L}{\partial z1} = \frac{\partial L}{\partial a1} \odot a1 \odot (1-a1) $$
参数优化技巧
- 学习率对比实验:
- 0.1:震荡剧烈
- 0.01:稳定下降(推荐)
-
0.001:收敛过慢
-
L2 正则化实现:
reg_lambda = 0.01 loss += 0.5 * reg_lambda * (np.sum(np.square(W1)) + np.sum(np.square(W2))) dW2 += reg_lambda * W2 # 添加到梯度计算
实用调参建议
- 权重初始化:Xavier 初始化效果更佳
- 批量归一化:在激活前对 z 值做标准化
- 早停法:验证集准确率连续 3 轮不提升时终止
部署扩展思路
- Flask API 封装模型预测接口
- 使用 Swagger 生成交互文档
- 考虑用 PyTorch 重构获得 GPU 加速
通过本项目,你可以掌握:
– 神经网络的核心数学原理
– 从零编码实现的能力
– 工业级模型优化技巧
建议下一步尝试用不同的激活函数 (如 ReLU) 和优化器 (Adam) 进行对比实验,这将帮助你更深入理解深度学习调参的艺术。
正文完
