第7章 神经网络热身

前六章,你把地基一块块铺好了:数字(线性代数)、变化(微积分)、可能性(概率)、学习的方法(优化)、动手的代码(Python),还有机器学习的世界观(第 6 章)。现在,是时候把零件拼成一台真正的"智能机器"了 - 神经网络。别被名字吓到:它骨子里就是"加权求和加开关",再配上一个让错误倒着流的魔法。这一章我们不推公式、不手算,只讲直觉、看图画、敲一小段代码。读完你会发现:你早就准备好了。

7.1 神经元:加权求和加开关

先回忆第 1 章做过的矩阵乘法:它的每一行,其实就是"把输入里的每个数字,分别乘上一个权重,再加起来"。这个动作太重要了,所以神经网络把它做成了最基础的零件 - 神经元(neuron)。一个神经元只干两件事:第一,加权求和;第二,过开关

怎么理解"权重"?假设你要判断"今天要不要带伞"。你心里其实有一张评分表:天气阴沉,重要程度 0.6;湿度,0.3;出门时间长短,0.1。每个因素先乘上自己的重要程度(这就是权重 w),全部加起来,得到一个"带伞分",最后过一个开关:分数够高就"带",不够就"不带"。神经元的计算一模一样:每个输入 x 乘上对应的权重 w,求和,再加上一个偏置 b(相当于开关的门槛),最后丢进激活函数 f(就是那个开关),得到输出 y。

你也可以把它想成传话游戏:上一个人说的一句话(输入),你按自己重视的程度打个折(乘权重),汇总完再决定要不要继续往下传(过开关)。一个人传话没意思,几亿个神经元连成网络,就能认出你的脸、听懂你的话 - 后面几节会看到它们怎么连。

\[ y=f\!\left(\sum_i w_i x_i+b\right) \]

别怕这个式子:Σ 的意思是"把后面这一串全部加起来";wᵢxᵢ 是"第 i 个输入乘上它的权重";偏置 b 是开关的"初始灵敏度" - b 大,神经元容易被激活;b 小,就挑剔一些。一句话:权重管"这个输入重不重要",偏置管"门槛高不高"

重要

记住这个零件
神经元 = 加权求和 + 开关。权重 w:每个输入有多重要;偏置 b:开关的门槛;激活 f:放行还是拦截。整个神经网络,就是无数个这样的零件连在一起。

图 7-1 单个神经元的结构:输入先乘权重求和,再过激活开关,得到输出

7.2 激活函数:给网络”活性”

上一节神经元里有个"开关" - 它的正式名字叫激活函数(activation function)。没有它行不行?试试看:把开关全拆掉,网络就只剩"加权求和"。而一堆加权求和叠在一起,算来算去结果还是加权求和 - 就像把许多直线首尾相接,得到的仍然是一条直线。没有激活函数,叠多少层都等于一层,网络就白叠了。激活函数,正是给网络注入"活性"的那个东西。

最早登场的明星叫 sigmoid。它把任意一个数压到 0 到 1 之间,画出来是一条平滑的 S 形曲线(图 7-2 左)。它像一个"可微的水龙头":不是啪的一下开或关,而是从"基本关着"平滑地拧到"完全打开"。因为输出永远在 0~1 之间、看起来很像概率,早期神经网络几乎都用它。

今天的绝对主角是 ReLU,全名"修正线性单元"。它的规则简单到离谱:输入是正数,原样输出;输入是负数,一律归零图 7-2 右)。它像一个"只放行好消息的门卫":负能量直接拦下,正能量放行。它算得快、表现稳,所以今天从手机上的小模型到 ChatGPT 背后的大模型,几乎全用它。

那 sigmoid 去哪儿了?它有个小毛病:曲线两头变得很平,梯度"卡"在那里,网络学得慢;ReLU 在正半轴上斜率永远是 1,信号传得又直又快。这条直觉先记住,背后的原因等你读到主书第 1 章 1.4 节、结合梯度下降就全明白了。

注记

