3.0 引言
📌 上章回顾
上一章我们学习了感知机。关于感知机,有好消息,也有坏消息。
✅ 好消息:
即便是复杂的计算任务,感知机理论上也可以表示出来。
只要结构足够深、组合足够巧,它甚至能模拟出一个完整的计算机。
我们看到它能构造:
- 逻辑门(AND、OR、NAND)
- 加法器
- 非线性函数(比如 XOR)
这说明感知机拥有极强的表示能力。
❌ 坏消息:
虽然感知机“能表示”,但目前是靠人工设定权重来实现的。
上一章中我们是参考真值表,“拍脑袋”选出了合适的参数:
w = [0.5, 0.5]
b = -0.7
这种方式在实际问题中是不可行的,尤其是面对图像、语音这种高维复杂输入时,参数数以千计,我们没法一一设置。
🤖 神经网络的意义:
神经网络的关键优势是:可以从数据中自动学习出合适的权重参数。
这解决了感知机的最大痛点。
📌 本章我们将关注神经网络在“推理阶段”的工作流程,即:
输入层 → 隐藏层 → 输出层 的信号传递
使用激活函数进行非线性变换
📌 而在下一章,我们将开始学习神经网络的训练过程:
如何从数据中学习
误差反向传播算法(backpropagation)。
3.1 从感知机到神经网络
神经网络和上一章介绍的感知机有很多共同点。这里,我们主要以两者的差异为中心,来介绍神经网络的结构。
3.1.1 神经网络的例子
用图来表示神经网络的话,如图3-1所示。
我们把最左边的一列称为输入层,最右边的一列称为输出层,中间的一列称为中间层。中间层有时也称隐藏层。“隐藏”一词的意思是,隐藏层的神经元(和输入层、输出层不同)肉眼看不见。另外,本书中把输入层到输出层依次称为第0层、第1层、第2层(层号之所以从0开始,是为了方便后面基于Python进行实现)。
图3-1中,第0层对应输入层,第1层对应中间层,第2层对应输出层。
只看图3-1的话,神经网络的形状类似上一章的感知机。实际上,就神经元的连接方式而言,与上一章的感知机并没有任何差异。那么,神经网络中信号是如何传递的呢?
3.1.2 复习感知机
在了解神经网络中的信号传递方式之前,我们先来复习一下感知机的工作原理。
它接收两个输入信号 x 1 x_1 x1 和 x 2 x_2 x2,通过对应的权重 w 1 w_1 w1 和 w 2 w_2 w2 进行加权,然后输出一个值 y y y。
🧮 数学表示(公式 3.1)
y = { 1 ( w 1 x 1 + w 2 x 2 + b > 0 ) 0 otherwise y = \begin{cases} 1 & (w_1 x_1 + w_2 x_2 + b > 0) \\\\ 0 & \text{otherwise} \end{cases} y=⎩ ⎨ ⎧10(w1x1+w2x2+b>0)otherwise
这里的:
- w 1 , w 2 w_1, w_2 w1,w2 是权重,控制每个输入的重要性;
- b b b 是偏置项(bias),控制“激活的容易程度”。
❓偏置是怎么处理的?
在上图中偏置 b b b 没有显式画出,但其实它就像一个特殊输入,值始终为 1。
我们可以把偏置理解为一个“阈值调节器”:
- 它始终参与计算;
- 但不会随输入数据变化。
🎨 如果画出完整的结构图(图3-3),就是这样:
图中将偏置的输入神经元涂成灰色,以示区别。
✅ 更加简洁的数学形式(公式 3.2)
为了简洁,我们引入一个函数 h ( x ) h(x) h(x):
y = h ( w 1 x 1 + w 2 x 2 + b ) y = h(w_1 x_1 + w_2 x_2 + b) y=h(w1x1+w2x2+b)
这个函数 h ( x ) h(x) h(x) 被称为激活函数(activation function)。
🚀 定义激活函数 h(x)(公式 3.3)
最常见的激活函数是阶跃函数:
h ( x ) = { 1 ( x > 0 ) 0 otherwise h(x) = \begin{cases} 1 & (x > 0) \\\\ 0 & \text{otherwise} \end{cases} h(x)=⎩ ⎨ ⎧10(x>0)otherwise
也就是说,如果加权求和的结果大于 0,就输出 1;否则输出 0。
📌 小结
项目 | 说明 |
---|---|
输入 x i x_i xi | 外部信号,比如像素值或传感器数据 |
权重 w i w_i wi | 表示输入信号的重要性 |
偏置 b b b | 控制“激活的门槛”,始终与输入1相乘加入 |
h ( x ) h(x) h(x) | 激活函数,决定输出是否“点亮” |
输出 y y y | 感知机的判断结果,0或1 |
通过这种结构,感知机就能模拟出逻辑门、进行分类决策,是神经网络的原始雏形。
3.1.3 激活函数登场
刚才登场的 h ( x ) h(x) h(x)函数会将输入信号的总和转换为输出信号,这种函数一般称为激活函数(activation function)。如“激活”一词所示,激活函数的作用在于决定如何来激活输入信号的总和。
💡 激活函数的作用
就像“激活”这个词本身所表达的意思,激活函数的目的是:
决定神经元是否被“激活”,即是否向下传递信号。
它是整个神经网络中非线性处理的核心。
🧮 更详细的公式分解
之前我们写过感知机的简洁形式:
y = h ( w 1 x 1 + w 2 x 2 + b ) (公式 3.2) y = h(w_1 x_1 + w_2 x_2 + b) \quad \text{(公式 3.2)} y=h(w1x1+w2x2+b)(公式 3.2)
其实它可以拆分成两个步骤:
-
第一步:求加权和
a = w 1 x 1 + w 2 x 2 + b (公式 3.4) a = w_1 x_1 + w_2 x_2 + b \quad \text{(公式 3.4)} a=w1x1+w2x2+b(公式 3.4) -
第二步:用激活函数处理 a a a
y = h ( a ) (公式 3.5) y = h(a) \quad \text{(公式 3.5)} y=h(a)(公式 3.5)
这就像把信号先“合成”,再“判断是否激活”。
🧠 神经元内部结构图解(图 3-4)
通常我们会用一个圆圈 ○ 表示一个神经元。现在,我们在这个神经元内部加上细节,如下所示:
图示结构说明:
- x 1 , x 2 x_1, x_2 x1,x2:输入信号
- w 1 , w 2 w_1, w_2 w1,w2:权重
- b b b:偏置
- a a a:节点加权和
- h ( a ) h(a) h(a):激活函数处理后输出 y y y
在一些图中,a、h()、y 会在神经元内部显式表示,帮助我们更清晰理解运算流程。
🧠 “节点” vs “神经元”
- 本书中,“节点”和“神经元”是可以互换使用的。
- 节点表示神经网络图中的一个计算单元,和“神经元”含义相同。
📘 图示演变(图 3-5)
我们常用两种方式画神经元结构图:
普通画法(简洁) | 详细画法(显式显示计算过程) |
---|---|
一个圆圈代表一个神经元 | 圆圈内写上 a → h(a) → y |
这种表示方式会在后续神经网络结构图中频繁使用,有助于理解前向传播(forward)和误差传播(backpropagation)。
📌 感知机 与 神经网络 的连接点:激活函数
激活函数是连接“感知机”和“神经网络”的桥梁。
模型类型 | 特点 |
---|---|
朴素感知机 | 使用阶跃函数作为激活函数,结构较简单 |
多层感知机(MLP) | 使用sigmoid、ReLU等平滑函数,可构成深层网络 |
激活函数的不同,决定了模型能力的差异,也是感知机升级为神经网络的关键一步。
下一节,我们就将系统地介绍各种常见的激活函数,包括:
- sigmoid
- ReLU
- 阶跃函数
- softmax(输出层用)
让我们正式进入神经网络的非线性世界!🌐
3.2 激活函数
在上一节我们提到,感知机的激活函数是“阶跃函数” —— 输入超过某个阈值时就输出 1,否则输出 0。
感知机使用的是这种非常简单的激活方式,但神经网络的强大之处,恰恰来自于“选择不同的激活函数”。
3.2.1 sigmoid函数
神经网络中最早被广泛使用的激活函数就是 sigmoid 函数,数学表达式如下:
σ ( x ) = 1 1 + e − x (公式 3.6) \sigma(x) = \frac{1}{1 + e^{-x}}\quad \text{(公式 3.6)} σ(x)=1+e−x1(公式 3.6)
sigmoid 函数可以把任意实数输入“压缩”到 0 到 1 的区间内。
实际上,上一章介绍的感知机和接下来要介绍的神经网络的主要区别就在于这个激活函数。
其他方面,比如神经元的多层连接的构造、信号的传递方法等,基本上和感知机是一样的。下面,让我们通过和阶跃函数的比较来详细学习作为激活函数的sigmoid函数。
3.2.2 阶跃函数的实现
感知机使用的阶跃函数如下:
h ( x ) = { 1 if x > 0