📕 第1章 深度学习与机器学习
📄 一句话概括

深度学习不是什么新东西,它就是「多层类神经网络」的另一个名字。 一个神经元只做两件事:把输入加权求和,再把结果弯一下。 把这样的神经元叠成几层,网络就能自己从原始数据里造出有用的特征,不必由人先把特征想好。 这一节用一个同心圆的数据集把这件事量出来: 同一条数据,三种做法,准确率 0.5125/1.0000/1.0000,差别只在「特征是谁造的」。

📝 本节和前面几节的关系

这是全书第一章第一节,先把「深度学习在哪儿」讲清楚。 后面第 4 章拆单个神经元、第 5 章拆卷积,都是从这一节的定义往下长; 第 2、3 章先解决「怎么把环境装起来」。 如果 41 课《图解深度学习》已经读过,这一节可以当复习;没读过也没关系,本节只需要会算加权和。

一、三个词的位置

人工智能、机器学习、深度学习,这三个词天天一起出现,但它们是一层套一层的关系, 不是三件并列的事。

词 干什么 典型代表
人工智能 一切让机器表现出智能的办法 规则系统、搜索、机器学习
机器学习 不手写规则,给数据和目标,让程序自己调参数 线性回归、支持向量机、随机森林
深度学习 模型是多层网络,特征和分类器一起学 CNN、RNN、Transformer

所以「深度学习更高级」这句话是错的。 它只是在数据够多、算力够用的时候更省人力——省的是「想特征」这一道工序, 代价是要喂更多数据和更多电。

二、一个神经元做的两件事

一个神经元收进几个数 x₁、x₂,先算加权和:z = w₁x₁ + w₂x₂ + b。w 是权重,b 是偏置。 这一步是纯线性的。 然后它把这个 z 塞进一个非线性函数 f,输出 a = f(z)。 这个 f 书里叫激励函数,常见的是 sigmoid、tanh、ReLU。 为什么非要那个 f?因为没有它,叠多少层都等于一层。 两层线性接起来是 w₂(w₁x) = (w₂w₁)x,两个矩阵乘能合并成一个矩阵乘,深度就白搭了。 非线性是把「直」掰「弯」的唯一手段,也是深度能成立的前提。

三、深度=层数,层数有什么用

单层网络的判别边界是 w·x + b = 0,几何上是一个超平面,二维里就是一条直线。 同心圆这种数据,一条直线怎么摆都切不开——这正是下一节要讲的 1969 年那次打击。 两层之后,隐层先把输入变换到另一个空间,输出层在那个空间里切一刀。 刀还是直的,但它切的已经不是原来的空间——这就是多层能画出曲线的原理。 再往深走,每一层学到的模式越来越「大」:第一层看边缘,中间层看部件,最后几层看整个物体。 这件事第 5 章会用手算的卷积核对上号。

四、代价:参数与算力

同心圆那个例子里,两层网络 33 个参数就够:第一层 2×8 个权重加 8 个偏置, 第二层 8×1 个权重加 1 个偏置。 真实的网络是百万级到千亿级。 参数一多,要的数据也跟着多,否则网络会把训练集背下来而不会举一反三——那叫过适,5.11 节专门讲。 第二笔代价是算力。 网络里绝大部分乘加都发生在矩阵乘上,所以「能不能训」这件事,很大程度上就是「矩阵乘够不够快」。

五、动手 Demo:同一份数据,三种做法

造 400 个点:内圈半径 0~1,外圈半径 1.5~2.2,各 200 个,角度均匀撒开,再叠一点 0.05 的高斯噪声。 内圈标 0,外圈标 1。 三种做法喂的是同一份数据:① 拿原始 xy 做逻辑回归;② 人先把 (x, y) 换成半径 r,再扫一遍最优阈值; ③ 两层网络自己学。

import numpy as np
rg = np.random.default_rng(20261026)

# 造数据:内圈一类、外圈一类,中间留空
n = 200
t = rg.uniform(0, 2 * np.pi, n)
r0 = rg.uniform(0.0, 1.0, n)
r1 = rg.uniform(1.5, 2.2, n)
X = np.vstack([np.c_[r0 * np.cos(t), r0 * np.sin(t)],
               np.c_[r1 * np.cos(t), r1 * np.sin(t)]])
X = X + rg.normal(0, 0.05, X.shape)
y = np.r_[np.zeros(n), np.ones(n)]

# 做法一:直接拿 xy 做线性分类(逻辑回归,梯度下降 3000 步)
w = np.zeros(2); b = 0.0
for _ in range(3000):
    p = 1 / (1 + np.exp(-(X @ w + b)))
    g = p - y
    w -= 0.1 * (X.T @ g) / len(y)
    b -= 0.1 * g.mean()

