你每天都在使用机器学习,只是可能不知道。
手机输入法在你打完「今天天气」之后建议「不错」——它从数十亿条真实对话中学到了这个搭配。购物网站把你可能想买的东西排在前面——它从你和其他人的浏览记录中学到了偏好。邮箱把广告邮件自动丢进垃圾箱——它从几百万封被标记过的邮件中学到了什么是垃圾邮件。
这些功能背后都是同一个思路:不告诉机器规则是什么,而是给它看大量的数据,让它自己从数据里学出规则。这个思路叫做机器学习。
传统程序是怎样的
在机器学习出现之前,程序的逻辑全部由人来写。
你可能没有写过程序,但你一定见过这种逻辑:温度计应用显示当前温度,如果低于零度就提示「注意结冰」。这里面的规则——零度是分界线——是人定的,程序只负责照做。
再比如一个计算器:输入两个数和一个运算符,程序按照加减乘除的规则算出结果。规则由人写,清晰、确定、不会出错。
这种方式在规则清晰的时候非常好用,但它有一个根本的局限:有些问题的规则写不出来。
写不出来的规则
给你一张照片,你一眼就能分辨里面是猫还是狗。但如果让你写一套规则来做同样的判断,你会发现无从下手:
- 「如果有尖耳朵就是猫」——可很多猫是折耳的,很多狗的耳朵也是竖的。
- 「如果体型小就是猫」——那大猫怎么办?小型犬怎么办?
- 「如果瞳孔是竖的就是猫」——照片里不一定看得到瞳孔。
每一条规则都有例外,例外的例外还有例外。你能认出猫和狗,但你无法把自己判断的过程写成一套明确的规则交给机器。
语言也是这样。「他在银行工作」和「河岸两边的银行」——同样的「银行」在两句话里意思完全不同。要让机器理解这种区别,不可能靠人手写规则穷举所有情况。
机器学习的思路
机器学习换了一个方向。你不告诉机器「什么是猫」,而是给它看一万张标好了「猫」或「狗」的照片,让它自己找出两者的区别。你不告诉机器「银行在这句话里是什么意思」,而是给它看几十亿句真实的话,让它自己学会根据上下文理解词义。
机器不需要你告诉它规则。它从数据中提取规则。
这个思路需要三样东西:
第一样:数据
数据是机器从中学习的原料。
识别猫狗需要大量标注好的照片——每张照片都要有人标上「这是猫」或「这是狗」。翻译需要大量中英对照的句子。语音识别需要大量录音和对应的文字。
Sophia 的训练数据是 200 亿个 token 的文本——token 是文本的最小片段,后面的章节会详细解释。这些文本来自百科全书、书籍、论文、网页、代码等等。
有一条你会在整门课中反复遇到的铁律:数据的质量和数量划定了机器能学到什么。 再精妙的模型、再高级的训练方法,也学不出数据里没有的东西。如果训练数据全是英文,模型就不会说中文;如果训练数据里没有数学,模型就不会做数学。Sophia 的训练数据里中文占了 56.5%,这是一个刻意的选择——因为她被设计为一个以中文对话为核心的模型。
第二样:模型
模型是一台旋钮极多的机器。
想象一台有十个旋钮的机器。你给它输入一张照片,它输出一个判断——「猫」或「狗」。旋钮的位置不同,判断就不同。某个旋钮的组合让它把所有照片都判断为「猫」,另一个组合让它随机猜,而某个特定的组合让它能够准确地区分猫和狗。
训练开始之前,所有旋钮都是随机拨的。机器对任何输入的反应都是随机噪声——不比抛硬币好多少。
Sophia 有多少个旋钮?十亿零一千两百六十三万零四百八十个。 准确地说是 1,012,630,480 个。每一个旋钮都是一个数字,叫做「参数」。训练的目标就是找到这十亿个数字的正确组合。
第三样:学习算法
学习算法是调旋钮的方法。
它做的事情可以用三步概括:
- 把一条数据喂给机器,看它的输出。
- 拿输出和正确答案做比较,计算差多远。
- 微微转动旋钮,让输出离正确答案近一点。
然后换下一条数据,再来一遍。
这三步看似简单,但重复几十亿次之后,效果是惊人的。一开始全是随机噪声的十亿个旋钮,最终会收敛到一组有意义的值——机器「学会」了数据中的规律。
用一个例子亲手感受
下面是一个最简化的例子。假设你有四套房子的面积和售价:
面积(平方米)→ 价格(万元)
60 → 180
80 → 240
100 → 300
120 → 360
你一眼就能看出:价格 = 面积 × 3。但机器不知道这个关系,它需要从数据中学。
我们的模型极其简单:价格 = w × 面积,其中 w 是唯一的旋钮。一开始 w 是一个随机数,我们要让它慢慢靠近 3。
下面这段代码用 Python 实现了这个过程。Python 是一种编程语言——如果你从来没见过代码,不要跳过,每一行后面都有解释:
import random # 引入一个工具包,用来生成随机数
# 数据:四套房子的(面积, 价格)
data = [(60, 180), (80, 240), (100, 300), (120, 360)]
# 模型只有一个旋钮 w,一开始随机设一个值
w = random.random() # random() 生成一个 0 到 1 之间的随机小数
print(f"训练前:w = {w:.4f}") # 打印出初始的 w
# 学习:重复 100 轮
for epoch in range(100): # range(100) 的意思是"从 0 到 99 循环"
for area, true_price in data: # 每一轮,逐条取出四套房的数据
predicted = w * area # 用当前的 w 计算预测价格
error = predicted - true_price # 预测价格 - 真实价格 = 误差
w = w - 0.00001 * error * area # 根据误差微微调整 w
print(f"训练后:w = {w:.4f}") # 打印出学完之后的 w
假设 w 的初始值是 0.7,让我们手动走一遍第一条数据:
面积 = 60,真实价格 = 180
预测价格 = 0.7 × 60 = 42
误差 = 42 − 180 = −138(预测比真实低了 138)
调整量 = 0.00001 × (−138) × 60 = −0.0828
新的 w = 0.7 − (−0.0828) = 0.7828
w 从 0.7 变成了 0.7828——朝着 3.0 的方向迈了一小步。第一步迈得不多,但 100 轮 × 4 条数据 = 400 次调整之后,w 会非常接近 3.0。
运行这段程序,输出大约是:
训练前:w = 0.7000
训练后:w = 3.0000
机器自己找到了「价格 = 面积 × 3」这个规律。没有人告诉它答案是 3,它是通过反复试错学到的。
从这个例子到 Sophia
这个例子和 Sophia 的训练在原理上是完全一样的。区别只在规模:
| 房价例子 | Sophia | |
|---|---|---|
| 旋钮数量 | 1 个 | 10 亿个 |
| 数据 | 4 条 | 200 亿个 token |
| 输入 | 房子面积 | 一段文本 |
| 输出 | 一个价格 | 下一个词的概率 |
| 训练次数 | 400 次 | 约 200 亿次 |
原理相同,规模不同。这门课接下来的五十九个章节会一步一步地展开这张表:文本怎么变成机器能处理的数字,「下一个词的概率」是怎么算出来的,十亿个旋钮怎么同时高效地调整,以及怎么知道训练是否成功。每一步都会回到 Sophia 的实际设计,让你看到原理怎么变成一个真实的、能和你对话的模型。