感知器 — 一组输入 (1, 0, 1) 从头走到尾
这一章讲三件事: 机器学习里最基本的那台机器长什么样(它只有三条线); 「学习」这两个字具体指哪几个动作; 以及「往哪边挪」这个问题是怎么被回答的。
它在全书链条里的位置: 第 19 章说「规则由机器从数据里自己找」。 这一章把「自己找」这四个字拆成能看见的步骤。 而拆到最后你会发现,它用的正是第 01 章那句「把大问题分解成小单元」。 需要的基础: 第 19 章的参数、目标、训练数据。
1. 先看现象:最小的那台机器,只有三条线
机器学习里最基本的一种计算方法,叫感知器1。
它小到可以整个画出来2:
x₁ ─── w₁ ───┐
├──→ [ s ] ──f──→ y
x₂ ─── w₂ ───┤
│
x₃ ─── w₃ ───┘
图说:左边三个 x 是输入,右边的 y 是输出。
三条线上各挂着一个数 w,中间的 s 是它们汇总的结果,
f 是最后那道闸门。全章就是把这张图上的每个字母走一遍。
原书说,你可以 把它当成「根据输入求输出的一种计算方法」, 也可以把它当成电路里的一个电子元件;而书里选择把它称为模型3—— 也就是第 19 章那个「先假设一种关系」的假设本身。
全章的主走查(从这一节到第 8 节,同一组输入走到底)
─────────────────────────────────────────────────────────
输入 (x₁, x₂, x₃) = (1, 0, 1) 权重 (w₁, w₂, w₃) = (0.6, −0.2, 0.5)
§2 加权和 s = 1.1
§4 过闸门 y = 1
§6 给个目标 2.0,算出差多远 → 0.81
§7 看出该往哪挪 → 权重变成 (0.7, −0.2, 0.6)
§7 重算 s = 1.3,差多远降到 0.49
─────────────────────────────────────────────────────────
⚠ 这一组输入、这三个权重、那个目标值、以及挪动的步子,
全部是我们为演示编的,不是真实数值。原书这张图上没有具体的数。
2. 每条线上挂的那个数,叫权重
这一节走主走查的第一、二步。
三条线上各挂一个数,把输入乘上它再全部加起来,得到 s4:
s = w₁x₁ + w₂x₂ + w₃x₃
这个「先各自乘上一个数、再加总」的结果,叫加权和5。
而那三个数 w₁、w₂、w₃ 叫作权重——w 取自英文 weight 的首字母6。
权重是干什么的?它反映对应的那个输入有多要紧7。
- 三个权重都取 1,就是三个输入同等对待、直接相加;
- 某个权重取 0,那个输入在求和时直接被无视8。
代进我们那组数(走查第一、二步):
s = 0.6 × 1 + (−0.2) × 0 + 0.5 × 1
= 0.6 + 0 + 0.5
= 1.1
注意中间那一项:x₂ 是 0,所以不管 w₂ 是 多少,它对 s 都没有贡献。
这一点在第 7 节挪权重时会变得很关键。
s = 1.1。 走查的前两步完成。
这里有一句原书写下的、很值得记住的话:即使是相同的输入,只要权重的值改变, 计算结果也会改变——所以通过调整权重就能对结果加以调整9。 「学习」这件事的全部空间,就在这一句里。
3. 那个式子还有个更短的写法
这一节交代一个你出门一定会撞见的名字。
把那三个权重摆成一排、把输入也摆成一排,按位置对应着相乘,再全部加起来—— 这个运算叫内积(也叫点积)10:
(w₁ w₂ w₃) · (x₁ x₂ x₃) = w₁x₁ + w₂x₂ + w₃x₃
└ 权重那一排 ┘ └ 输入那一排 ┘
图说:两排数,按位置一一配对相乘,再把结果全加起来。
和上一节那个加权和是同一件事,只是写法短了。
为什么要换个写法?因为机器学习里要处理的数实在太多11。 三个还写得下,三千个就没法一个个写了; 用一排数(第 19 章的向量)整体表示,式子才看得清在说什么。
原书用的记法是把两排数各自用一个加粗的字母代表,写成 wx 两个字母12。
4. 最后那道闸门:激活函数
这一节走主走查的第三步。
算出 s 之后还有一步:让 s 过一道闸门,才得到输出 y13:
y = f(s)
这个 f 叫激活函数14。它可以有很多种定义,原书为了说明,采用最简单的一种15:
f(s) = 0 (当 s ≤ 0)
f(s) = 1 (当 s > 0)
不管 s 是多少,输出只可能是 0 或 1 两个值之一。 原书在这里点了一句很好的话:这一步是把连续的值拿进逻辑的世界—— 也就是我们第 02 到 05 章那个真假两分的世界16。
闸门的门槛在 0 这个位置,而这个门槛值叫作阈值17。 「阈」就是门槛的意思:够得着门槛就是 1,够不着就是 0,可以照字面理解18。
代进我们的走查(第三步):s = 1.1,大于 0,所以 y = 1。
输入 (1, 0, 1) → 加权和 1.1 → 过闸门 → 输出 1
图说:走到这里,这台机器已经完整地跑了一遍。
但它还没有「学」到任何东西 —— 权重是我们随手定的。
5. 「学习」是四个动作
这一节走主走查的第四步,把「学习」这个词拆开。
机器学习里的学习,就是通过调整参数,得到与目标尽可能接近的输出19。 对感知器来说,要调的参数就是那三个权重。
原书把这件事拆成四步,一圈一圈重复20:
① 准备好训练数据(每条包括:输入 + 目标)
② 把输入代进模型,得到输出
③ 拿输出和目标比一比
④ 调整参数,让下次的输出更接近目标
↑ │
└────────────────────────────────────┘
图说:第 ③ 步的「比一比」和第 ④ 步的「往哪调」是这一章剩下的全部内容。
我们的走查现在走到第 ③ 步——但要比,得先有个目标。
给它编一个:目标 t = 2.0(这个数是我们为演示编的)。 于是问题变成:输出离 2.0 差多远,以及怎么改才能更近。
顺带一句,原书给的训练数据长这样:(x₁, x₂, t) = (10, 2, 5)——
前两个是输入,最后一个是目标21。格式就是这么朴素。
6. 「差多远」怎么算
这一节走主走查的第五步,而这里有一个必须交代的动作。
先说那个动作:从这一节起,我们把第 4 节那道闸门摘掉。
为什么必须摘? 因为闸门只吐 0 和 1。 输出是 1、目标是 2.0,差 1.0;可你把 w₁ 从 0.6 挪到 0.7,s 从 1.1 变成 1.3, 过完闸门输出还是 1——差多远一点没变。 看不见变化,就不知道该往哪挪。
原书做的正是同一件事:讲到这一步的时候,它明说「简单起见, 设输入只有两个,并且省略掉激活函数的步骤」22。 我们照做,只是保留三个输入,以便同一组数走到底。
接下来是怎么比。原书说得很清楚:对输出的评价不是「好或不好」, 而是要知道它与目标相比「到底有多不好」23。
办法是取差、再平方,有几条数据就全部加起来24:
差多远 = (目标 − 输出)²
为什么要平方?
① 输出比目标大、还是比目标小,都算「偏离」—— 平方之后一律为正;
② 恰好相等时差是 0,平方还是 0。
这个衡量「有多不好」的式子,叫损失函数25; 它的值越大,输出和目标偏离得越厉害;越接近 0,偏离得越小26。
顺带把另一个名字也认了:每一条数据上「目标减输出」的那个差,叫误差—— 原书那个式子的全名就叫「平方和误差函数」。
代进我们的走查(第 五步):
输出 y = 1.1(摘掉闸门,直接用加权和)
目标 t = 2.0
差多远 = (2.0 − 1.1)² = 0.9² = 0.81
0.81。这就是这台机器现在有多差。
7. 「往哪边挪」这个问题怎么答
这一节走主走查的第六、七步,是这一章的核心。
现在知道差 0.81 了,可该把哪个权重往哪边挪?
先看一张图。 因为损失的大小随着权重变化, 所以可以把它想象成一张高低起伏的地形图:横着两个方向是两个权重, 高度是「差多远」。学习的目标就是在这张地形图上找到地势尽可能低的地方27。
差多远(越高越差)
╲ ╱
╲ ╱╲ ╱
╲╱ ╲ ╱
● ╲╱ ← 谷底
你在这儿
───────────────────────→ 权重
图说:人用眼睛一看就知道哪里低,可计算机没有「看一眼」这个能力。
它只能从脚下这一点出发,问一句「往哪边走会更低」。
「在当前这一点上,朝哪个方向走下降最快」——这个方向的名字叫梯度。 (注意:原书从头到尾没有解释过这个词,中文版译者专门加了一条注说明这一点28。)
而「顺着这个方向一小步一小步往下走」的做法,叫梯度下降法29。 原书对它的说明只有一句大白话:无论是在山峰还是在山谷, 只要不断重复从落脚点向低处前进,就一定能到达地势低的位置30。
代进我们的走查(第六步):往哪挪?
s = w₁ × 1 + w₂ × 0 + w₃ × 1 = w₁ + w₃ ← x₂ 是 0,w₂ 根本不参与
现在 s = 1.1,目标 2.0 —— s 偏小,所以 w₁ 和 w₃ 都该往上挪。
w₂ 挪不挪都一样(这一条输入对它没有意见)。
挪多少?我们挑 0.1 这个步子(这个步子是我们编的)。第七步:
权重:(0.6, −0.2, 0.5) → (0.7, −0.2, 0.6)
重算:s = 0.7 × 1 + (−0.2) × 0 + 0.6 × 1 = 1.3
差多远:(2.0 − 1.3)² = 0.7² = 0.49 ← 从 0.81 降到了 0.49
0.81 → 0.49。这一圈的「学习」完成了。
主走查走完了:同一组输入 (1, 0, 1),从加权和 1.1、输出 1, 一路走到「挪完权重之后 s 变成 1.3、差多远降到 0.49」。 再转几圈,s 会越来越靠近 2.0。
8. 步子迈多大,以及会不会卡在小坑里
这一节交代上一节那个「0.1」背后的两个真问题。
第一个问题:步子迈多大。 步子越大,朝目标前进得越快; 但步子太大,说不定有些小山谷就直接跨过去了31。 这个步子的大小,叫学习率32。 原书给的经验是:第一步可以大一些,之后看学习的进展再调整33。
第二个问题:走到不动了,就是最低点吗? 不一定。 原书说的是:如果运气够好,会走到某个地方, 从那儿往哪个方向走损失都不 再减小; 到了那儿,这个模型就可以说是「训练好的模型」了34。
注意「如果运气够好」这半句——它掩着一件事: 你停下的地方可能只是一个小坑,而不是整张地图的最低处。 这种「四周都比这里高、但它并不是全局最低」的地方,行话叫局部最优 (这个名字原书没有给,是我们补的)。
第三,也是这一章的落点:为什么非要这么一小步一小步挪?
因为参数一多,「往这个方向试一下、往那个方向试一下」这种莽撞做法就不行了—— 原书明说:那样会发生第 7 章讲的指数爆炸35。也就是我们第 13 章那件事。
而这一整套做法,原书自己回指了第 1 章: 本书在第 1 章中提到过「将大问题分解为小单元」,这里也是同样的思路—— 并不是要一口气从整个地图中找到最低的地点, 而是从当前的落脚点出发,看往哪个方向走更低36。
这就是第 01 章那句主旨在全书最后一次现身,而且是原书自己点的名。