# 做法二:手工把 (x, y) 换成半径 r,再扫一遍最优阈值
r = np.hypot(X[:, 0], X[:, 1])
order = np.argsort(r)
acc_r = 0.0
for k in range(1, len(r)):
    pred = np.zeros(len(r)); pred[order[k:]] = 1.0
    acc_r = max(acc_r, float((pred == y).mean()))

# 做法三:两层网络 2-8-1,tanh 隐层 + sigmoid 输出
W1 = rg.normal(0, 0.5, (2, 8)); b1 = np.zeros(8)
W2 = rg.normal(0, 0.5, (8, 1)); b2 = np.zeros(1)
for _ in range(4000):
    H = np.tanh(X @ W1 + b1)
    p = 1 / (1 + np.exp(-(H @ W2 + b2))).ravel()
    g = (p - y) / len(y)
    gH = np.outer(g, W2.ravel()) * (1 - H * H)
    W2 -= 0.5 * (H.T @ g).reshape(-1, 1);  b2 -= 0.5 * g.sum()
    W1 -= 0.5 * (X.T @ gH);                b1 -= 0.5 * gH.sum(0)

实跑输出:

--------------------------------------------------------------------
深度学习的基础 —— 同一份数据,三种做法
--------------------------------------------------------------------

  400 个点,内圈一类、外圈一类,两个同心圆。半径 0~1 与 1.5~2.2 分开,中间留空。

  做法                      参数个数  准确率
  -------------------------------------------
  线性分类器(原始 xy)     3         0.5125
  手工造出「半径」再切一刀  1         1.0000
  两层网络(2-8-1,自己学) 33        1.0000

  三种做法喂的是同一份数据,差别只在「特征是谁造的」:
  **线性分类器 3 个参数,只能画一条直线,永远切不开内外圈,50% 上下;**
  **手工造出半径 r,1 个参数就够——人已经把「圆」这个结构想明白,写进了特征;**
  **两层网络 33 个参数,没人告诉它该用半径,它自己从 xy 里追平了这个结果。**

  这就是深度学习一句话的定义:**把「造特征」这一步也从人手里拿走,交给层数去做。**
  隐层那 8 个单元各算一次「输入的加权和再弯一下」,组合出来的边界就不再是直线。
  注意它并不比人聪明——**它只是把「人想特征要花的时间」换成了「机器算参数要花的算力」。**

线性分类器 0.5125,基本等于瞎猜。 它只有 3 个参数,只能画一条直线,而内外圈是套着的,直线穿不进去。 手工造半径 1.0000,只用了 1 个参数。 因为「半径」这个变换已经把「圆」这个结构写进了特征,剩下的只是「半径大于多少算外圈」。 两层网络 1.0000,33 个参数,没人告诉它该用半径。 它靠隐层那 8 个单元把 xy 揉成一个新空间,在那个空间里一刀切开。 注意最后这一点:它不是比人聪明,是比人省事。人想特征要花时间和经验,机器算参数要花算力和电。 深度学习能流行,是因为后者的价格掉得比前者快。

30 秒实验

  1. 把噪声从 0.05 调到 0.4,三种做法的准确率各掉到多少?先猜,再改一个数重跑。
  2. 把隐层从 8 改成 2 再跑,两层网络还能到 1.0000 吗?如果掉了,说明什么?
  3. 把两圈半径改成 0.8~1.2 与 1.0~1.4(互相重叠),手工半径那一招还能满分吗?

常见误区

  1. 以为深度学习是「更聪明的机器学习」。 它是结构不同的机器学习。 在几百条数据的小表上,线性模型和随机森林常常打得过神经网络,还省事得多。
  2. 以为层数越多越准。 层数多了参数多了,没有相应多的数据和正则,结果只会是训练集上 0 误差、 测试集上惨不忍睹。
  3. 以为深度学习就不用人管特征了。 归一化、去重、数据增强、标签质量,这些活一样都跑不掉; 网络只是把「造特征」这一项接过手了。
自测三问(点开对答案) 1. 为什么两层纯线性网络等价于一层? —— 因为 w₂(w₁x) = (w₂w₁)x,两个矩阵可以先乘成一个。 中间没有非线性,层数再多也只是换了个等价的大矩阵。 2. 同心圆例子里,手工特征凭什么 1 个参数就够? —— 因为 r = √(x²+y²) 这个变换本身是非线性的,它已经把「圆」这个结构搬进了特征空间。 剩下的判定是「r 大于某个值」,一维里切一刀即可。 3. 33 个参数追平 1 个参数,说明深度学习更强吗? —— 不说明。它说明的是:**参数换掉了人的思考。**这个数据集上人想得出半径,所以手工作法极省; 换成「判断这张图是不是猫」,人说不出该造什么特征,差距就出来了。

这一节说清了深度学习是什么、凭什么成立。 下一节回到 1958 年,看这条路是怎么被踩出来的,以及它为什么在 1969 年被判了一次死刑。

相关笔记