别小看"归零"
ReLU 把大量神经元的输出打成 0,让网络变得"稀疏",反而更容易学出干净、有用的特征。看似"丢信息",其实是"做减法" - 这正是它好用的小秘密。

图 7-2 sigmoid 把任意数压到 0~1(平滑开关);ReLU 把负数归零、正数放行(门卫)

7.3 前向传播:数据流过网络

零件齐了,现在把神经元连成网络,让数据从一头流到另一头。这个过程叫前向传播(forward propagation):"前向"指从输入到输出,"传播"指数据一路流过去。

想象一个快递分拣中心:包裹(数据)从收件口进来,经过一个个分拣站(层),每个分拣站按自己的规则处理(加权求和、过开关),最后送到对应的出口(输出)。包裹从进门到出门只往前走、从不回头 - 这就是一次前向传播。神经网络做一次预测,就是做一次前向传播。

来看一个具体的微型网络(图 7-3)。输入层有两个数字:x₁=0.5、x₂=−1。它们分别乘上箭头上的权重,送到中间层:第一个中间神经元算出 0.5×1.0+(−1)×(−0.5)+0.1=1.1,过 ReLU - 正数,放行,还是 1.1;第二个算出 0.5×(−0.8)+(−1)×0.6+0.2=−0.8,过 ReLU - 负数,直接归零。最后输出层把 1.1 和 0 按权重加起来:0.6×1.1+0.4×0=0.66。这一次预测的答案就是 0.66。

注意 ReLU 那一刀:−0.8 变成 0,这个神经元对结果"贡献为零",后面的计算直接跳过它。前向传播,就是一个数字接一个数字、一层接一层算过去的过程。

如果把网络画出来,前向传播就是一条单行道:数据只能从输入流向输出,中间的每一层都只跟自己的前一层、后一层打交道 - 你不需要记住整条路,只需要一层一层接力。这也是它叫"前向"的原因:永远往前走,从不回头。

你可能会问:这些权重都是随便定的,凭什么准?问得好 - 一开始确实不准。而"不准"这件事,正是下一节故事的起点。

图 7-3 前向传播数值小例子:数字从输入层一路算到输出层,节点下方是每层算出的值

注记

前向传播只是一次"按当前权重的预测"
它又快又便宜,真正麻烦的是"怎么把权重改好"。别急,答案就在 7.4 节

7.4 反向传播:错误倒着流

前向传播算出预测,和标准答案一比,发现差了 - 这个"差多少"叫损失(loss),第 4 章你已经见过。问题是:怎么让损失变小?也就是,怎么改这些权重?

直觉答案是:让错误"倒着流回去"。想象一场考试:你算出答案 0.7,标准答案是 0.9,差了 0.2。这 0.2 不是凭空冒出来的,它是网络中一层一层计算累积出来的。就像批完卷子要追溯"为什么错":哪个神经元在计算里出力多(贡献大),谁就多承担一点责任、多改一点权重;出力少的,少改。从输出层开始,把误差按"贡献比例"一层一层往输入方向分摊回去 - 这就是反向传播(backpropagation,简称 BP)

打个比方:你是乐队指挥,演出结束观众反应平平。你顺着乐谱往回捋 - 这段主奏是谁?把它的音量调一调;那段和声是谁垫底?稍微动一点。每个人按责任大小调整,下一场自然更接近理想效果(完整版见下方类比卡)。

所以反向传播只有两步:第一,把误差从输出往输入"倒着流",沿途按贡献分摊;第二,每经过一个神经元,顺手更新它的权重 - "你出力大,就多改你一点"。至于"改多少",第 4 章学过:梯度下降。反向传播算出的,正是每个权重该迈的那一步(梯度),梯度下降负责照单执行。

最关键的一句话:你不需要会手算!在 PyTorch 里,一句 loss.backward() 就替你把所有分摊和梯度算好了。你要做的,是理解"它在把错误倒着分摊回去"这个直觉 - 剩下的事交给框架,下一节就动手。

