共计 2076 个字符,预计需要花费 6 分钟才能阅读完成。
背景与核心挑战
全连接神经网络(Fully Connected Network)在图像分类、时序预测等任务中曾是主流选择。比如早期的 MNIST 手写数字识别,全连接网络就能达到不错的效果。但随着数据复杂度提升,暴露出两个致命问题:

- 参数量爆炸 :输入为 224×224 图像时,首层参数即达 224×224×512≈2500 万,显存直接溢出
- 梯度消失 :Sigmoid 激活函数在反向传播时梯度最大仅 0.25,5 层连乘后梯度值衰减至 0.001 以下
数学原理拆解
前向传播本质是矩阵连乘加非线性变换。以第 $l$ 层为例:
$$\mathbf{z}^l = W^l \mathbf{a}^{l-1} + \mathbf{b}^l$$
$$\mathbf{a}^l = \sigma(\mathbf{z}^l)$$
不同激活函数的导数差异显著:
-
Sigmoid:
$$\frac{d\sigma}{dz} = \sigma(z)(1-\sigma(z))$$
当 $z=0$ 时取得最大值 0.25 -
ReLU:
$$\frac{d\text{ReLU}}{dz} = \begin{cases}
1 & \text{if} z > 0 \
0 & \text{otherwise}
\end{cases}$$
有效缓解梯度消失但可能引发神经元死亡
PyTorch 完整实现
import torch.nn as nn
import torch.nn.functional as F
class FiveLayerFC(nn.Module):
def __init__(self, input_dim=784, hidden_dims=[512,256,128,64]):
super().__init__()
self.layers = nn.ModuleList([
nn.Sequential(nn.Linear(input_dim if i==0 else hidden_dims[i-1], hidden_dims[i]),
nn.BatchNorm1d(hidden_dims[i]),
nn.ReLU(),
nn.Dropout(0.3)
) for i in range(4)
])
self.classifier = nn.Linear(hidden_dims[-1], 10)
def forward(self, x):
x = x.view(x.size(0), -1) # 展平输入 [B, C*H*W]
for layer in self.layers:
x = layer(x)
return self.classifier(x)
关键设计点:
- ModuleList:动态管理各层,避免手动定义 5 个变量
- BatchNorm:在激活函数前加入,加速收敛
- Dropout:随机屏蔽 30% 神经元防止过拟合
训练优化技巧
权重初始化
def init_weights(m):
if isinstance(m, nn.Linear):
nn.init.xavier_normal_(m.weight, gain=nn.init.calculate_gain('relu'))
m.bias.data.fill_(0.01)
model.apply(init_weights)
动态学习率
# 阶梯式下降
scheduler1 = torch.optim.lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1)
# 余弦退火
scheduler2 = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=100)
常见问题解决方案
梯度检查
from torch.autograd import gradcheck
input = torch.randn(10,784, requires_grad=True)
test = gradcheck(model, input, eps=1e-6)
print("Gradient check passed:", test)
显存不足
accum_steps = 4
for i, (inputs, labels) in enumerate(train_loader):
outputs = model(inputs)
loss = criterion(outputs, labels)
loss = loss / accum_steps # 梯度累积
loss.backward()
if (i+1) % accum_steps == 0:
optimizer.step()
optimizer.zero_grad()
性能验证
| 配置 | MNIST 准确率 | CIFAR-10 准确率 |
|---|---|---|
| Sigmoid+ 无 BN | 97.2% | 52.1% |
| ReLU+BN | 98.7% | 63.4% |
| ReLU+BN+Dropout | 98.9% | 65.8% |
| ReLU+BN+CosineLR | 99.1% | 67.2% |
实际开发中发现几个关键经验:
- BatchNorm 层对深层网络稳定训练至关重要
- 学习率 warmup 能提升 CosineAnnealing 效果
- 梯度累积步数建议设为 2 的幂次方
全连接网络虽不如 CNN/Transformer 流行,但在特征维度较低的场景(如表格数据)仍有应用价值。理解其运作原理对掌握更复杂模型也大有裨益。
正文完
