多层网络与前向传播


多层网络与前向传播

本节摘要:一个神经元只会画一条直线,把它们堆起来,你就能画出任何形状。1969 年 Minsky 与 Papert 证明了单层网络在数学上无法学会异或——这几乎让神经网络资金断流了十年。事后看,解法显而易见:别只用一层。把神经元堆成层,让第一层把输入空间雕刻成新特征,第二层再把这些特征组合成单条直线做不出的决策。这个堆叠就是多层网络,它是当今所有生产级深度学习模型的根基。而前向传播(Forward Pass)——数据从输入流经隐藏层抵达输出——是你让网络动起来之前必须先搭好的第一件事。本节将用纯 Python(不用 numpy)从零实现 Layer 与 Network 类,跑通完整的前向传播,追踪矩阵维度,讲透万能逼近定理,并用一个 2-2-1 网络配合手工调好的 sigmoid 权重破解异或。

学习目标

阅读完本节,你应当能够:

  1. 用纯 Python 从零搭建带 Layer 与 Network 类的多层网络,跑通完整的前向传播。
  2. 追踪矩阵维度流经每一层的过程,并定位形状不匹配的 bug。
  3. 解释堆叠非线性激活如何让网络学到弯曲的决策边界。
  4. 用 2-2-1 架构配合手工调好的 sigmoid 权重破解异或问题。

一、问题与直觉

单个神经元是一台画线机,仅此而已——在你数据上画一条直线。AI 里的一切真实任务——图像识别、语言理解、下围棋——都需要曲线。把神经元堆成层,你才能得到曲线。

1969 年,Minsky 与 Papert 证明了这个限制是致命的:单层网络学不会 XOR。不是「学得很吃力」,而是数学上不可能。XOR 真值表把 [0,1] 与 [1,0] 放一边、[0,0] 与 [1,1] 放另一边,没有任何一条直线能把它们分开。

这砍掉了神经网络十多年的研究经费。事后看,解法太简单:别再用一层。把神经元堆成层,让第一层把输入空间雕刻成新特征,第二层再把这些特征组合成单条直线做不出的决策。

这个堆叠就是多层网络,它是当今所有生产级深度学习模型的根基。前向传播——数据从输入经隐藏层流向输出——是你让其它一切都跑起来之前必须先搭好的第一块。

层:输入层、隐藏层、输出层

多层网络有三类层:

  • 输入层:严格说它不算一层,只是承载你的原始数据。两个特征就是两个输入节点,这里不做任何计算。
  • 隐藏层:真正干活的地方。每个神经元接收上一层全部输出,施加权重和偏置,再过一道激活函数。叫「隐藏」,是因为你在训练数据里永远看不到这些值。
  • 输出层:最终答案。二分类是一个 sigmoid 神经元;多分类是每类一个神经元。

这是一个 2-3-1 网络:两个输入、三个隐藏神经元、一个输出。每条连线带一个权重,每个神经元(除输入外)带一个偏置。

每一层产出一个向量,叫隐藏状态。对文本,隐藏状态会升维——把一个词编码成 768 个数以捕捉语义;对图像,它会降维——把数百万像素压成可控的表示。学习就住在隐藏状态里。

神经元与激活

每个神经元做三件事:

  1. 把每个输入乘上对应的权重;
  2. 把乘积全部求和,加上偏置;
  3. 把和送进激活函数。

本节的激活函数是 sigmoid:

sigmoid(z) = 1 / (1 + e^(-z)) ​

sigmoid 把任意实数压到 (0, 1) 区间:大正数挤向 1,大负数挤向 0,0 落在 0.5。这条光滑曲线正是让学习成为可能的关键——不像感知机的硬阶跃,sigmoid 处处都有梯度。

前向传播:数据怎么流

前向传播把输入数据逐层推过网络,直到输出。前向传播期间不发生任何学习,它是纯计算:乘、加、激活、重复。

每一层按顺序做两件事:

z = W * input + b (线性变换) a = sigmoid(z) (激活) ​

上一层的输出变成下一层的输入。这就是前向传播的全部。

矩阵维度

追踪维度是深度学习里最重要的调试技能。看这个 2-3-1 网络:

步骤 运算 维度 结果形状
输入 x -- (2,)
隐藏层线性 W1 * x + b1 W1: (3, 2), b1: (3,) (3,)
隐藏层激活 sigmoid(z1) -- (3,)
输出层线性 W2 * h + b2 W2: (1, 3), b2: (1,) (1,)
输出层激活 sigmoid(z2) -- (1,)

规则:第 k 层的权重矩阵 W 形状是(第 k 层神经元数, 第 k−1 层神经元数)。行对应当前层,列对应上一层。形状对不上,就是有 bug。

万能逼近定理

1989 年,George Cybenko 证明了一件惊人的事:只要隐藏神经元足够多,单隐藏层网络就能以任意精度逼近任意连续函数。

但这不代表单隐藏层永远最优——它只说明架构理论上可行。实践中,更深网络(更多层、每层更少神经元)用远少于「浅而宽」网络的总参数量,就能学会同样的函数。这正是深度学习行得通的原因。

直觉:隐藏层里每个神经元学会一个「凸起」或一种特征,把足够多的凸起摆在合适位置,就能逼近任何光滑曲线。神经元越多,凸起越多,逼近越好。

可组合性