提示

类比:像乐队指挥调整音量
演出结束,观众反应平平(误差)。这不是某个乐手一个人的错,而是整支乐队合出来的结果。指挥顺着乐谱往回看:这段主奏是第二小提琴?把它的音量调大一点;那段和声有点抢戏?稍微收一收。每个人按"责任大小"调整,下一场自然更接近理想效果。反向传播干的就是这件事:谁贡献大,谁就多改。

图 7-4 反向传播:误差(红色虚线)从输出倒着流向输入,沿途按贡献分摊并更新权重

7.5 用 PyTorch 写一个数字识别

纸上谈兵够了,来写真的。这一节我们用 PyTorch 训练一个手写数字识别:给它看一张 28×28 像素的手写数字图片,它告诉你这是 0~9 里的哪个。这个任务叫 MNIST,是深度学习界的"hello world",几乎所有框架的教程都从它开始。

代码一共 25 行左右(下面是完整代码,建议照着敲一遍 - 第 5 章已经教会你 Python 了):

import torch
import torch.nn as nn
from torchvision import datasets, transforms

# ① 数据:把 28×28 的图片拉平成 784 个数字,打包成小批量
train = datasets.MNIST('./data', train=True, download=True,
                  transform=transforms.ToTensor())
loader = torch.utils.data.DataLoader(train, batch_size=64, shuffle=True)

# ② 模型:784 个输入 → 128 个神经元 → 10 个输出(0~9 各一个分数)
model = nn.Sequential(
  nn.Linear(784, 128),  # 加权求和 + 偏置(7.1 节)
  nn.ReLU(),            # 开关:负数归零(7.2 节)
  nn.Linear(128, 10),  # 再求和一次,得到 10 个分数
)
loss_fn = nn.CrossEntropyLoss()             # 考卷:预测和答案差多少
optim = torch.optim.Adam(model.parameters())  # 下山脚步(第 4 章)

# ③ 训练循环:前向 → 算损失 → 反向 → 更新,循环几千次
for images, labels in loader:
  pred = model(images.view(-1, 784))  # 前向:算一次预测
  loss = loss_fn(pred, labels)        # 算损失:这次差多少
  loss.backward()                # 反向:错误倒着流,算出每个权重该改多少
  optim.step()                 # 更新:照梯度迈一步
  optim.zero_grad()              # 清空记录,准备下一批

拆开看,代码就三块:数据(把 28×28 的图片拉平成 784 个数字,打包成小批量)、模型(784 个输入 → 128 个神经元 → 10 个输出)、训练循环。模型那三行,就是 7.1、7.2 节的东西:Linear 是"加权求和 + 偏置",ReLU 是"开关"。loss_fn 是"考卷",optim 是第 4 章的"下山脚步"(Adam 就是带惯性的梯度下降)。

细心的你可能发现了:代码里没有一句"怎么手算梯度"。因为 PyTorch 的每一个算子(Linear、ReLU)都知道自己怎么求导,loss.backward() 会顺着计算图把误差一路倒着传回去 - 这正是 7.4 节那个直觉的工程实现。你要做的只是定义模型、选好"考卷"和"下山方法",然后循环。

最核心的是训练循环那四行 - 也是全章最重要的四行,见表 7-1。而且每一步都有你的"老朋友":前向是你算过的矩阵乘法,反向是第 2 章的链式法则,更新是第 4 章的梯度下降 - 知识真的串起来了。

步骤 代码 在干什么
① 前向 pred = model(x) 数据流一遍,算一次预测
② 算损失 loss = loss_fn(pred, y) 考卷打分:预测和答案差多少
③ 反向 loss.backward() 错误倒着流,算出每个权重该改多少
④ 更新 optim.step() 照梯度迈一步,更新所有权重

这四步循环几千上万次,损失一路下降,网络就越来越准 - 你在第 4 章见过的"损失下降曲线",就是这四步一遍遍跑出来的。

重要

