← 返回周报
HIDDEN LAYER · 2026-03-23 18:00 · 样本 #329

一个样本走进隐藏层

这一页用训练好的真实权重,把某一个样本从输入到输出完整拆开。 不是示意图,每一个数字都是模型实际算出来的。

01

输入:12 个小时的流量

模型看到的不是日期,是 12 个数字。下面是原始值和标准化(z-score,减均值除标准差)之后的值。

06:00
162-0.80
07:00
646+0.05
08:00
1214+1.05
09:00
1790+2.05
10:00
1358+1.30
11:00
1539+1.61
12:00
1586+1.70
13:00
1504+1.55
14:00
1305+1.20
15:00
1131+0.90
16:00
1250+1.11
17:00
661+0.08

均值和标准差来自训练集:μ = 617.32,σ = 570.95。 标准化后的值才是模型真正看到的输入。

02

隐藏层长什么样:一张 12 × 16 的权重表

这就是隐藏层的全部内容。16 个神经元,每个神经元对 12 个输入各有一个权重,共 192 个数字。行是输入时刻,列是神经元编号,颜色深浅表示权重绝对值。 鼠标悬停可以看到精确数值。

n1n2n3n4n5n6n7n8n9n10n11n12n13n14n15n16
06:00
+0.11
-0.56
+0.31
+0.22
-0.65
-0.47
+0.06
-0.16
+0.03
-0.30
+0.35
+0.31
-0.15
+0.51
+0.10
-0.41
07:00
+0.13
-0.51
+0.34
-0.13
-0.11
-0.36
+0.51
-0.10
-0.17
-0.10
+0.21
+0.15
+0.05
+0.18
+0.84
-0.23
08:00
-0.23
-0.28
+0.38
+0.37
-0.16
-0.21
-0.31
+0.26
+0.13
+0.17
-0.40
+0.12
-0.26
+0.13
+0.22
+0.02
09:00
+0.27
-0.10
+0.37
+0.18
-0.69
+0.08
-0.19
-0.28
-0.19
+0.46
-0.43
+0.42
-0.43
-0.12
-0.02
+0.24
10:00
+0.29
+0.30
+0.21
-0.26
+0.18
+0.04
-0.58
-0.51
-0.34
+0.16
+0.02
+0.27
-0.22
+0.08
+0.17
-0.10
11:00
+0.19
-0.17
+0.05
-0.19
-0.35
+0.35
-0.27
-0.04
+0.18
+0.16
+0.28
-0.08
+0.00
+0.00
-0.75
-0.59
12:00
-0.54
-0.21
+0.17
-0.49
-0.38
+0.50
-0.15
+0.31
-0.23
-0.02
-0.61
-0.20
+0.11
-0.65
+0.14
+0.02
13:00
-0.25
-0.68
+0.03
-0.26
-0.03
+0.12
+0.64
-0.06
-0.28
+0.08
+0.17
+0.53
+0.08
+0.23
+0.55
-0.38
14:00
-0.26
-0.16
-0.25
-0.66
+0.32
-0.04
-0.54
-0.36
+0.41
+0.36
+0.72
+1.18
+0.17
-0.36
-0.86
+0.02
15:00
-0.31
-0.15
-0.46
-0.04
+0.38
-0.18
-0.04
-0.43
-0.82
-0.03
+0.02
+0.69
-0.16
+0.44
-0.21
-0.45
16:00
-0.39
-0.27
+0.50
-0.18
+0.48
-0.53
+0.39
+0.14
-0.69
-0.27
-0.03
+0.21
+0.02
-0.46
-0.59
+0.10
17:00
+0.64
+0.11
+0.39
+0.11
+0.58
+0.15
-0.13
+0.43
+0.14
+0.69
-0.11
-0.49
-1.08
+0.70
+0.77
-0.09
正权重 负权重 色深 = |w| / 1.18

加上 16 个偏置 b₁,隐藏层一共 192 + 16 = 208 个参数。输出层再有 16 个权重加 1 个偏置,总共 225 个。

03

这个样本激活了哪几个神经元

每个神经元先对自己那一列的 12 个权重和输入做加权求和,得到 z₁; 再过 ReLU(修正线性单元,max(0, z₁))得到 h₁。 z₁ 为负的神经元输出被压成 0,等于这个样本上它没有参与决策。

