深度学习实战练习 (Deep Learning Exercises)
“神经网络的强大源于其层层递进的非线性变换。” —— 本专题聚焦神经网络底层机制、架构优化及大规模分布式训练原理,配套 C++ 算子级模拟。
🪜 练习阶梯与评价标准
| 等级 | 难度目标 | 核心考察点 | 期望达成 |
|---|---|---|---|
| ● Level A | 张量运算与 BP | 反向传播、激活函数、卷积计算 | 理解梯度流动的物理本质 |
| ● Level B | 模型设计与正则 | BN/LN 原理、Dropout、ResNet 结构 | 具备解决梯度消失/爆炸能力 |
| ● Level C | 架构创新与工程 | Transformer 缩放点积、分布式 SGD | 理解现代 LLM 底层设计逻辑 |
🎯 考点覆盖模型 (Knowledge Matrix)
| 知识模块 | 核心考点 | 关联习题 | 推荐等级 |
|---|---|---|---|
| 反向传播 | 自动微分原理、梯度链式法则矩阵化 | 练习 1, 6 | Level A |
| 卷积神经网络 | 感受野计算、参数量推导、空洞卷积 | 练习 2 | Level A |
| 正则化与归一化 | BN 推理偏差、LayerNorm 原理 | 练习 3 | Level B |
| 残差结构 | 恒等映射证明、梯度流优化 | 练习 4 | Level B |
| 注意力机制 | Scaled Dot-Product 统计学意义 | 练习 5 | Level C |
| 优化器算法 | Momentum, Adam, 学习率调度 | 练习 7 | Level C |
📂 核心习题库
Level A:基础巩固 (Foundations)
练习 1:反向传播 (Backpropagation) 的矩阵形式推导
题目描述:在全连接网络中,已知第 层的激活值为 ,。定义误差 。请推导 与 的递推关系。
Check Solution (Matrix Derivation)
推导过程:
- 链式法则展开:
- 计算局部导数: 由于 。 则 。
- 合并项:
- 矩阵化表示: 其中 表示 Hadamard 积。
练习 2:卷积层参数量计算
题目描述:输入图像尺寸 ,使用 卷积核,步长 2,填充 3,输出通道数 64。求输出尺寸及该层参数量(含偏置)。
Check Solution
计算步骤:
- 尺寸计算:。输出为 。
- 参数量:每个卷积核参数 = 。总参数 = 。
Level B:综合提升 (Intermediate)
练习 3:Batch Normalization (BN) 的作用与推理偏差
题目描述:为什么 BN 在训练和推理(Test time)时的行为不同?推理时如何获得均值和方差?
Check Solution
核心机制:
- 训练时:利用当前 Batch 的均值 和方差 进行归一化,以加速收敛并缓解梯度消失。
- 推理时:单个样本没有 Batch 统计量。因此,推理时使用训练过程中通过 移动平均 (Running Average) 累计得到的全局均值和方差。
- 目的:确保推理结果的确定性,不依赖于推理时的 Batch Size。
练习 4:ResNet 解决退化问题的数学直觉
题目描述:考虑残差块 。请从梯度流的角度解释为什么这种设计能允许训练成百上千层的网络。
Check Solution
梯度流分析: 在反向传播时,。 由于存在常数项 ,梯度可以直接跨过复杂的非线性层 传回前一层。即使 层的权重导致梯度消失(),整体梯度依然保持在 左右,确保了深层网络参数的有效更新。
Level C:竞赛挑战 (Advanced)
练习 5:Attention 机制中的 Scaled Dot-Product
题目描述:在 Transformer 的注意力计算中,。为什么需要除以 ?
Check Solution
统计学解释: 假设 和 的分量是独立且均值为 0、方差为 1 的随机变量。则点积 的均值为 0,方差为 。 当 很大时,点积的量级会变得非常大,导致经过 softmax 后梯度落入饱和区(极小),引发梯度消失。除以 可以将方差重新缩放到 1,使 softmax 的输入处于敏感区,确保梯度平稳。
练习 6:手写神经网络反向传播 (C++ Implementation)
题目描述:实现一个简单的 2 层 MLP(全连接网络)在 C++ 中的前馈过程。
Check Solution (C++ Neural Engine Simulation)
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
// 简单激活函数
double sigmoid(double x) { return 1.0 / (1.0 + exp(-x)); }
struct Layer {
int in, out;
vector<vector<double>> W;
vector<double> b, a;
Layer(int i, int o) : in(i), out(o), W(o, vector<double>(i, 0.1)), b(o, 0), a(o, 0) {}
void forward(const vector<double>& input) {
for (int i = 0; i < out; i++) {
double sum = b[i];
for (int j = 0; j < in; j++) sum += W[i][j] * input[j];
a[i] = sigmoid(sum);
}
}
};
int main() {
vector<double> input = {0.5, 0.3};
Layer layer1(2, 3);
layer1.forward(input);
cout << "Output Activations: ";
for (double val : layer1.a) cout << val << " ";
cout << endl;
return 0;
}
🏆 训练建议
- 理解归一化:对比 BN, LN, IN, GN 的应用场景(如 NLP 为什么首选 LN)。
- 关注感受野:计算深层网络中一个神经元对应的输入图像区域大小。
- 工程实战:尝试在 PyTorch 中从零实现一个带有残差结构的 Transformer Block。