看懂这个循环,就看懂了所有深度学习
训练的本质永远是四步:前向 → 算损失 → 反向 → 更新。以后不管遇到 CNN、RNN、Transformer 还是大模型,变的只是"模型长什么样、数据怎么喂",循环本身不变。

7.6 通往《人工智能理论与实践》的桥

现在回头看看你手里有什么:神经元(加权求和加开关)、激活函数(给网络活性)、前向传播(数据流过网络)、反向传播(错误倒着流),还有一个真能跑起来识别手写数字的小程序。这些,正是《人工智能理论与实践》第 1 章"BP 神经网络"的全部骨架 - 主书第 1 章的地基,你自己已经搭好了

先看这张对照表(表 7-2),读主书时遇到卡壳,就回来翻本章对应的图和类比:

本章内容 主书《人工智能理论与实践》对应 读主书时你会见到
7.1 神经元:加权求和加开关 第 1 章 1.2 / 1.3 节 感知机的数学定义、网络结 构图
7.2 激活函数:给网络"活性" 第 1 章 1.4 节 sigmoid / tanh / ReLU 的 性质与选择
7.3 前向传播:数据流过网络 第 1 章 1.5 节 前向传播与损失函数
7.4 反向传播:错误倒着流 第 1 章 1.5 节 链式法则、用梯度下降更新 权重的完整推导

图 7-5 通往主书的桥:本章每一节,都对应主书第 1 章的一站

主书第 1 章会把今天"只讲直觉"的东西补上公式和严谨推导:感知机怎么收敛、损失函数怎么选、链式法则怎么一步步把梯度算出来。别怕 - 有了本章的直觉打底,那些公式只是给直觉"盖章"。你读主书时会发现,每一处推导都能对回本章的一幅图。换句话说:主书负责"严谨",本书负责"先懂",两本书合起来读,就是完整的入门路径。

这一章也补上了最后一块拼图:从第 1 章的数字,到第 4 章的优化,再到第 7 章的神经网络,"AI 怎么学会"这件事你已经完整走了一遍。剩下的事情只有一件:动手。把 7.5 节的代码跑起来,再翻开主书第 1 章 - 你会发现,自己读得比想象中顺利得多。

最后记住一个心态:读主书时遇到不懂的公式,先别硬啃,回到本章对应的图和类比里缓一缓,再回去读,通常就通了。第 8 章还会给你一张完整的 12 周学习计划,把今天的热身放进整个学习地图里。

重要

本章要点

  • 神经元 = 加权求和 + 开关:y = f(Σ wᵢxᵢ + b)。权重管"重要性",偏置管"门槛"。
  • 激活函数给网络"活性":sigmoid 是 0~1 的平滑开关;ReLU 负数归零、正数放行。没有激活函数,多层叠加等于一层
  • 前向传播:数据从输入流到输出,只往前走;一次预测 = 一次前向传播。
  • 反向传播:误差从输出倒着流,按贡献比例分摊并更新权重。你不需要会手算,一句 loss.backward() 搞定。
  • 训练循环四步:前向 → 算损失 → 反向 → 更新。看懂它,就看懂所有深度学习。
  • 本章 = 主书第 1 章 BP 神经网络的完美前置:7.1→1.2/1.3、7.2→1.4、7.3 与 7.4→1.5。
警告

衔接 · 下一站

  • 读主书前,先回来把四张图看一遍:图 7-1(神经元)、图 7-2(激活函数)、图 7-3(前向传播)、图 7-4(反向传播)。带着这四张图翻开《人工智能理论与实践》第 1 章,你会发现公式都有了画面。
  • 本章用到的旧知识:第 1 章矩阵乘法(7.1 的求和)、第 2 章链式法则(7.4 的"分摊"在数学上就是它)、第 4 章梯度下降(7.4 的"更新")、第 5 章 Python(7.5 的代码)。卡住了就回对应章节。
  • 下一站:第 8 章系统学习路线 - 把这本书学到的连成一张 12 周计划,然后正式翻开《人工智能理论与实践》第 1 章