为什么是 Python,以及怎么使唤它
这一章讲三件事: 一门明明很慢的语言凭什么当了 AI 的门面; 拿到一个问题该从哪儿下手(两把思维工具);以及第 01 章那条链的最后一环 —— 一个 −1 到 1 的数,怎么真的变成两个轮子的转速。 它在全书链条里的位置是第 1 级台阶: 要让车自己跑,先得能指挥计算机。 不需要编程基础,遇到的生词都在当场解释。
1. 顶层全景
一个问题(「电池 11.5V,这车能上场吗?」)
│
│ ① 用两把工具拆开它:计算思维(把实际问题变成能算的东西)
│ IPO(输入什么 — 怎么处理 — 输出什么)
▼
一段 Python 代码
│
│ ② 交给「解释器」——它先把代码译成一种中间形式,再一条条执行
▼
结果打印在屏幕上
│
│ ③ 真正费算力的活(几百万次乘加)不在这一层做,
│ Python 把它们转手交给用 C 写好的库
▼
快
图说:这一章从上往下走一遍。第 2 节讲最下面那一格(为什么慢却好用),
第 3 节讲最上面那一格(两把工具),第 4—7 节讲中间那一格(语法零件)。
本章主走查: 「电池电压 11.5V,这辆车该不该上场?」 这个问题会从第 4 节一路走到第 7 节,每一节给它加一个零件。 另有一处副走查在第 5 节 —— 那是第 01 章那条链的最后一环,不在主走查上,所以单独走。
2. 一门慢语言,凭什么当了 AI 的门面
先看现象:程序是怎么变成机器动作的
计算机真正能直接执行的,只有一长串 0 和 1 —— 书里管这个叫机器语言。
比如在一台 16 位计算机上,「把 2 和 3 加起来」这条指令长这样:11010010 001110111。
没人愿意这样写程序。 所以有了一层一层的翻译:
| 层次 | 长什么样 | 谁能读 |
|---|---|---|
| 机器语言 | 11010010 00111011 | 只有 CPU |
| 汇编语言 | add 2, 3, result | 人勉强能读,和机器指令一一对应 |
| 高级语言 | result = 2 + 3 | 人一眼能读,和具体机器无关 |
书把前两种叫低级语言,第三种叫高级语言。「低」不是贬义, 它指的是离硬件近:直接摸得到内存地址和寄存器,代价是换一台不同架构的机器就跑不了2。
高级语言怎么变回机器认得的东西:两条路
编译执行:整份代码 → (编译器一次翻译完) → 一个可执行文件 → 直接跑
快;但换个平台要重新翻译一遍。C、C++、Java 走这条
解释执行:代码 → (解释器一行一行翻译,翻一行跑一行)
慢;但换个平台不用改。Python、JavaScript、Ruby 走这条
图说:一个是「先全部译成中文再读」,一个是「读一句译一句」。
后者每次读都要重译,所以慢。
Python 走的其实是混合路。 书自己纠正了「Python 是纯解释型」这个流行说法: 它运行时会先把代码转换成中间形式的字节码,再由解释器执行这些字节码3。
「字节码」在这里当场解释: 它是一种介于人写的代码和机器指令之间的东西 —— 比源代码更接近机器、但还不是任何一台具体机器的指令。好处是只用翻译一次, 之后重复执行就省下了反复翻译的开销;坏处是它终究还要有人边读边执行, 所以还是比直接跑机器码慢。
那为什么做 AI 反而都用它
这是本节的核心问题。答案不是「它其实不慢」,答案是「慢的那一层没在干活」。
书给的说法很直接:因为 Python 编程方式灵活简单,很多用 C、C++ 开发的专业库 都可以通过简单的接口封装以供 Python 使用,所以 Python 被称为**「胶水语言」**4。
拆开看这件事:
你写的 Python: result = numpy.dot(A, B) ← 一行,慢的那一层只执行了这一行
│
▼
实 际发生的: 一段用 C 写好、编译成机器码的矩阵乘法
几百万次乘加,全速跑
│
▼
还给你: 结果
图说:Python 在这里只做了「点菜」,炒菜的是 C。
点菜慢一点无所谓,因为炒菜才是耗时间的那部分。
这就是全书的技术前提。 后面所有「把 128×128 的图送进网络算一遍」这类动作, Python 只负责发号施令,真正的算术在别人写好的库里跑。
生态:为什么随手就有库可用
书还给了三个数字,说明这门语言的可用零件有多少5:
| 数量 | 参照 | |
|---|---|---|
| 标准库(装好就有,不用另外装) | 约 270 个 | 相当于买手机时预装的应用 |
| 第三方库(要另外装) | 十几万个 | 相当于整个应用商店 |
| 装一个第三方库要几步 | 一条命令 | pip install 名字 |
书还点出了这类开源生态的三个特点:竞争发展(同一个功能常常有好几个项目在抢, 赢者通吃)、相互依存(库和库互相调用)、迅速更迭 —— 活跃项目的更新周期常常不到一个月,而传统商业软件是 3 到 6 个月6。
判断(我们的,不是书里的): 「更新周期不到一个月」在 2024 年是优点, 在工程上却是一把双刃剑 —— 第 14 章和第 16 章各有一处是被它咬到的: 装框架必须找和硬件系统版本对应的那个包,版本对不上就装不上。 快和稳在这件事上是互斥的。 如果错,会错在: 如果那两处装不上其实是硬件厂商发布节奏的问题、而不是开源生态更新快, 那这条因果就挂错了地方。判据是:同一块板子换个非开源的工具链,会不会也有版本对不上的问题。
3. 拿到一个问题,从哪儿下手
这一节给两把工具。它们贯穿全书 —— 后面每一个实例都是照这两把工具拆开的。
工具一:计算思维
这个词由周以真在 2006 年的一篇论文里提出7。它不是「像计算机那样思考」, 恰恰相反 —— 书特意强调它是人求解问题的一种途径。
它的两个核心特征是抽象和自动化,四个步骤是:
① 把实际问题抽象成数学问题,建一个模型
② 把模型里的变量和规则用符号表示出来
③ 把解题思路写成一步步的算法
④ 让计算机去执行
图说:书对这四步的总结值得记住——
「抽象是方法和手段,自动化是最终的目标」。
抽象贯穿全程,自动化是为了把人从重复计算里解放出来。
书还给「计算」下了一个很宽的定义:用特定的符号串,按照预定的规则, 经过有限步骤,得到一个满足预定条件的符号串8。 这个定义的用处是:它把「什么能算」的边界推得很远 —— 只要能符号化、能定规则, 就能算。识别一张图属于哪一类,按这个定义也是「算」。
工具二:IPO
比上面那把更小、更实用。IPO 就是三个英文单词的首字母:输入 — 处理 — 输出9。
| 字母 | 意思 | 这本书里通常是什么 |
|---|---|---|
| Input | 数据从哪儿来 | 键盘、文件、摄像头、别的程序 |
| Process | 拿它干什么 | 书说这一部分统称算法,是程序的灵魂 |
| Output | 结果怎么给出去 | 屏幕、文件、另一个程序、电机 |
拿到任何一个题,先填这三个格子。 下面两节各拆一个实例,两次都是照这个格子填的。
4. 第一个实例:一个到处都是的分段函数
书的第一个例子不是「Hello World」,而是本行的东西 —— 这是它的一个特点。
先看这个函数在做什么
规则只有一句:输入大于 0,就原样输出;输入是 0 或者更小,就输出 0。
输入 x = 3.7 → 输出 3.7
输入 x = 0 → 输出 0
输入 x = −2.1 → 输出 0
图说:正数照单全收,负数一律压成 0。就这么简单。
用 IPO 拆开它:输入是一个数 x;处理是那句判断;输出是处理后的数。
示范代码(这段是我们写的,不是书里的 —— 原书的代码是图片,清洗出来的文本里没有):
def relu(x):
if x > 0:
return x
else:
return 0
现在给它 留名
这个分段函数在深度学习里到处都是。它的名字叫 ReLU —— 全称是 Rectified Linear Unit,书直接说它「实际上是斜坡函数,即 f(x) = max(0, x)」10。
它属于一类东西,这类东西叫激活函数。书给的定位是:它最终决定要发送给下一个神经元的信息11。
书还说这类函数是为了实现「非线性输出」。非线性 = 画出来不是一条直线 —— 画出来是直线的那种叫线性(比如 y = 2x + 1),而上面这个函数在原点拐了个弯,所以它是非线性的。
现在你只需要记住这两个名字和这条规则。 为什么神经网络里非要有这么一道手续、为什么偏偏是这个形状最常用, 第 07 章讲(那里会看到它是被另一个更早的做法逼出来的)。
为什么要在这里就给名字,而不是留到第 07 章: 因为你翻开任何一个深度学习工具的文档,
relu这个词都会在第一页出现。 现在给了名字,你以后撞见它时能认出「这就是我已经懂了的那个东西」。