NTU EE7207 神经网络与深度学习 — 课程总结
最后更新: 2025年12月
2025年下半年在南洋理工大学修读了 EE7207 Neural Networks and Deep Learning,系统地从感知器学到了 Transformer。这篇文章是课程的复盘与个人总结,适合有一定编程基础但刚接触深度学习的同学参考。
课程概览
EE7207 是 NTU 电气与电子工程学院的研究生核心课程,理论与实践并重,主要涵盖:
- 经典神经网络:感知器、MLP、反向传播
- 径向基函数网络:RBF / Gaussian 核、聚类中心选取
- 卷积神经网络 (CNN):图像特征提取、经典架构
- 循环神经网络 (RNN / LSTM):序列建模与时序依赖
- 支持向量机 (SVM):核技巧与间隔最大化
- 现代深度学习:Attention、正则化、优化器
1. 神经网络基础
从感知器到 MLP
感知器(Perceptron)是最基础的线性分类器:输入加权求和,经过激活函数输出。
单层感知器只能处理线性可分问题——XOR 问题直接打倒了它。加入隐藏层后形成多层感知器(MLP),理论上可以逼近任意连续函数(万能近似定理)。
import torch.nn as nn
class MLP(nn.Module):
def __init__(self, in_dim, hidden_dim, out_dim):
super().__init__()
self.net = nn.Sequential(
nn.Linear(in_dim, hidden_dim),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(hidden_dim, out_dim)
)
def forward(self, x):
return self.net(x)
激活函数选型
| 激活函数 | 公式 | 优点 | 缺点 |
|---|---|---|---|
| Sigmoid | 1/(1+e⁻ˣ) | 输出有界 [0,1] | 梯度消失、非零中心 |
| Tanh | (eˣ-e⁻ˣ)/(eˣ+e⁻ˣ) | 零中心 | 仍有梯度消失 |
| ReLU | max(0, x) | 计算快、无饱和 | 死神经元(负区间永久关闭) |
| Leaky ReLU | max(αx, x) | 解决死神经元 | 需调 α |
实践经验: 隐藏层默认 ReLU,分类输出层用 Softmax,回归用 Linear,二分类用 Sigmoid。
2. 反向传播
BP 算法是神经网络训练的核心,本质是链式法则 + 梯度下降。
前向传播 → 计算损失 → 反向求梯度 → 更新权重
损失函数
# 多分类
loss = nn.CrossEntropyLoss()(output, labels)
# 回归
loss = nn.MSELoss()(output, targets)
优化器
# Adam(大多数任务首选)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3, weight_decay=1e-4)
# SGD + Momentum(大规模视觉任务有时更优)
optimizer = torch.optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
学习率调度:
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=100)
3. RBF 网络 — Assignment 1 实战
课程第一次作业:用 Gaussian RBF 神经网络完成二分类任务。这是我第一次真正从头设计一个神经网络(不是调包),印象很深。
RBF 网络结构
输入层(d维)→ 隐藏层(M个高斯节点)→ 输出层(线性)
隐藏层每个节点计算输入到中心点的 Gaussian 响应:
φⱼ(x) = exp( -||x - cⱼ||² / (2σⱼ²) )
设计关键点
Step 1: 用 k-means 确定中心点
from sklearn.cluster import KMeans
M = 20 # 隐藏节点数,通过交叉验证选取
kmeans = KMeans(n_clusters=M, random_state=42).fit(X_train)
centers = kmeans.cluster_centers_ # shape: (M, d)
Step 2: 用 P-nearest-neighbor 启发式确定宽度 σ
import numpy as np
from scipy.spatial.distance import cdist
D = cdist(centers, centers)
np.fill_diagonal(D, np.inf)
# 每个中心点到最近邻中心的距离作为 σ
sigma = D.min(axis=1)
Step 3: 构造隐藏层输出矩阵,伪逆求权重
def rbf_layer(X, centers, sigma):
dist2 = cdist(X, centers, 'sqeuclidean') # (N, M)
return np.exp(-dist2 / (2 * sigma**2))
Phi = rbf_layer(X_train, centers, sigma) # (N, M)
W = np.linalg.pinv(Phi) @ y_train # 输出权重
# 预测
Phi_test = rbf_layer(X_test, centers, sigma)
y_pred = np.sign(Phi_test @ W)
RBF vs MLP
| RBF 网络 | MLP | |
|---|---|---|
| 训练方式 | 解析解(伪逆) | 迭代梯度下降 |
| 训练速度 | 极快 | 较慢 |
| 小数据表现 | 好(局部拟合强) | 容易过拟合 |
| 大数据扩展 | 一般 | 强 |
| 超参数 | M, σ, 中心点 | 层数、宽度、lr |
结论:小数据 + 明确的局部结构 → RBF 有优势;大规模任务 → MLP / CNN 更合适。
4. 卷积神经网络 (CNN)
CNN 的核心思想:局部连接 + 权重共享,大幅减少参数量的同时保留空间信息。
class CNN(nn.Module):
def __init__(self, num_classes=10):
super().__init__()
self.features = nn.Sequential(
nn.Conv2d(1, 32, 3, padding=1), # 卷积
nn.BatchNorm2d(32),
nn.ReLU(),
nn.MaxPool2d(2), # 下采样
nn.Conv2d(32, 64, 3, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.MaxPool2d(2),
)
self.head = nn.Sequential(
nn.Dropout(0.5),
nn.Linear(64 * 7 * 7, 256),
nn.ReLU(),
nn.Linear(256, num_classes)
)
def forward(self, x):
return self.head(self.features(x).flatten(1))
感受野理解: 两层 3×3 卷积 = 一个 5×5 的等效感受野,但参数量是 2×(3×3×C²) vs (5×5×C²),参数更少、非线性更强。这是 VGG / ResNet 的设计出发点。
5. 序列建模:RNN 与 LSTM
标准 RNN 受梯度消失限制,难以学习长距离依赖。LSTM 通过门控机制解决了这个问题:
遗忘门(ft): 决定丢弃多少历史信息
输入门(it): 决定写入多少新信息
输出门(ot): 决定输出多少隐状态
lstm = nn.LSTM(input_size=64, hidden_size=128,
num_layers=2, batch_first=True, dropout=0.3)
output, (hn, cn) = lstm(x) # x: (B, T, 64)
实际上在学这门课之前,我已经在 RoPEHAR 毫米波 HAR 项目中用过 LSTM 做时序建模。当时更多是按文献照搬结构,对门控机制的物理含义不太清楚。修完这门课之后,才真正理解遗忘门和输入门是如何在每个时间步上动态决定”保留多少历史”与”写入多少新信息”的——这种选择性记忆正是 LSTM 在长序列上优于标准 RNN 的本质原因。
6. 正则化 — 对抗过拟合
Dropout: 训练时随机丢弃,测试时全激活
nn.Dropout(p=0.5)
Batch Normalization: 每个 mini-batch 归一化,稳定训练,是现代网络的标配
nn.BatchNorm2d(num_features) # 卷积层后
nn.LayerNorm(hidden_dim) # Transformer 中
L2 正则化(权重衰减)
optimizer = torch.optim.Adam(model.parameters(), weight_decay=1e-4)
Early Stopping: 监控验证集 loss,停止时机比学习率调度更重要
if val_loss < best_val_loss:
best_val_loss = val_loss
torch.save(model.state_dict(), 'best_model.pt')
推荐资料
- 李沐《动手学深度学习》 — B站,理论+代码同步讲解,中文友好
- Deep Learning Book (Goodfellow et al.)
- CS231n (Stanford)
- CS224n (Stanford)
- PyTorch 官方教程
- Andrej Karpathy’s Blog
课程作业代码:github.com/Mr-VanGogh-K/EE7207
欢迎交流: jiacheng008@e.ntu.edu.sg