n1静默
z₁-1.367
h₁ = ReLU0.000
n2静默
z₁-1.830
h₁ = ReLU0.000
n3激活
z₁+1.538
h₁ = ReLU1.538
n4静默
z₁-2.415
h₁ = ReLU0.000
n5静默
z₁-0.805
h₁ = ReLU0.000
n6激活
z₁+1.168
h₁ = ReLU1.168
n7静默
z₁-1.352
h₁ = ReLU0.000
n8静默
z₁-1.087
h₁ = ReLU0.000
n9静默
z₁-2.354
h₁ = ReLU0.000
n10激活
z₁+2.213
h₁ = ReLU2.213
n11静默
z₁-1.280
h₁ = ReLU0.000
n12激活
z₁+3.710
h₁ = ReLU3.710
n13静默
z₁-0.432
h₁ = ReLU0.000
n14静默
z₁-1.678
h₁ = ReLU0.000
n15静默
z₁-1.628
h₁ = ReLU0.000
n16静默
z₁-1.305
h₁ = ReLU0.000

16 个神经元里只有 4 个被激活(n3、n6、n10、n12)。 其余 12 个的 z₁ 全为负,被 ReLU 压成了 0。

这就是 ReLU 的稀疏性:同一个样本只走其中一小部分通路,不同样本激活不同的神经元。

04

解剖一个神经元:n10

n10 是这一样本里输出绝对值最大的神经元。它的算法就是「12 个乘积求和,再加偏置」, 和线性模型一模一样——区别只在于最后过了一道 ReLU。

时刻 输入 x 权重 w 乘积 累加
06:00-0.797-0.297+0.237+0.237
07:00+0.050-0.105-0.005+0.231
08:00+1.045+0.175+0.183+0.414
09:00+2.054+0.456+0.937+1.351
10:00+1.297+0.163+0.212+1.563
11:00+1.614+0.163+0.262+1.825
12:00+1.697-0.015-0.026+1.799
13:00+1.553+0.078+0.122+1.921
14:00+1.204+0.358+0.432+2.353
15:00+0.900-0.032-0.029+2.324
16:00+1.108-0.270-0.300+2.024
17:00+0.076+0.688+0.053+2.077
累加和 +2.077
加偏置 b₁ = +0.136 z₁ = +2.213
过 ReLU h₁ = 2.213

09:00(1790 辆/小时)和 17:00(661 辆/小时)对它的贡献较大。 这些权重是训练过程中自己学出来的,没有人指定它应该关注哪个时刻。

05

输出层:把 16 个数合成 1 个

只有激活的神经元有输出,其余是 0。所以实际参与最后的加权的只有这 4 个。

神经元h₁W₂贡献 h₁·W₂
n31.538-0.426-0.656
n61.168+0.412+0.482
n102.213-0.373-0.825
n123.710+0.141+0.522
加偏置 b₂ = -0.1011-0.5786
归一化输出 -0.5786 × σ(570.95) + μ(617.32) = 287 辆/小时

真实值是 242 辆/小时,预测 287, 差 45 辆。

06

ReLU 到底做了什么

同一组 z₁,过 ReLU 前后对比。上半部分是 z₁,下半部分是 h₁:

n1
n2
n3
n4
n5
n6
n7
n8
n9
n10
n11
n12
n13
n14
n15
n16

负值全部归零,正数原样通过。 这一步是整个网络唯一的非线性来源——如果去掉它, 两层矩阵乘法会合并成一个矩阵,模型立刻退化成实验 01 的线性模型。

副作用是「死神经元」:某个神经元如果长期只输出负值, 梯度恒为 0,它就再也学不动了。这个样本里 12 个神经元处于这种状态。

07

实现:这些全部来自 3 行代码

手写版(numpy):

# 前向:12 维 → 16 维 → 1 维
z1 = X @ W1 + b1          # (m, 16)  这张表就是上面那个热力图
h1 = np.maximum(0.0, z1)  # (m, 16)  ReLU
pred = h1 @ W2 + b2       # (m, 1)   合成输出

框架版(PyTorch)等价写法:

self.fc1 = nn.Linear(12, 16)   # 对应 W1, b1
self.act = nn.ReLU()           # 对应 np.maximum(0, z1)
self.fc2 = nn.Linear(16, 1)    # 对应 W2, b2

所以「隐藏层」不是一个抽象概念:它就是一张 12×16 的权重表、一个 16 维偏置向量, 加一道 max(0, ·)。这个样本走完一遍,就是 12×16 = 192 次乘法加 16 次比较。