理论学习:四张结构图在讲什么
先把那张图盖住,只留标题。
AI 界的四大天王:DNN、CNN、RNN、GAN。四个缩写你大概都念得出来。可我把图放大,指着 DNN 里的一条斜线问:这条线代表什么?你说是「连接」。我再问:连接里装的是什么数?它和旁边那条线是同一个数吗?换一张图,这个数还认得猫吗?
四个问题,能答上两个,说明你看过图;能答上四个,才说明你看懂了结构。
这张图的信息量不在四个缩写,在四种连线方式。它只画了谁连谁,没画每条线在算什么。这一篇不训练任何网络,只做一件事:把四张图拆成同一副骨架,让你看到箭头背后的乘加。
<!-- 配图:四张网络总览,2×2 布局,对应上传的四大天王图 -->
一、先找共同骨架
四张图长得完全不一样:DNN 是一排排圆点,CNN 是彩色方块和网格,RNN 是绕来绕去的箭头,GAN 是两个方框对着指。可它们都在回答同样三个问题:
- 输入是什么形状?
- 一层里谁和谁连?
- 输出是什么形态?
把装饰拿掉,任何网络的前向都是一条链:
x → z₁ = W₁x + b₁ → a₁ = σ(z₁) → z₂ = W₂a₁ + b₂ → ... → ŷ → L(ŷ, y)这里只有三种操作:线性变换、非线性激活、损失。区别在于 W 的形状、谁和谁共享 W、以及最后输出什么。
还有一个容易被忽略的事实:四张图都没有画「训练」。图是拓扑,训练是另一张图——损失、梯度、参数更新。你盯着这四张图看一辈子,也看不出学习率、反向传播和过拟合。那些是第 2 章的事。
所以这一篇只讲结构层:连接方式、参数共享、归纳偏置。把这三样抓住,四张图就变成了同一件事的四种方言。
| 网络 | 谁和谁连 | 什么被共享 | 输入假设 |
|---|---|---|---|
| DNN | 相邻层全连接 | 不共享 | 输入之间没有结构 |
| CNN | 局部窗口连接 | 同一个卷积核滑遍全图 | 有用模式是局部的、平移不变的 |
| RNN | 沿时间步连接 | 同一组权重在每个时刻复用 | 顺序有信息、不同时刻规律相同 |
| GAN | 生成器与判别器交叉连接 | 各自内部共享 | 数据分布可由噪声连续映射得到 |
二、DNN:全连接,最灵活也最贵
<!-- 配图:3-4-2 的全连接网络,一条线代表一个权重 -->
看这张 3-4-2 的图。左边三个输入 x₁、x₂、x₃,中间四个隐藏神经元 h₁ 到 h₄,右边两个输出 y₁、y₂。
每一条斜线都是一个权重。第一个隐藏神经元 h₁ 收到的输入是:
z₁ = w₁₁x₁ + w₂₁x₂ + w₃₁x₃ + b₁
h₁ = ReLU(z₁)注意下标:w₂₁ 是「第二个输入连到第一个隐藏神经元」的权重。图上那条加粗的蓝线,就是 w₁₁。
一个神经元做的事只有两件:把进来的数各自乘上权重、加起来,再过一次激活函数。一层四个神经元,就是把同一件事做四遍,只是每遍用一组不同的权重。
把这件事写成矩阵,一层就是一次乘法:
z = Wx + b输入 3 维,隐藏层 4 维,W 就是 4×3 的矩阵,b 是 4×1 的向量。参数量是 4×3 + 4 = 16。第二层 4 维到 2 维,参数量 2×4 + 2 = 10。整个网络 26 个参数,和图上连线的数量对得上:12 条输入到隐藏,8 条隐藏到输出,再加 6 个偏置。
现在把规模放大。手写数字 784 维输入,隐藏层 256 维:
784×256 + 256 = 200,960
256×10 + 10 = 2,570
合计 203,530 个参数还扛得住。换成一张 224×224×3 的彩色图,拉平就是 150,528 维。接一层 1000 个神经元的全连接:
150,528×1000 + 1000 ≈ 1.5 亿个参数光是这一层,float32 就要 600MB。还没开始训练,显存先没了。
这就是全连接的代价:它不做任何假设,默认每个输入都可能和每个输出有关系。假设最少,所以最灵活;也正因为假设最少,所有关系都得从数据里学,参数和样本都烧不起。
CNN 就是在这里拐弯的:图像里相邻像素的关系,比隔着一千个像素的关系重要得多。这个假设一加上,参数立刻掉几个数量级。
三、CNN:局部连接,一个核滑遍全图
<!-- 配图:7×7 输入、3×3 卷积核、5×5 特征图,高亮一个感受野 -->
图里左边是输入,中间是卷积核,右边是特征图。卷积核就是一个小矩阵,3×3 一共 9 个权重,再加 1 个偏置。
它的动作不是「连」,是「盖」:把 3×3 的窗口盖在输入左上角,9 个位置逐元素相乘再求和,得到一个输出值;然后窗口往右挪一格,再来一次。7×7 的输入,3×3 的核,步长 1,能盖出 5×5 个位置,每个位置都产生一个输出值。
关键在「同一个核」。25 个位置用的都是这 9 个权重,不是每个位置各有一套。参数共享就发生在这里。
算一下账。输入 3 通道,输出 32 个特征图,3×3 卷积核:
3×3×3×32 + 32 = 896 个参数输入从 224×224 换成 512×512,参数量还是 896。变的只是特征图的尺寸,不是权重数量。
这和全连接是两个世界。全连接把图像拉平,空间结构当场丢失;卷积保留网格,只在小窗口里做点积。一个 3×3 的核只看见 9 个像素,它怎么知道整张图里有没有猫?
靠堆。第一层的神经元只看 3×3,第二层把第一层的 3×3 拼起来,就能看到 5×5 的原图;第三层看到 7×7。层数越深,感受野越大。
<!-- 配图:三层 3×3 卷积,感受野 3→5→7 -->
感受野的递推公式:
RF_l = RF_(l-1) + (k_l - 1) × Π s_i三层 3×3、步长全是 1,感受野就是 3、5、7。想要更大的感受野,不一定非要上 7×7 的大核;三个 3×3 堆起来,感受野一样到 7,参数还更少:3×3×3 = 27,对比 7×7 = 49。
卷积的假设是两句话:有用的模式是局部的;同一个模式出现在图像哪个位置,都该被同样识别。这两句话对了,参数就省、样本就省;错了,比如任务依赖的是全局的、位置敏感的关系,卷积的 inductive bias 反而会拖后腿。
四、RNN:同一组权重,沿时间复用
<!-- 配图:x_t → h_t → y_t,h_t 上有一个 W_hh 自环 -->
DNN 和 CNN 都假设输入是一次性给全的。一句话、一段语音、一支股票的价格序列,不是一次给全的,是一个时刻来一个。
RNN 的折叠图只画了一个节点 h,加一个指向自己的环。这个环的意思是:上一时刻的隐藏状态,会作为下一时刻的输入之一,再回来一次。
展开成时间步,就是一条链:
<!-- 配图:三个时间步展开,三列共用同一组 W_xh、W_hh、W_hy -->
公式只有一行:
h_t = tanh(W_xh x_t + W_hh h_(t-1) + b_h)
y_t = W_hy h_t + b_yx_t 是当前输入,h_(t-1) 是上一时刻的记忆,h_t 是更新后的记忆。W_xh 负责「现在」,W_hh 负责「过去」,两个加起来再过 tanh。
参数共享发生在时间轴上:处理第 1 个词、第 50 个词、第 100 个词,用的都是同一组 W_xh、W_hh、W_hy。序列从 10 步变成 100 步,参数量一点不变。
算一下。输入 100 维,隐藏状态 128 维:
W_xh: 100×128 + 128 = 12,928
W_hh: 128×128 + 128 = 16,512
合计 29,440输出如果是 10 类,再加 W_hy 的 128×10 + 10 = 1,290,总共 30,730。
这也是 RNN 的代价所在。时间步必须串行:第 t 步要等第 t-1 步的 h 算完。序列有多长,前向就有多长,没法像 CNN 那样把整张图并行铺开。
更麻烦的是反向传播。BPTT 要把每个时间步的雅可比矩阵连乘起来。连乘 100 个小于 1 的数,梯度会缩到几乎为零;连乘 100 个大于 1 的数,梯度会爆掉。这就是梯度消失和梯度爆炸,第 7 章会用数值实验把它复现出来。
RNN 的假设是:顺序有信息,而且不同时刻的统计规律相同。这两句对,它就能用一组参数处理任意长度的序列;不对,比如关键信息隔了 500 个时间步,普通 RNN 就记不住。LSTM 和 GRU 的门控,就是为这个问题打的补丁。
五、GAN:两个网络,一套对抗 loss
<!-- 配图:噪声 z → 生成器 G → 假样本;真实样本与假样本进判别器 D -->
前面三个网络都在做「判断」:这张图是什么类、这个序列下一个词是什么。GAN 做的是「生成」:给我一批看起来像真的新样本。
图里有两个网络。生成器 G 吃一个噪声 z,吐出一个样本 G(z);判别器 D 吃一个样本,吐一个 0 到 1 之间的数,表示它觉得这个样本是真的概率。
训练目标写成一个极小极大问题:
min_G max_D E[log D(x)] + E[log(1 - D(G(z)))]拆开看。D 想最大化这两项:对真实样本 x,D(x) 越接近 1 越好;对生成样本 G(z),D(G(z)) 越接近 0 越好。G 想最小化第二项:它希望 D(G(z)) 越接近 1 越好,也就是骗过 D。
所以图上那两个箭头互相对着指,但两个网络各有一本账。更新 D 的时候,G 的参数冻结;更新 G 的时候,D 的参数冻结。谁也别想在一次 backward 里把对方的参数一起改了。
理论上,当 D 达到最优时,G 最小化的是真实分布和生成分布之间的 JS 散度。可如果两个分布的支撑集几乎不重叠——训练初期基本都这样——JS 散度是个常数,梯度为零,G 就学不动。判别器越强,G 越没梯度;判别器太弱,G 又拿不到有用的信号。这个平衡很难踩。
GAN 的假设是:真实数据分布可以被一个连续映射从低维噪声推出来,而且不需要显式地写出概率密度。假设成立,它能生成很逼真的样本;假设不成立,或者训练平衡没踩好,就会模式崩溃——G 只生成少数几种样本,别的都忘了。
六、把四张图放进同一张坐标
<!-- 配图:DNN 参数量随输入维度平方增长,CNN/RNN 基本不变 -->
现在可以横向对比了。
| 网络 | 连接方式 | 共享方式 | 归纳偏置 | 输出 | 参数随规模 | 训练难点 |
|---|---|---|---|---|---|---|
| DNN | 相邻层全连接 | 无 | 输入之间无结构假设 | 向量 | 随输入维度平方增长 | 参数多、易过拟合 |
| CNN | 局部窗口 | 卷积核滑遍全图 | 局部性 + 平移不变 | 特征图 | 与图像尺寸无关 | 深层退化、感受野受限 |
| RNN | 沿时间步 | 权重沿时间复用 | 顺序有信息、规律平稳 | 序列 | 与序列长度无关 | 梯度消失、不能并行 |
| GAN | 双网络对抗 | 各自内部共享 | 噪声可连续映射到数据 | 样本 | 取决于 G 与 D | 不收敛、模式崩溃 |
这张表最重要的一列是「归纳偏置」。说白了,就是你替模型做的假设。
DNN 的假设最少:它不认为输入有什么结构,所以什么都能学,但什么都要用参数和样本去堆。CNN 假设「有用的东西是局部的、挪个位置还认得」,于是参数从一亿降到几百。RNN 假设「顺序重要、不同时刻规律一样」,于是序列多长都用同一组权重。GAN 假设「数据分布可以被噪声推出来」,于是它不需要似然函数,只需要一个判别器。
假设对了,参数少、学得快、样本省;假设错了,网络再深、数据再多,也只是在错误的方向上用力。
七、回到开头的四个问题
- DNN 从 784 维接到 256 维,一层多少权重?200,960 个,外加 256 个偏置。
- CNN 的 3×3 核在 224×224 的图上滑,参数会变多吗?不会。9 个权重加 1 个偏置,图多大都一样。
- RNN 处理 100 个词,W 会变成 100 份吗?不会。W_xh、W_hh、W_hy 各只有一份,100 个时间步反复用。
- GAN 的判别器输出 0.7,是在夸生成器还是在骂它?看输入是谁。真实样本拿到 0.7,说明 D 没认出来,是在骂 D;生成样本拿到 0.7,说明 G 骗过了 D,是在夸 G。
四个问题答完,这张图就不再是四个并列的名词,而是四种假设。
还剩半个问题没解决:图里的箭头在反向传播时算什么?这一篇只讲了前向,箭头顺流而下;反向时箭头倒着走,每条线传的是梯度,不是数据。下一篇先把每条箭头写成一行公式,第 2 章再让箭头倒着走。
自检
合上笔记,试着不看图回答:
- 四种网络各自共享了什么?
- 为什么 CNN 的参数量与图像尺寸无关?
- 为什么 RNN 的时间步不能并行?
- GAN 的两个 loss 为什么不能一次 backward 一起算?
答不上来的那一条,回到对应小节,把公式和数字重新推一遍。下一章我们从最小的神经元开始,真的把它训起来。