神经网络是可组合的——你可以堆叠、串联、并行。Whisper 模型用一个编码网络处理音频、另一个解码网络生成文本;现代 LLM 多为 decoder-only;BERT 是 encoder-only;T5 是 encoder-decoder。架构选型决定了模型能做什么。

二、从零实现

纯 Python,不用 numpy,所有矩阵运算都从零写。完整代码见原课程 phases/03-deep-learning-core/02-multi-layer-networks/code/ 相应文件。

Step 1:sigmoid 激活

import math def sigmoid(x): x = max(-500.0, min(500.0, x)) return 1.0 / (1.0 + math.exp(-x)) ​

那个截断到 [-500, 500] 是为了防止溢出:math.exp(500) 很大但有限,math.exp(1000) 就是无穷了。

Step 2:Layer 类

深度学习里最重要的运算就是矩阵乘法。每一层、每个注意力头、每一次前向传播——底层都是 matmul。线性层接收输入向量,乘以权重矩阵,加上偏置向量:y = Wx + b。神经网络里 90% 的计算量就是这一个公式。

层持有一个权重矩阵和一个偏置向量,其 forward 方法接收输入向量、返回激活后的输出。权重矩阵形状是 (n_neurons, n_inputs):每一行是一个神经元跨全部输入的权重。forward 遍历神经元,算加权求和加偏置,套 sigmoid,收集结果。

Step 3:Network 类

网络就是一列层。前向传播把它们串起来:第 k 层输出喂进第 k+1 层。逻辑就四行:数据进去,逐层流过,从另一头出来。

Step 4:用手工权重解 XOR

在第 01 节里我们用 OR、NAND、AND 感知机组成了 XOR。现在用我们的 Layer 与 Network 类做同样的事,采用 2-2-1 架构:两个输入、两个隐藏神经元、一个输出。

隐藏层权重设成 [[20, 20], [-20, -20]]、偏置 [-10, 30],输出层权重 [[20, 20]]、偏置 [-30]。这些大权重(20、-20)让 sigmoid 表现得近乎阶跃函数:第一个隐藏神经元近似 OR,第二个近似 NAND,输出神经元把它们合成 AND,也就是 XOR。

Step 5:圆形分类

再上一个更难的任务:判定二维点是否落在以原点为圆心、半径 0.5 的圆内。这需要弯曲的决策边界——单个感知机无能为力。生成 200 个点,搭一个 2-8-1 网络,跑前向传播。

用随机权重,网络几乎判不准。但前向传播照样跑得通——这就是要点:前向传播只是计算,学会正确的权重是第 03 节反向传播的事。

三、框架对比

PyTorch 四行就能把上面的事做完:

import torch import torch.nn as nn model = nn.Sequential( nn.Linear(2, 8), nn.Sigmoid(), nn.Linear(8, 1), nn.Sigmoid(), ) x = torch.tensor([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]) output = model(x) print(output) ​

nn.Linear(2, 8) 就是你的 Layer 类:权重矩阵形状 (8, 2)、偏置向量形状 (8,)。nn.Sigmoid() 是你逐元素的 sigmoid。nn.Sequential 就是你的 Network 类:按顺序串层。

差距在速度与规模:PyTorch 跑在 GPU 上、处理百万级样本的 batch、自动算反向传播的梯度。但前向传播的逻辑和你从零写的完全一致。

四、可复用产物

本节产出(位于原课程 outputs/):

  • prompt-network-architect.md:一个可复用提示,在你需要决定「该用几层、每层几个神经元、用哪种激活函数」时给出建议。

五、练习

  1. Easy:搭一个 2-4-2-1 网络(两层隐藏),在 XOR 数据上用随机权重跑前向传播,打印中间隐藏层输出,观察每一层的表示如何变化。
  2. Medium:把圆形分类器的隐藏层从 8 改成 2、再改成 32,各用随机权重跑前向传播。隐藏神经元数量会改变输出的范围或分布吗?为什么?
  3. Hard:在 Network 类上实现一个 count_parameters 方法,返回可训练权重和偏置的总数。在 784-256-128-10 网络(经典 MNIST 架构)上测试,它有多少参数?

本节要点回顾

  1. 单层感知机只会画直线:堆叠神经元成多层,才能画出弯曲的决策边界,这是当今所有深度学习模型的根基。
  2. 三类层各司其职:输入层只装数据,隐藏层真正提炼特征,输出层给出最终答案。
  3. 前向传播是纯计算:乘权重、加偏置、激活、重复,期间不发生任何学习。
  4. 维度追踪是头号调试技能:第 k 层权重矩阵形状为 (本层神经元数, 上层神经元数),行对应当前层、列对应上一层。
  5. sigmoid 是光滑的:处处有梯度,正是它让学习成为可能(对比感知机的硬阶跃)。
  6. 万能逼近定理:单隐藏层 + 足够神经元理论上可逼近任意连续函数,但更深网络用更少参数达到同样效果。
  7. 神经网络可组合:可堆叠、串联、并行,架构选型(encoder-only / decoder-only / encoder-decoder)决定模型能力。

下一节,我们正式推导反向传播——前向传播把数据推过去,反向传播把梯度推回来,亲手实现一遍,你就真正懂了「学习」在做什么。

作者与出处
原作者:Rohit Gupta
来源:rohitg00
许可证:MIT
整理人: 灏天文库整理
由灏天文库结构化整理,提供目录导航、全文检索与在线阅读,便于系统化学习
发布者: 作者: Rohit Gupta 转发
评论区 (0)
U