Skip to content

理论学习:四张结构图在讲什么 ​

先把那张图盖住,只留标题。

AI 界的四大天王:DNN、CNN、RNN、GAN。四个缩写你大概都念得出来。可我把图放大,指着 DNN 里的一条斜线问:这条线代表什么?你说是「连接」。我再问:连接里装的是什么数?它和旁边那条线是同一个数吗?换一张图,这个数还认得猫吗?

四个问题,能答上两个,说明你看过图;能答上四个,才说明你看懂了结构。

这张图的信息量不在四个缩写,在四种连线方式。它只画了谁连谁,没画每条线在算什么。这一篇不训练任何网络,只做一件事:把四张图拆成同一副骨架,让你看到箭头背后的乘加。

四张网络总览

<!-- 配图:四张网络总览,2×2 布局,对应上传的四大天王图 -->

一、先找共同骨架 ​

四张图长得完全不一样:DNN 是一排排圆点,CNN 是彩色方块和网格,RNN 是绕来绕去的箭头,GAN 是两个方框对着指。可它们都在回答同样三个问题:

  1. 输入是什么形状?
  2. 一层里谁和谁连?
  3. 输出是什么形态?

把装饰拿掉,任何网络的前向都是一条链:

text
x → z₁ = W₁x + b₁ → a₁ = σ(z₁) → z₂ = W₂a₁ + b₂ → ... → ŷ → L(ŷ, y)

这里只有三种操作:线性变换、非线性激活、损失。区别在于 W 的形状、谁和谁共享 W、以及最后输出什么。

还有一个容易被忽略的事实:四张图都没有画「训练」。图是拓扑,训练是另一张图——损失、梯度、参数更新。你盯着这四张图看一辈子,也看不出学习率、反向传播和过拟合。那些是第 2 章的事。

所以这一篇只讲结构层:连接方式、参数共享、归纳偏置。把这三样抓住,四张图就变成了同一件事的四种方言。

网络谁和谁连什么被共享输入假设
DNN相邻层全连接不共享输入之间没有结构
CNN局部窗口连接同一个卷积核滑遍全图有用模式是局部的、平移不变的
RNN沿时间步连接同一组权重在每个时刻复用顺序有信息、不同时刻规律相同
GAN生成器与判别器交叉连接各自内部共享数据分布可由噪声连续映射得到

二、DNN:全连接,最灵活也最贵 ​

DNN 全连接拓扑

<!-- 配图:3-4-2 的全连接网络,一条线代表一个权重 -->

看这张 3-4-2 的图。左边三个输入 x₁、x₂、x₃,中间四个隐藏神经元 h₁ 到 h₄,右边两个输出 y₁、y₂。

每一条斜线都是一个权重。第一个隐藏神经元 h₁ 收到的输入是:

text
z₁ = w₁₁x₁ + w₂₁x₂ + w₃₁x₃ + b₁
h₁ = ReLU(z₁)

注意下标:w₂₁ 是「第二个输入连到第一个隐藏神经元」的权重。图上那条加粗的蓝线,就是 w₁₁。

一个神经元做的事只有两件:把进来的数各自乘上权重、加起来,再过一次激活函数。一层四个神经元,就是把同一件事做四遍,只是每遍用一组不同的权重。

把这件事写成矩阵,一层就是一次乘法:

text
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 维:

text
784×256 + 256 = 200,960
256×10 + 10 = 2,570
合计 203,530 个参数

还扛得住。换成一张 224×224×3 的彩色图,拉平就是 150,528 维。接一层 1000 个神经元的全连接:

text
150,528×1000 + 1000 ≈ 1.5 亿个参数

光是这一层,float32 就要 600MB。还没开始训练,显存先没了。

这就是全连接的代价:它不做任何假设,默认每个输入都可能和每个输出有关系。假设最少,所以最灵活;也正因为假设最少,所有关系都得从数据里学,参数和样本都烧不起。

CNN 就是在这里拐弯的:图像里相邻像素的关系,比隔着一千个像素的关系重要得多。这个假设一加上,参数立刻掉几个数量级。

三、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 卷积核:

text
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 -->

感受野的递推公式:

text
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:同一组权重,沿时间复用 ​

RNN 折叠画法

<!-- 配图:x_t → h_t → y_t,h_t 上有一个 W_hh 自环 -->

DNN 和 CNN 都假设输入是一次性给全的。一句话、一段语音、一支股票的价格序列,不是一次给全的,是一个时刻来一个。

RNN 的折叠图只画了一个节点 h,加一个指向自己的环。这个环的意思是:上一时刻的隐藏状态,会作为下一时刻的输入之一,再回来一次。

展开成时间步,就是一条链:

RNN 展开画法

<!-- 配图:三个时间步展开,三列共用同一组 W_xh、W_hh、W_hy -->

公式只有一行:

text
h_t = tanh(W_xh x_t + W_hh h_(t-1) + b_h)
y_t = W_hy h_t + b_y

x_t 是当前输入,h_(t-1) 是上一时刻的记忆,h_t 是更新后的记忆。W_xh 负责「现在」,W_hh 负责「过去」,两个加起来再过 tanh。

参数共享发生在时间轴上:处理第 1 个词、第 50 个词、第 100 个词,用的都是同一组 W_xh、W_hh、W_hy。序列从 10 步变成 100 步,参数量一点不变。

算一下。输入 100 维,隐藏状态 128 维:

text
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 ​

GAN 双网络结构

<!-- 配图:噪声 z → 生成器 G → 假样本;真实样本与假样本进判别器 D -->

前面三个网络都在做「判断」:这张图是什么类、这个序列下一个词是什么。GAN 做的是「生成」:给我一批看起来像真的新样本。

图里有两个网络。生成器 G 吃一个噪声 z,吐出一个样本 G(z);判别器 D 吃一个样本,吐一个 0 到 1 之间的数,表示它觉得这个样本是真的概率。

训练目标写成一个极小极大问题:

text
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 假设「数据分布可以被噪声推出来」,于是它不需要似然函数,只需要一个判别器。

假设对了,参数少、学得快、样本省;假设错了,网络再深、数据再多,也只是在错误的方向上用力。

七、回到开头的四个问题 ​

  1. DNN 从 784 维接到 256 维,一层多少权重?200,960 个,外加 256 个偏置。
  2. CNN 的 3×3 核在 224×224 的图上滑,参数会变多吗?不会。9 个权重加 1 个偏置,图多大都一样。
  3. RNN 处理 100 个词,W 会变成 100 份吗?不会。W_xh、W_hh、W_hy 各只有一份,100 个时间步反复用。
  4. GAN 的判别器输出 0.7,是在夸生成器还是在骂它?看输入是谁。真实样本拿到 0.7,说明 D 没认出来,是在骂 D;生成样本拿到 0.7,说明 G 骗过了 D,是在夸 G。

四个问题答完,这张图就不再是四个并列的名词,而是四种假设。

还剩半个问题没解决:图里的箭头在反向传播时算什么?这一篇只讲了前向,箭头顺流而下;反向时箭头倒着走,每条线传的是梯度,不是数据。下一篇先把每条箭头写成一行公式,第 2 章再让箭头倒着走。

自检 ​

合上笔记,试着不看图回答:

  • 四种网络各自共享了什么?
  • 为什么 CNN 的参数量与图像尺寸无关?
  • 为什么 RNN 的时间步不能并行?
  • GAN 的两个 loss 为什么不能一次 backward 一起算?

答不上来的那一条,回到对应小节,把公式和数字重新推一遍。下一章我们从最小的神经元开始,真的把它训起来。