共计 1610 个字符,预计需要花费 5 分钟才能阅读完成。
背景:为什么需要理解神经网络架构
神经网络作为机器学习的核心模型,其架构设计直接影响模型表现。但初学者常被以下问题困扰:
– 为什么需要多个隐藏层?
– 权重到底如何影响数据流动?
– 为什么我的网络输出全是零?

本文将用代码和数学推导,带你看懂神经网络的基础架构。
一、输入层:数据的第一道门
输入层是原始数据的入口,核心任务是数据标准化。例如处理 MNIST 手写数字时:
# 原始像素值 (0-255) 标准化到 0 - 1 范围
X_train = X_raw / 255.0
assert X_train.max() <= 1.0 # 维度检查
关键点:
– 标准化能加速梯度下降收敛
– 输入层神经元数量 = 特征维度(如 28×28 图像展平后为 784)
二、隐藏层:神经网络的 ” 思考 ” 过程
激活函数选择
| 函数 | 公式 | 适用场景 |
|---|---|---|
| Sigmoid | $\sigma(z)=\frac{1}{1+e^{-z}}$ | 二分类输出层 |
| ReLU | $ReLU(z)=max(0,z)$ | 隐藏层首选 |
def relu(x):
return np.maximum(0, x)
# 对比实验:试试把这里改成 sigmoid 看训练速度变化
权重初始化陷阱
错误做法:
W = np.random.rand(784, 256) # 全部初始化为 (0,1) 随机数
正确做法(He 初始化):
W = np.random.randn(784, 256) * np.sqrt(2/784) # 考虑前层神经元数
为什么:不恰当的初始化会导致梯度消失 / 爆炸
三、输出层:给出最终答案
多分类问题用 Softmax
数学原理:
$softmax(z_i) = \frac{e^{z_i}}{\sum_{j=1}^K e^{z_j}}$
代码实现时注意数值稳定性:
def softmax(x):
exps = np.exp(x - np.max(x)) # 防溢出技巧
return exps / np.sum(exps, axis=1, keepdims=True)
四、完整前向传播实现
import numpy as np
# 网络参数
input_dim = 784
hidden_dim = 256
output_dim = 10
# 初始化权重(注意维度)W1 = np.random.randn(input_dim, hidden_dim) * 0.01
b1 = np.zeros((1, hidden_dim))
W2 = np.random.randn(hidden_dim, output_dim) * 0.01
b2 = np.zeros((1, output_dim))
# 前向传播
def forward(X):
# 第一层
z1 = np.dot(X, W1) + b1
a1 = relu(z1) # 激活函数
# 输出层
z2 = np.dot(a1, W2) + b2
return softmax(z2)
# 测试维度
X_sample = np.random.rand(32, 784) # 假设 batch_size=32
output = forward(X_sample)
assert output.shape == (32, 10) # 必须通过的检查
五、常见问题排查指南
1. 梯度消失诊断
- 现象:训练初期权重更新幅度极小
- 检查:各层激活值是否趋近 0(特别是使用 sigmoid 时)
2. 过拟合应对
- 添加 Dropout 层:
mask = (np.random.rand(*a1.shape) < 0.5) # 50% 丢弃 a1 = a1 * mask / 0.5 # 注意 scale 保持期望值
3. 层数选择原则
- 先从 1 - 2 层开始,逐步增加
- 参考验证集表现决定是否加深
动手实验建议
尝试修改以下参数观察效果:
1. 将 hidden_dim 改为 64/512,比较训练速度
2. 增加第三个隐藏层
3. 把 ReLU 换成 LeakyReLU(提示:np.where(x>0, x, 0.01*x))
总结
通过这次实践,我们搞清楚了:
– 神经网络各层的职责分工
– 权重初始化的正确姿势
– 如何通过维度检查避免低级错误
建议下一步:
1. 实现反向传播完成完整训练
2. 用 PyTorch/TensorFlow 重构此网络
3. 在真实数据集(如 MNIST)上测试效果
正文完
发表至: 未分类
近一天内
