跳到主要内容

通读笔记(二):第 7—11 章 —— 这本书真正的正文

reading-notes.md。这五章约 90k 字符,占全书 56%,是这本书不可替代的部分。


10. 第 7 章 Python 计算生态及机器学习概述(text/08-ch07-7-python.txt,18.1k 字)

这一章是全书的枢纽:前面是「怎么写 Python」,从这里开始是「怎么用 Python 做 AI」。

10.1 骨架

计算思维(周以真 2006)

Python 计算生态(为什么是 Python:胶水语言、十几万第三方库)

数据分析三大库 numpy / pandas / matplotlib
↓ (matplotlib 的落点:画 loss 和 acc 曲线)
机器学习概述(三步走 / 按任务分类 / 按学习方式分类)

一元线性回归:模型 → 损失函数 → 梯度下降 → 智能车路径拟合

10.2 计算思维(7.1)

  • 周以真(Jeannette Wing)2006 年在论文 Computational Thinking 中提出(:13);
  • 两大核心特征:抽象自动化(:23);
  • 四步:实际问题 → 数学模型 → 符号映射 → 写成算法 → 计算机执行(:25:31);
  • 「抽象是方法和手段,自动化是最终的目标」(:33);
  • 计算的本质被定义成:「使用特定的符号串,按照预定的规则,经过有限步的步骤,得到一个满足预定条件的符号串」(:35)。

10.3 Python 生态(7.2)

位置
计算生态三特点:竞争发展(赢者通吃)、相互依存、迅速更迭(活跃项目更新周期 < 1 个月,对比商业软件 3—6 个月):45:49
「胶水语言」:C/C++ 写的专业库通过简单接口封装给 Python 用:53
模块 / 包 / 库三级:57:61
标准库约 270 个:67
三种安装方式:pip / 官网自定义 / whl 文件离线:71:83
七大应用领域各自的代表库:87:99

10.4 numpy / pandas / matplotlib(7.3)—— 「数据分析三大剑客」

numpy 两个基本对象:ndarray(存单一数据类型的多维数组)和 ufunc(能对数组整体运算的函数)(:111)。 覆盖:创建、增删、变形(转置/展平/重整/复制)、拼接、切分、统计量、特殊常量、随机数包、线性代数包。

书里讲清楚的几组易混对照(这是这一节真正有价值的部分,表格是图片但对照说明在正文里):

对照差别位置
x.resize() vs np.resize() vs reshape()前者原地改、无返回值;np.resize 允许尺寸不一致会自动截断/拼接;reshape 有返回值、元素数必须相同、可用 -1 自动算某一维:153:157
ravel() vs flatten()ravel 是引用(改展平后的会影响原数组),flatten 是复制:163
np.repeat() vs np.tile()repeat 复制每个元素(可用 axis 控制行列);tile 复制整个数组:167

pandas 的定位说得很实在: 「『数据预处理』可以说是机器学习中最耗费时间的环节」「多数研发团队不会投入太多精力从事全新机器学习模型的研究,而是针对具体的项目和特定的数据,使用现有的经典模型进行分析」(:225)。

pandas 与 numpy 的分工(:229:231):

numpypandas
核心结构ndarray,任意维series(一维)/ dataframe(二维)
数据同质性必须同质可异构,同列同类型即可
索引只有数字索引数字索引 + 标签索引
定位数值计算、矩阵、线代读写、清洗、分析、可视化全流程

matplotlib 的关键概念是 figure 与 axes 的父子关系:figure 是画板,axes 是画板中的子图, 图表/图例/坐标轴又是 axes 的内部元素(:295)。书特意澄清: 「axes 从形式上讲是坐标轴 axis 一词的复数形式,但意义上却远非 2 个或多个坐标轴那么简单」(:301)。 两套接口:pyplot(单图、交互式够用)vs axes(多图、面向对象更优)(:299)。 三步:创建画板 → 绘制图表 → 配置图例(:305)。

7.3.4 落点:画 loss 和 acc 曲线(:313:317)。 数据文件 lossandacc.csv 三列:参数更新次数、loss 值、准确率。 这是把 matplotlib 直接接到深度学习上的过渡实例。

10.5 机器学习概述(7.4)—— 全书的概念地基

机器学习三步(这是全书反复用的框子,第 9 章开头又复述了一遍):

① 选模型 —— 「模型就是一组函数的集合」
② 判好坏 —— 设计损失函数(回归用欧式距离,分类用交叉熵)
③ 找最好的 —— 优化方法(梯度下降、牛顿法);「最重要也是最困难的」

(:333:337)

泛化能力的定义:「使得学到的函数能够很好地适用于新样本,而非仅仅只是在训练样本上面表现良好」(:331)。

按任务分类(:349:357):回归 / 分类 / 聚类(三大常见)+ 降维 / 密度估计 / 排序学习。

  • 回归:确定因变量与自变量的相关关系,建立回归方程;
  • 分类:学到一个分类决策函数,再对新数据预测分类;
  • 聚类:对未知样本划分成类簇。

按学习方式分类(:363:369):

  • 有监督:输入输出都已知,任务是发现两者的关系。回归、分类、排序都属此类;
  • 无监督:无标签,机器自行发现模式。聚类、降维、密度估计、模型生成;
  • 半监督:一部分有标签,「普遍来讲,没有标签的数据量会大于有标签的数据量」; 依据是「数据的分布必然不会是完全随机的」。

10.6 一元线性回归(7.5)—— 全书唯一一条从头推到尾的数学链条

这一节是第 8 章的预演,必须在拆解里讲透。 书用了教科书式的「三次改进」讲法:

第几版损失函数什么问题位置
① 直接算 预测值 - 真实值,累加取平均正负抵消,误差趋近 0:393:395
② 取绝对值再累加取平均绝对值函数在 x=0 处不可导(左导 -1、右导 +1):395:397
平方再取平均 = 平方损失 = 最小二乘可导、光滑:397:409

这三步的写法非常好 —— 每一步都是被上一步的毛病逼出来的,正是「不许跳级」的正面样板。

然后:「损失函数 J(θ₀,θ₁) 是一个关于参数 θ₀、θ₁ 的函数,一元线性回归学习的过程就是如何选取 适当的 θ₀、θ₁ 的值,使得 J 最小」(:401)。 书还给了一个降维演示:令 θ₀=0,损失函数就变成只关于 θ₁ 的一条曲线,曲线最低点就是最优参数(:405)。

梯度下降(7.5.3):

  • 下山比方 —— 不知道山下在哪,就沿着当前位置高度下降最快的方向走,走一段再重新选方向(:419);
  • 导数即斜率,导数为负 → 增大 θ 会让损失减小,所以取负梯度再乘一个系数作为参数增量(:421:425);
  • 学习率 α(Learning Rate, Lr),「也叫步长,是梯度下降法中一个非常重要的超参数」; 太小 → 迭代次数巨大、太慢;太大 → 在最小值附近反复振荡,收敛不到最低点(:427:431);
  • 损失函数里分母乘 2「为了便于后续二次函数求导计算」(:439);
  • θ₀、θ₁ 必须同步更新,因为两个更新公式里都同时含有 θ₀、θ₁,不同步的话一个会污染另一个(:441)。 —— 这条口径在第 8 章的 BP 走查里又强调了一次(09-ch08.txt:245:281)。

7.5.4 落点:智能车路径拟合。 Data_middlepoint.csv 里有直线路段采集的 42 个路径中心点(x,y), 用 sklearn 的线性回归拟合出一条车道中心线,供后续路径跟踪用(:447)。 sklearn 六大模块清单在 :451:461

10.7 习题里的一个真数据集

EVMiles-200.csv:某电动汽车实际行驶采集,200 个样本,第一列是续驶里程(标签), 其余 4 列是特征,要求分别建 4 个一元线性回归(:585)。


11. 第 8 章 深度学习基础及车辆识别项目实践(text/09-ch08.txt,17.7k 字)

这是全书理论最厚的一章,也是全书唯一一处给了完整数值走查的地方。

11.1 骨架

四个概念的包含关系:深度学习 ∈ 神经网络 ∈ 机器学习 ∈ 人工智能

单层感知机(第 4 章讲过,这里补上参数更新公式)

多层感知机 = 全连接神经网络 DNN

深度学习理论基础:前向传播 → 激活函数 → 损失函数 → 优化方法 → 反向传播 → 计算图

深度学习框架:tensorflow / pytorch / PaddlePaddle

落地:DNN 车辆识别项目(汽车/摩托车/货车 三分类)

11.2 关键定位句

  • 「深度学习 ∈ 神经网络 ∈ 机器学习 ∈ 人工智能」(:17)—— 一句话把四个词的关系钉死,值得照搬;
  • 「机器学习中最受欢迎的算法才从传统的 SVM 算法逐渐转变为现如今的神经网络算法」(:15);
  • 深度学习的「深度」有两个含义:一是网络层数深,二是能学到样本更深层次的特征(:59);
  • 浅层神经网络大多只有 3—5 个隐藏层,深层有十几到上百层(:59);
  • 全连接的由来:「除输入层和输出层之外,每一层的每一个节点都与上下层节点全部连接」(:63);
  • 隐藏层能更好地分离数据特征,但过多的隐藏层会导致过拟合(:63)。

11.3 单层感知机的补完(8.1.2)

第 4 章只给了结构,这一章补上:

  • 生物神经元与人工神经元的功能对位(:31): 树突 ↔ 接收输入;细胞体 ↔ 加权求和;轴突 ↔ 激活函数控制输出;突触 ↔ 输出层;
  • 「一个单层感知器可以简单理解为一个线性回归模型」(:35);
  • 训练 = 学习权重和偏置的过程;把偏置也看成一个特殊的权重,问题就化归为学 wᵢ(:37);
  • 参数更新用学习率 η,取值范围 (0,1)(:39);
  • 实例 8.1 的具体数据:平面上 4 个点,标签 1 的是 (5,4) 和 (4,5),标签 -1 的是 (1,2) 和 (3,2), 用单层感知器分成两类(:41)。这是书里少有的可直接引用的具体数字。

11.4 多层感知机为什么成立(8.1.3)

书给的理由是类比:「傅里叶变换、多项式的泰勒展开等,都可以分解为简单基本函数的叠加, 也就是说,用简单的函数组合出复杂的函数是有理论支撑的」(:53)。

缺口 G11(重要):书说「有理论支撑」但没有点名这个理论。 它指的是通用逼近定理,而书自己的参考文献 [15] 恰恰就是 Cybenko 1989 (13-fm.txt:33,搜「Approximation by superpositions」)—— 参考文献里有,正文里没接上。 我们书架上讲透了这一条,见 §14 缺口清单。

另一句关键区分:「神经元和感知器本质上是一样的,只不过感知器的激活函数是阶跃函数, 而神经元的激活函数往往选择为 sigmoid 函数或 ReLU 函数等」(:53)。

11.5 ★ 走查 A:信号前向传播(8.2.1)—— 带真数字

:71:75,一个「输入层 + 两个隐藏层 + 输出层」的小网络:

输入 1 和 -1
↓ 第一层第一个神经元:1×1 + (-1)×(-1) + 偏置 1 = 3
↓ sigmoid(3) = 0.95
↓ …其他神经元同法…
输出 0.61 和 0.64

书自己点明:「全连接神经网络实际上就是由多个单层感知器按照一定的规则连接起来所形成的, 整个神经网络叠加起来可以把它抽象为一个函数」(:75), 「参数学习需要做的事情就是去不断学习调整权重和偏置」(:77)。

11.6 激活函数(8.2.2)

  • 为什么必须有:没有激活函数,「无论网络有多少层,最终输出都是输入的线性组合, 整个网络的逼近能力将极其有限」(:81)。这是全书对激活函数最要紧的一句话。
  • sigmoid / tanh 的病:具有饱和性,输入非常大或非常小时导数趋近于零 → 梯度消失(:83);
  • ReLU:x>0 时梯度不变,有效解决梯度消失;但 x<0 时梯度为 0, 「这个神经元及之后的神经元梯度永远为 0,不再对任何数据有所响应」→ 于是有了 Leaky-ReLU 和 ELU(:83);
  • Softmax:把数值向量归一化成概率分布(各项之和为 1),作最后一层用于多分类; 「Softmax 层常和交叉熵损失函数一起结合使用」(:89)。

第 2 章埋的 ReLU 伏笔在这里收了(03-ch02-2-python.txt:3309-ch08.txt:83)。 第 2 章只说「f(x)=max(0,x)」,到这里才回答「为什么用它」。

11.7 损失函数(8.2.3)

四个作用:衡量准确性、优化模型、计算反向传播信号、评估模型(:97:103)。 两大类(:107:109):

原理代表
基于距离度量把样本映射到欧式空间等特征空间,量真实值与预测值两点间的距离MSE、L2(LSE)、L1(LAE)、Smooth、Huber
基于概率分布度量真实分布与估计分布之间的距离KL 散度(相对熵)、交叉熵、Softmax 损失、Focal

用在训练阶段:一批数据前向传播 → 算损失 → 反向传播更新参数(:105)。

11.8 优化方法(8.2.4)—— 一条清晰的演进链

标准梯度下降(全部样本算总误差再更新)
│ 病:大规模样本效率极低;接近最优时收敛变缓

随机梯度下降 SGD(随机抽 1 个样本)
│ 好:快;有更大概率跳出较差的局部最优
│ 病:容易困在局部最优和鞍点附近

小批量梯度下降 mini-batch(取一个子集)
│ 「现如今使用梯度下降法往往都是指小批量梯度下降法」
│ 病:对学习率敏感,需要合适的初始化和步长

Momentum(动量;γ 一般取 0.9)
│ 方向一致就加速,不一致就衰减;有助于跳出局部最优
│ 病:「只会盲目地跟随最大下降梯度」,可能冲出坡底

Nesterov Momentum(前瞻项:用下一时刻的近似参数求梯度)

Adam(Kingma & Ba, 2014;β₁=0.9, β₂=0.999, α=0.001)
「无论数据稀疏与否都能取得相对较好的效果」

(:119:147)

11.9 ★★ 走查 B:误差反向传播(8.2.5)—— 全书最完整的一处,带全部数字

这是全书对拆解最有价值的一段。 :151:291

BP 的来历:「以 McClelland 和 Rumelhart 为首的科学家小组提出」(:153); 「在实际应用中,大约 80% 的神经网络模型都采取了 BP 网络或 BP 网络的变化形式」(:153)。

BP 到底是什么(书的这句澄清很重要):

「BP 算法实际上是一种在神经网络训练过程中用来计算梯度的方法…… 这个梯度会反馈给某种学习算法,例如梯度下降法,用来更新权值,这里梯度下降法才是学习算法。」(:165)

链式法则: y=f(u), u=g(x) → dy/dx = (dy/du)(du/dx); 「在神经网络中,每个节点都可以看作是一个复合函数」(:167:173)。

具体网络与全部初始数值(:175:183):

结构:2 输入 → 1 个隐藏层(2 神经元 h₁ h₂) → 输出层(2 神经元 o₁ o₂)
全连接 ⇒ 8 条连线 ⇒ 8 个权重 + 隐藏层偏置 b₁ + 输出层偏置 b₂ = 10 个参数
激活:sigmoid

输入 i₁=0.02 i₂=0.7
期望 o₁=0 o₂=1
初值 w₁=0.1 w₂=0.2 w₃=0.3 w₄=0.4
w₅=0.2 w₆=0.3 w₇=0.1 w₈=0.2
b₁=0.3 b₂=0.2

三步走(书自己分的 Step1/2/3):

做什么具体结果
Step1 前向输入层→隐藏层(净活值 net_h1 → 激活 out_h1)→ 隐藏层→输出层第一轮输出 [0.62586, 0.59613],与期望 [0,1] 相差较大(:203)
Step2 反向平方误差 E_total = E_o1 + E_o2;先更新 w₅(输出层侧),再更新 w₁(输入层侧)见下
Step3 迭代反复第一轮后 E_total 由 0.27741 降到 0.26537;迭代 10000 次后总误差 0.000063612,输出 [0.00793003941675692, 0.9919789331998798](:291)

Step2 的链条(这是「不许跳级」的天然素材):

  • 更新 w₅(隐藏层→输出层)拆成三项: ∂E_total/∂w₅ = (∂E_total/∂out_o1) · (∂out_o1/∂net_o1) · (∂net_o1/∂w₅)(:215:237) —— 分别对应「总误差怎么随 o₁ 的输出变」「sigmoid 的导数」「净活值怎么随权重变」;
  • 更新 w₁(输入层→隐藏层)多一层:因为 h₁ 的输出同时流向 o₁ 和 o₂, 所以 E_o1 和 E_o2 都是 w₁ 的函数,∂E_total/∂out_h1 要把两条路加起来(:251:261:265);
  • 同步更新的口径:「在求每个参数更新值的时候,其他参数在这一轮中仍然用更新前的值」(:245:281)。

拆解建议:这条走查应该成为整本拆解的「主走查」,并且贯穿多章 —— 因为它同时用上了前向传播、sigmoid、平方损失、链式法则、梯度下降、学习率、同步更新。 注意公式本体是图片,但每一步的文字描述、所有输入数值和所有结果数值都在正文里,足够我们自己重算并复现。

11.10 计算图(8.2.6)

  • 引入理由很直白:「如果仅使用公式来描述的话会很复杂,如 8.2.5 小节所示」(:297);
  • 节点 = 数据(标量/矢量/张量),边 = 操作(函数);节点间的结构关系叫拓扑结构(:297);
  • 一个带数的小例子:a=1, b=2 → c=3, d=3, e=9(:311);
  • 五步构建法(:317:327);
  • 「在 Pytorch、TensorFlow、PaddlePaddle 等深度学习框架中都广泛采用了计算图」(:329)。

11.11 深度学习框架(8.3)

框架书里给的关键事实位置
tensorflowGoogle 大脑出品,基于 DistBelief 的第二代;2015-11-09 开源;名字来自 tensor(N 维数组)+ flow(数据流图);四组件 tensor/graph/OP/session:341:345
pytorch前身 torch,torch7 团队开发;「可以看作是加入了 GPU 支持的 numpy」,也可看成「拥有自动求导功能的深度神经网络」:349
PaddlePaddle 飞桨「中国首个自主研发、功能完备、开源开放的产业级深度学习平台」;四大优势:易用前端+高层 API、超大规模分布式训练(千亿稀疏特征/万亿参数/数百节点)、多端多平台推理引擎、270 个以上官方模型:355:367

书的立场是明说的:「虽然起步较晚,但发展速度非常迅速……相信它会为我国自主产权的人工智能技术发展奠定更好的基础」(:337)。 这是编者的价值判断,不是技术论断,拆解时要按「三个声音」分开标。

11.12 ★ 深度学习通用五步(8.4 开头)—— 后三章的公共骨架

:373:385这五步在第 9、10、11 章各走一遍,是全书后半段的结构主干:

① 数据处理 —— 五件事:数据导入 / 形状变换 / 数据集划分 / 归一化 / 数据封装
归一化的两个好处(书写得很具体):
a) 让不同参数的 loss 曲线较为规则,学习率可以设成统一的值
b) 每个特征的权重大小可以直接代表该特征对预测结果的贡献度
② 模型设计 —— 选网络类型、层数、连接方式
③ 模型训练 —— 喂数据、算损失、用优化算法更参数;选超参数(学习率、批量大小)
④ 模型评估和调优 —— 用测试集看准确性/精确度/召回率;不佳就回去改架构、优化算法或超参数
⑤ 模型部署和应用 —— 部署到硬件设备或服务器

11.13 DNN 车辆识别项目(8.4)

位置
任务三分类:1=汽车、2=摩托车、3=货车:387
数据来源2005 PASCAL 视觉类挑战赛(VOC2005) 数据筛选处理:387
训练/验证划分9:1:407
损失函数paddle.nn.CrossEntropyLoss() 交叉熵:417
优化器paddle.optimizer.Adam():417
学习率lr = 0.1:417
预测结果举例汽车 1.00 / 摩托车 0.00 / 货车 0.00:427
代码书里明说不附代码,给 AI Studio 链接 https://aistudio.baidu.com/projectdetail/3808393?...:393:395

书自己给了一句很老实的话:「单张图片的结果并不能准确反映出模型的效果,一般会有一个测试集」(:427)。


12. 第 9 章 卷积神经网络及斑马线识别项目实践(text/10-ch09.txt,16.3k 字)

12.1 ★ 这一章的写法是全书最好的:先讲 DNN 病在哪,再讲 CNN 怎么治

9.1 全连接神经网络的问题
├─ 结构不灵活
├─ 参数爆炸 ← 主症
└─ 极易过拟合
9.2 CNN 理论基础
├─ 三大特点:局部连接 / 权值共享 / 下采样 ← 三味药,一一对症
├─ 卷积层:一维 → 二维 → 多核 → 多通道 → 多通道多核
└─ 池化层:最大池化 / 平均池化,目的是扩大感受野
9.3 五个典型模型 LeNet → AlexNet → VGGNet → GoogleNet → ResNet
9.4 落地:CNN 斑马线检测项目

12.2 ★ 走查 C:参数爆炸的具体算账(9.1)—— 带真数字

:23,手写数字识别,输入 16×16:

输入层 256 个神经元(16×16)
3 个隐藏层,每层 1000 个
输出层 10 个

权重:256×1000 + 1000×1000 + 1000×1000 + 1000×10 = 2 266 000
偏置:1000 + 1000 + 1000 + 10 = 3 010
总计:2 269 010 个参数

(清洗文本里 10³ 被写成 103,是上标丢失,不是数据错;总数 2269010 是书给的,自己核过,对得上。)

书接着说:「倘若输入的图片大小为 128×128 甚至更大,网络的层数为 10 层乃至更多, 那么就会造成参数量过大,也就是参数爆炸的问题」(:23)。

另一处算账(9.2.1 局部连接,:41): 一张 640×480 的输入图,全连接 → 感受野是整张图,要更新 307200 个参数; 局部连接每次只取 16×16 的一小块 → 只要 256 个参数。

第三处(9.2.2 卷积 vs 全连接,:79): 3×3 输入、2×2 卷积核 → 只学 4 个参数;换成全连接(9 个输入、4 个神经元)要 36 个。

这三处算账都是现成的走查材料,而且都带具体数字。

12.3 三大特点的对位(9.2.1)

手段干什么关键概念位置
局部连接每个隐藏层节点只连到图像的局部区域感受野(Local Receptive Fields):特征图上的像素点映射回输入图像的对应区域:41
权值共享多个神经元各连一小块,但权重设成一样「用尽可能少的参数覆盖尽可能多的图像区域」:45
下采样把图缩小,不影响物体识别两种做法:stride>1 的池化,或 stride>1 的卷积:49

书对局部连接给的直觉:「一张图像中会有很大一部分区域是无用或者说用处很小的…… 通过猫鼻子这一块区域就能识别出图片中是猫」(:41)。

书对「池化 vs 步长卷积」的判断很有信息量(:49):

池化提供的是固定的、不可学习的非线性变换,可看作一种先验运算; 网络浅时池化可能更好,网络深时用多层卷积替代池化可能更好 —— 因为卷积能学到比池化更好的非线性变换。

12.4 卷积层(9.2.2)—— 五级递进

① 一维卷积:16×16 输入,2×1 卷积核 ⇒ 每个神经元只连 2 个输入,权值共享后整层只学 2 个参数
② 二维卷积:6×6 输入、3×3 卷积核、stride=1、padding=0 ⇒ 输出 4×4
「卷积层的实现方式实际上是数学中定义的互相关(cross-correlation)运算」
尺寸公式:c = (r - k + 2p)/s + 1
③ 多核卷积:3×3 输入、3 个 2×2 卷积核、stride=1 ⇒ 学 4×3=12 个参数,得 3 个特征图
④ 多通道卷积:3 个通道的特征图 3×3×3,配 3 个 2×2 的二维核 = 一个 3×2×2 的「卷积核立方体」
每通道各自卷积,最后**累加**成一张输出特征图
⑤ 多通道多核卷积:实际应用中两者共同进行

(:59:97)

一个书自己提出又自己回答的好问题(:79:81):

卷积把参数量降下来了,可参数少也意味着模型能模拟的函数空间变小了, 那怎么保证它还够用?—— 答案是多核卷积:一个卷积核只提一个特征,那就用多个核。

术语口径: 卷积核(kernel)也叫滤波器(filter);w×h 的核称为 w×h 卷积(:67)。

12.5 池化层(9.2.3)—— 有一处带数字的走查

:101:109先讲问题:卷积核一般 3×3 或 5×5,一直卷下去处理范围仍然有限, 「假设只采到了一个轮胎的范围,那么怎么可能只通过这个轮胎来识别出整辆车」→ 需要扩大感受野

具体走查:特征图 4×4 → 2×2 池化 → 2×2 特征图; 「左上角 40 这个值对应的是原特征图左上角的四个值」; 一个像素的感受野由 3×3 增大至 4×4

两种池化的语义(:105):

  • max pooling:把最突出、最显著的特征保留下来;
  • average pooling:对相邻特征之间的差别做模糊处理。

全连接层在 CNN 里的角色:「将卷积层输出的二维矩阵特征图拉伸转化为一个一维向量」再送进 Softmax/tanh(:111)。

12.6 五个典型模型(9.3)—— 一条清晰的演进史

模型年份/作者(书里的说法)关键创新关键数字位置
LeNet(-5)Yann LeCun,书写「1988 年」;LeCun 被称「卷积之父」CNN 的基石8 层;输入 32×32(实际数字在中间 28×28);C1:6 个 5×5 核 → 6 张 28×28,156 参数;C3:60 个 5×5 核 → 16 张 10×10,1516 参数;C5:120 核,48120 参数;输出层 850 参数:119:143
AlexNetAlex Krizhevsky 等,2012,ImageNet 冠军数据增强、ReLU、局部响应归一化、Dropout5 卷积 + 3 全连接 + 3 池化 + 2 Dropout;约 65 万神经元、6000 万参数:149:167
VGGNetSimonyan 等,2014 ILSVRC 亚军全用 3×3 小卷积核;证明深度有利但有上限,最终定在 16—19 层VGG16 输入 224×224×3;参数约 1.38 亿;两个 3×3(18 参数)替一个 5×5(25 参数)= 前者的 72%;三个 3×3 感受野 = 一个 7×7:171:181
GoogleNetGoogle,2014 ILSVRC 冠军Inception 模块(1×1 / 3×3 / 5×5 卷积 + 3×3 最大池化并联);V1 加 3 个 1×1 卷积压缩降维;用平均池化代替全连接;两个辅助分类器(只在训练时用)22 层(含池化 27 层);参数约 500 万,是 VGG16 的 1/27;参数量仅为 AlexNet 的 1/12:185:207
ResNet何恺明残差/跳跃连接 H(x) = F(x) + x;「让模型的内部结构至少有恒等映射的能力」5 种深度 18/34/50/101/152;56 层比 20 层误差更大(退化问题);ResNet101 = 1 + (3+4+23+3)×3 + 1;BasicBlock 参数 256×256×3×3×2 = 1179648,Bottleneck 只要 69632:211:236

书自己交代的一处「今昔之别」: LeNet 输出层原来用径向基函数单元(算欧式距离), 「如今已经不采用径向基函数了,而是改用 Softmax() 函数」(:141)。

LeNet 的一条重要观察(:143): 随着网络加深激活值尺寸逐渐变小,但降太快会伤性能; 卷积层参数相对较少,大量参数都在全连接层。

12.7 ★ 第 9 章暴露的书内错误(要如实指出)

#错在哪证据
E1LeNet 说成 1988 年:119;而书自己的参考文献 [17] 是 LeCun 等 1998 年 Gradient-based learning applied to document recognition(13-fm.txt:37)。LeNet-5 是 1998 年
E2LeNet 池化方式前后矛盾:129 先说「在 LeNet 中采用最大池化(max pool)」,同一段后半句又说「在 LeNet 中,采用平均池化后,均值乘上一个权值参数加上一个偏置参数作为激活函数的输入」。:135 又说 S4「池化方式为最大池化」。原始 LeNet-5 用的是带权重和偏置的平均池化(子采样)
E3「一般池化层是没有参数的」与 S2/S4 有 12/32 个参数并存:129:135:143 —— 这一处书其实自己解释了(LeNet 的池化带权值和偏置),但表述容易读岔,拆解时要讲明白

12.8 CNN 斑马线检测项目(9.4)

  • 任务:二分类 —— 含斑马线的马路 vs 不含斑马线的马路(:244);
  • 设计流程五步:数据处理 → 模型设计 → 训练配置 → 训练过程 → 模型保存(:248);
  • 书里同样不附代码,给 AI Studio 链接 https://aistudio.baidu.com/projectdetail/5107670?contributionType=1(:250:254)。

13. 第 10 章 智能车自动巡航算法设计及部署(text/11-ch10.txt,15.3k 字)

13.1 ★★ 这一章是全书的落点,而且结构极漂亮:同一个任务,三种做法

任务:让小车沿着车道线自己跑一圈

做法一 §10.2 传统图像处理 OpenCV 颜色阈值分割 → 提车道线 → 巡线
(不训练模型,靠人手调参数)
做法二 §10.3 深度学习·回归 CNN 直接预测转向角(一个 [-1,1] 的连续值)
(第 4/5/6 章那条数据流水线在这里全部兑现)
做法三 §10.4 深度学习·分割 PaddleSeg 的 BisenetV2 逐像素分类出车道线
(再提中心线交给控制)

三种做法的部署硬件还不一样:做法一、二用 EdgeBoard,做法三用 Jetson Nano。 拆解时这一章必须按「三条路线的取舍」来写,不能按书的节序流水账。

13.2 竞赛现场的硬事实(10.1)—— 读者没有这些就读不懂后面

位置
线下赛场地600cm × 480cm,PU 布或喷绘布:23
车道(含黄线)宽度约 50cm;地图左下角是出发起点:23
理想环境冷光源、低照度、无磁场干扰;但真实赛场有纹路、不平整、边框裂缝、光照变化 —— 「这恰恰是比赛的考核项之一」:23
车模结构四电机各驱一轮;后轮用近似麦克纳姆轮可横向摆动;转向靠前轮双电机差速 + 后轮横移:25
线上赛任务(2023)识别虚车道线、实车道线、斑马线的位置和类别 —— 书判定为「典型的图像分割任务」:17
线上赛数据集16000 张车载影像;标注是与原图同尺寸的单通道灰度图;背景=0,实车道线=1,虚车道线=2,斑马线=3:19
线下赛硬性要求必须用组委会指定的百度 EdgeBoard 边缘计算板卡:23
平台训练在 AI Studio(免费 GPU);框架 PaddlePaddle:15

13.3 做法一:OpenCV 颜色阈值分割(10.2)

四步(带图,步骤全在正文):

① 读图 → 转灰度图
问题:场景里除了车道线,还有标识物、障碍物、背景元素
② 蒙版(mask)—— 「蒙版是一个 numpy 数组」,把不关心的区域像素置 0 或 255
形状:因为摄像头角度,车道线区域是「近大远小的梯形」
③ 把蒙版套到灰度图上,分割出感兴趣区域(ROI)
④ 阈值处理,得到车道线

(:49:61)

图像上方检测不准的四条对策(:61:69):缩小 ROI / 调阈值 / 加滤波 / 用自适应阈值。

实车流程(10.2.3)也全给了 —— 这是全书唯一一段真实的调试现场:

干什么关键点位置
1 摄像头位置校准小车后轮抵住起始框,调摄像头角度,使画面里刚好看到白色启动区,左右车道线大致对称:81:89
2 颜色阈值校准开两个窗口(原图 + 二值图)+ 一个参数调节器,调 HSV 数值,记下来填进 follow.py为什么是 HSV 不是 RGB:第 6 章讲过 HSV 面向视觉感知:93:105
3 巡线参数调节self.max_speed(正常巡线速度)、self.min_speed(识别到地标后的速度);self.scale_1/self.scale_2 分别是直行/转弯时角速度的放大比例:107:121
4 实测直道、小幅弯道、十字路口、大幅弯道都能跟踪:123:135

竞赛场地用绿色把车道线与背景分开(:39)—— 这就是为什么颜色阈值这么朴素的办法能work。 书还点了一句:特斯拉和 mobileye 用纯视觉方案,创意赛用摄像头「可以将其理解为对现实世界纯视觉感知方案的模拟」(:37)。

13.4 ★ 做法二:CNN 回归预测转向角(10.3)—— 全书的技术高潮

13.4.1 数据采集(10.3.1)—— 第 4/5/6 章伏笔的总兑现

:145:147:

控制手柄 --USB扩展器--> EdgeBoard 板卡
↓ 人遥控小车沿赛道行驶
摇杆转动幅度 --程序归一化--> [-1,1] 的连续小数(负=左转,正=右转)
↓ 同时
车头顶端摄像头按一定帧率拍前方道路图

形成「图像 ↔ 转角」的数据对,存成 json(键=图片编号如 "001.jpg",值=转角)

转成「图片名 + 转角」的 txt(为了匹配训练时的数据格式)

按 8:2 随机划分训练集与验证集

两条来自现场的经验(书写得很实在):

  • 采集速度可在 0—100 设置,「为了兼顾控制手柄时人的反应速度以及摄像头采集帧率,速度一般设置在 20 左右」(:147);
  • 「为了保证最后小车转向控制模型的光滑连续性……尽量避免出现跳跃性的大幅度转向」(:147)。

13.4.2 数据增强(10.3.2)—— 一个非常好的「为什么不能照搬通用做法」

通用的两大类增强:几何变换(翻转/平移/缩放)与颜色变换(滤镜/色调/对比度/亮度/噪声)。

**书的关键判断:「自动巡航模型需要根据图像中车道的位置、角度等信息来匹配其与小车转向角度 之间的关系,因此,几何变换在此并不适用。」(:167)

—— 水平翻转会把「左转」变成「右转」但标签不变,直接毁掉数据。这是全书最漂亮的一处推理,拆解必讲。

所以只做颜色变换,理由也给了现场证据:「背景环境的光照条件、现场地图反光程度和印刷色差 等因素会对模型预测结果有非常大的影响」(:167)。 用的五类:加不同滤镜、改色调、调对比度、调亮度、改饱和度; 工具是 PIL 的 ImageEnhance 类 + OpenCV(滤镜)+ numpy(把像素转成矩阵再算)(:167:169)。 并且要随机地做,「为了排除人为因素的干扰并防止出现特征集中的问题」(:175)。

泛化性与过拟合的定义也在这一节(:161:163)。

13.4.3 ★ 走查 D:巡航 CNN 模型的逐层尺寸(10.3.3)—— 带全部数字

回归 vs 分类的结构差别(:181:185):

最后一层全连接照样输出 m 个参数,但不是接到 n 个神经元(n=类别数)上,而是接到 1 个神经元上, 输出一个连续值。「分类任务解决的是一个离散型问题,最终输出的结果为对应分类数的概率值; 而回归问题解决的是一个连续型问题,最终的输出结果是一个连续值。」

为什么要自己设计一个小网络: 「巡航模型需要部署在小车搭载的 EdgeBoard 板上运行, 这种边缘计算开发板算力有限,因此要求网络模型规模较小」(:189)。

结构:借鉴 AlexNet,5 个卷积层(第 1、2、5 层后跟池化,第 3、4 层不跟)。 输入 128×128×3,「远小于 AlexNet 输入图像尺寸,参数量仅约为其 1/4」(:189)。

第一层的具体设置与理由(:193):

  • 3×3 卷积核 × 32 个,stride=2,padding=2;
  • 为什么要填充 —— 书给的解释很具体:3×3 卷积下「在图像的边缘,部分像素最少仅能经过 1 次 卷积计算,但是图像中心区域像素却能经过多达 9 次」,边缘信息提取不充分; 而且不填充的话 feature map 会越来越小。

逐层尺寸(书直接给了,可以整条当走查用,:201):

输入 128×128×3
conv1 32×65×65 → pool1 32×64×64
conv2 32×33×33 → pool2 32×32×32
conv3 64×17×17 (无池化)
conv4 64×10×10 (无池化)
conv5 128× 6× 6 → pool5 128× 5× 5
→ 拉平 → 3 层全连接(激活 leaky-ReLU,中间夹 dropout) → 最后一层输出 1 个数
→ tanh 层 → 压到 [-1,1]

四个设计选择,每一个书都给了理由:

选择理由位置
激活用 leaky-ReLU 而不是 ReLUReLU 在 x<0 时值为 0,网络加深时「极有可能会带来权值无法更新的情况」;leaky-ReLU 用一个非零固定斜率 a,「有选择地保留部分负值」:205:207
dropout,丢弃率 0.1两个好处:避免特征只在特定组合下有效、减少冗余中间特征并提高特征间正交性。丢弃率取小是因为「巡航网络模型参数量相对较小」:209
最后加 tanh因为标签本来就是归一化到 [-1,1] 的小数:211
损失用 均方差(MSE) 而不是绝对误差「均方差误差的梯度是随着损失值的大小而不断变化的」:损失大时梯度大,损失趋近 0 时梯度也趋近 0,所以「模型在训练结束时更加精确,更容易收敛」:213

13.4.4 训练结果(10.3.4)—— 带真数字

:225:训练 300 轮,总耗时约 180 分钟,损失值由 0.219 降到 0.019; 250 轮左右开始趋于平稳; 训练到 400 轮会过拟合——「此时尽管模型的损失值较低,但是使用该模型进行实测时效果会变差」。

这是全书最有价值的一句经验:损失更低 ≠ 实车更好。 拆解必须留住。

13.4.5 部署(10.3.5)

训练完成 → 生成 model(结构)和 params(参数)两个文件
↓ 下载到电脑
MobaXterm 新建 SSH 会话 → IP 通常 192.168.1.254 → 连上 EdgeBoard
↓ 上传 model 和 params
改 config.py:模型路径 + 摄像头编码

跑巡航程序

(:233:249)

验证分两层(:251:267):先对静态图片预测转角并打印在图上,再实车路试。 书对偏差的态度很诚实:「无论何种模型,在应用时都难以获得 100% 的成功率」, 少数偏差「有可能是数据采集时出现的部分错误噪声图像对模型的训练结果造成了干扰」(:257)。

13.5 做法三:PaddleSeg + BisenetV2 语义分割(10.4)

三种分割任务的区分(:277):

任务干什么
语义分割对图像中每一个像素点做类别预测
实例分割目标检测 + 语义分割:在每个预测框里勾出对应的「实例」
全景分割语义分割 + 实例分割:既检出全部目标,又区分同类别中的不同实例

为什么选轻量模型 BisenetV2(:345:355): 语义分割要逐像素分类,运算量很大;减运算量只有两条路 —— 缩小图片(丢细节、伤精度) 或降低模型复杂度(削弱特征提取能力、也伤精度)。 BisenetV2 的解法是双分支:

  • 详细分支捕获精细的局部信息;
  • 语义分支获取全局上下文信息;
  • 最后用 BGA(双边引导聚合)层融合两支。

标注流程(10.4.1):LabelMe → Create Polygons 沿目标边缘画闭合多边形 → 选类别; Save Automatically 开、Save With Image Data 关; 背景若要手动标注类别必须写 _background_,否则格式转换出错; 有孔洞的目标要先标外轮廓再沿孔洞画(:303:315)。 然后用 PaddleSeg 的转换脚本转格式(会自动生成 annotations 文件夹), 再用切分脚本生成 train.txt / val.txt / test.txt,每行是「原图路径 空格 标注图路径」(:321:335)。 参考数据集:https://aistudio.baidu.com/datasetdetail/130677(:339)。

部署换了硬件:Jetson Nano,JetPack 4.6.1,Python 3.7.1, 要去飞桨官网附录里找与 JetPack 版本对应的预编译 whl 包(:379:393)。 安装验证的输出是「Your Paddle Fluid is installed successfully!」(:393)。 最后一句很关键:「借助推理输出的图像,辅以相关算法(如提取中心线),即可完成小车的自动巡航功能」(:409) —— 分割只给出车道线像素,从像素到转角这一步书没讲(见缺口 G12)。 还提到 Nano 性能不足时可做模型轻量化,指向 11.2.5 节(:409)。


14. 第 11 章 智能车竞赛目标检测任务的 CNN 模型设计与部署(text/12-ch11-11-cnn.txt,18.1k 字)

14.1 骨架

11.1 目标检测概述 两个子任务 / 挑战 / 两代算法 / 数据格式 / 评估指标
11.2 单阶段方法与轻量化 SSD → YOLO → V2 → V3;剪枝 / 蒸馏 / 轻量模块设计
11.3 数据集构建 采集 → 标注(LabelImg / EasyData) → 划分
11.4 模型构建与训练 PaddleDetection + YOLOV3-MobileNetV1
11.5 部署 EdgeBoard(要先 Docker 编译量化) / Jetson Nano(直接装)

14.2 目标检测是什么(11.1.1)

  • 两个子任务:物体定位 + 物体分类;不同场景侧重不同 —— 超市商品识别侧重分类;工厂消防检测侧重定位;医疗病变检测两者都要高(:15);
  • 智能车场景下的两种典型应用:识别可行驶道路和交通标志、识别静态与动态障碍物(:15);
  • 挑战一是图像质量:摄像头硬件成像能力;光照、拍摄角度、雨雪雾霾扬尘; 同一图像中不同对象的尺度、密集程度、遮挡程度(:19);
  • 挑战二是方法本身:传统方法可解释性好但适应能力差,样本增加时模型更复杂而精度不涨; 深度学习方法要大量样本和算力,但方便增删类别、适应性好、样本越多越准(:21:23)。

14.3 两代算法(11.1.2)

传统: 滑动窗口/边缘检测/选择性搜索出候选区 → Haar / 方向梯度直方图(HOG) / SIFT 等人工设计的特征 → 线性分类器/SVM 分类。经典算法:VJ、HOG、可变部件模型(:35)。

深度学习(2018 年前两分,2018 年后三分):

代表关键点位置
两阶段R-CNN → Faster R-CNN → Mask R-CNNR-CNN 是鼻祖:一阶段选择性搜索出稀疏的感兴趣区,二阶段深度模型分类;Faster R-CNN 用全卷积网络替代选择性搜索,解决 R-CNN 训练慢、内存需求大;Mask R-CNN 用 RoIAlign 替换 RoIPool 提精度:41:47
单阶段SSD 系列、YOLO 系列一个阶段内同时完成定位和分类:49
Anchor FreeCornerNet(2018)「从严格意义上来说,Anchor Free 算法也是一类单阶段目标检测算法」:39

取舍口径: 「两阶段目标检测算法具有更高的精度,但其检测速度难以满足实时性的要求。 单阶段……牺牲了些许精度,但其实时性的特点更受产业界青睐」(:51)。

14.4 数据格式与评估指标(11.1.3)

两种主流格式(:59):

  • PASCAL VOC:定义目录结构,一个 xml 对应一张图;
  • COCO(微软):整个训练集的标注信息都在一个 json 文件里

书还给了一条判断:「数据集格式并没有优劣之分……随着硬件处理能力和效率的提高, 因数据集格式而带来的效率差异已经不那么重要」(:61)。

复杂度指标(:67):

  • FLOPS(浮点运算数量)反映所需计算资源,只与模型本身相关;
  • FPS(每秒帧数)反映执行速度,由硬件、运行环境、编译速度、编程语言共同决定 —— 所以「使用 FPS 指标时,必须提供模型运行时的处理器型号、主频、内存容量、操作系统、软件版本、语言选择」。 这条口径很硬,值得留。

性能指标链条(:71:89):

TP / FP / TN / FN

准确率 Accuracy = 预测正确 / 总数
← 陷阱:正样本占 99% 时,全预测为正也有 0.99 的准确率(书给了这个具体例子)

精确率 Precision(查准率)= 正确预测的正样本 / 全部预测为正
召回率 Recall(查全率) = 正确预测的正样本 / 测试集里的正样本总数
← 「精确率和召回率在计算时分子相同、分母不同」

P-R 曲线(横轴召回率、纵轴精确率)
← 缺点:调参很难两头都高,且容易受正负样本分布影响

AP = P-R 曲线与横轴围成的面积(「数字比曲线图更能体现一个模型的好坏」)

mAP = 各类别 AP 的平均(多分类整体性能)

★ 书内错误 E4(要如实指出): :71 把四个术语写成 「②正样本识别为负样本(False Positive, FP)」「④负样本识别为正样本(False Negative, FN)」。 FP 和 FN 的中文说明反了。 正确是:FP = 负样本被识别为正样本;FN = 正样本被识别为负样本。 这条一定要在拆解里改正并注明,否则读者按书上的定义去推 Precision/Recall 会全错。

14.5 单阶段方法(11.2)

模型年份骨干关键设计位置
SSD2016VGG16(把最后 2 个全连接换成 4 个卷积层)6 个不同尺度的特征图上设候选框;浅层特征图带大目标信息、深层带小目标信息;损失 = 类别损失(Softmax)+ 位置损失(Smooth L1);用 NMS 剔重叠框:99:101
DSSDResNet101引入反卷积网络融合高低维信息;每个预测层后加预测模块:103
YOLO24 卷积 + 2 全连接「单阶段目标检测算法的开山之作」;首次把检测当成回归问题;输入 448×448,划 7×7 网格,每格预测 2 个框 ⇒ 共 7×7×2 个框;损失是五项平方和的加权叠加:109:117
YOLOV2DarkNet-19224×224 预训练后用 448×448 微调 10 个 epoch;每个卷积层后加 BN、去掉 Dropout;借鉴 Anchor 但改用 k-means 聚类(依据 IoU)选出 5 个聚类中心;13×13 特征图每格 5 个候选框、每框 5 个量(4 坐标 + 1 置信度);passthrough layer 融合高低分辨率特征图;多尺度输入训练(每 10 个 epoch 换一次尺寸,必须是 32 的倍数:320,352,…,608):123:135
YOLOV3Darknet53(残差网络)Darknet53 = 1 个经典卷积正则层 + 5 个残差连接模块;每个卷积正则层 = L2 正则卷积 + batchnorm + leaky-relu 三层;真值框尺寸先聚类再定锚框:141:145
YOLOV82023-01Ultralytics 开源,基于 YOLOV5 改进,「全新的骨干网络和损失函数」:147

14.6 ★ 神经网络轻量化(11.2.5)—— 这是「为什么这本书要讲部署」的关键一节

动机一句话: 「过多的参数量和巨大的算力要求也限制了算法在算力、内存有限设备上的部署」(:153)。 两条大路:对训练好的大网络剪枝或权重轻量化,或者直接构建更轻的网络

方法怎么做代价位置
结构性剪枝剪除的基本单元是神经元现有硬件上就能提速、省存储;但颗粒度大,对精度影响较大:159
非结构性剪枝剪除的基本单元是单个权重精度损失小;但产生稀疏权值矩阵,需要下层硬件和计算库支持才能提速:161
知识蒸馏Hinton 提出;用大而好的教师模型的监督信息指导精简的学生模型训练:165
轻量化模块设计代表是 MobileNet见下:169

MobileNet 三代(书讲得很细,:169):

  • V1:首次用深度可分离卷积代替标准卷积 —— 拆成两层: 深度卷积(对每个输入通道各用一个单通道轻量滤波器)+ 逐点卷积(算输入通道的线性组合构建新特征);
  • V2:加跨层连接;用逐点卷积先升维再用激活函数,「减少激活函数对特征的破坏」;
  • V3:综合 V1 的深度可分离卷积 + V2 的线性瓶颈逆残差 + MnasNet 的 SE 轻量注意力; 平均池化层前移、移除最后一个卷积层;引入 h-swish 激活;
  • 书的实用判断(很有价值): 「相比于 MobileNetV1,MobileNetV2 和 MobileNetV3 在精度方面的 提升有限,却增加了较多的计算量,在工程实际中,使用较多的是 MobileNetV1 网络」。

—— 这解释了 11.4 节为什么选 YOLOV3-MobileNetV1

14.7 数据集构建(11.3)—— 现场经验最多的一节

采集(:179:189):

  • 两种方式:摄像头逐张手动采(适合针对性补数据)、录视频再抽帧(适合大批量);
  • 「为了平衡光照变化对数据样本的影响和车速变化造成的图像拖影的影响,数据采集分多个时间段 和多种车速在赛道场景下进行」(:179)—— 这是全书关于数据集质量最实的一句;
  • 抽帧后「部分图片很模糊,手动筛选剔除非常模糊的图片」(:189);
  • 实例 11.1 的按键约定:p 拍照、q 退出、1—9 与 a—b 切换保存目录(:183)。

标注(:191:269):

  • 工具清单:CVAT、Labelme、VIA、LabelImg、百度飞桨 EasyData;
  • LabelImg:先在 data/predefined_classes.txt 写标签名,切到 VOC 格式, 每标一张产生一个 xml;快捷键 W 建区块、A 前翻、D 后翻; 「标注数据尽量不要包括多余的区域,防止后续可能出现的干扰」(:209);
  • EasyData(https://ai.baidu.com/easydata/):建数据集(标注类型「物体检测」、模板「矩形框标注」) → 上传 zip(<5GB)→ 加标签 → 标注 → 智能标注(用已有标注自动标其余样本)→ 导出 xml; 导出包里是 Annotations(1.xml 递增)和 Images(1.jpg 递增)两个文件夹(:249:263)。

划分(:273):Annotations / Image / classes.txt 三个同级项, 跑实例 11.4 自动划分训练/验证/测试,训练集默认占比 0.9

14.8 训练(11.4)

环境(:291): AI Studio;PaddlePaddle==2.2.2,Python==3.7,PaddleDetection==release/2.4; 模型选 YOLOV3-MobileNetV1

PaddleDetection 的定位(:283:285): 基于 PaddlePaddle 的目标检测端到端开发套件, 打通「数据准备 → 模型选型 → 模型训练 → 模型部署」全流程; 覆盖 2D/3D 目标检测、实例分割、人脸检测、关键点检测、多目标跟踪、半监督学习。

★ 五个配置文件各管什么(这一节最有用的知识,:317:347):

文件管什么
configs/datasets/voc.yml标签类别数、训练/验证/测试集路径、标签文件路径
configs/runtime.yml启用 GPU、日志输出步数、模型保存步数
configs/yolov3/_base_/optimizer_270e.yml训练轮次、初始学习率、学习率衰减方式、优化函数
configs/yolov3/_base_/yolov3_mobilenet_v1.yml预训练模型参数、主干网络、锚框尺寸
configs/yolov3/_base_/yolov3_reader.yml数据加载线程数、输入图片尺寸、批大小、各种数据增强

启动训练加 --eval 会在训练中同步评估并自动输出最佳模型(:355); 训练完把 best_model 由动态图转成静态图导出(:363)。

14.9 ★ 部署(11.5)—— 两条完全不同的路

EdgeBoard 路线(必须先编译) Jetson Nano 路线(直接装)
───────────────────────────── ──────────────────────────────
装 Docker Desktop(Windows10) 配好 JetPack 4.6.1 / Python 3.7.1
↓ 导入镜像 ↓
建 bdcodes 共享文件夹,解压 compiler.zip 去飞桨官网找对应 JetPack 版本的
↓ 挂载共享目录、启动容器 预编译 whl 包并安装
↓ 导入环境变量与路径 ↓
准备 model/ 和 image/ 两个文件夹 下载模型、改推理脚本里的
★ image 里图片必须 >50 张, 配置文件/模型/权重路径
且覆盖所有类别 ↓
↓ 改 compiler/config.json 跑推理脚本调摄像头
model_dir / shape / quantize_num
(quantize_num 默认 50,是
「离线量化依赖的图片数量」)
↓ 启动编译 → build/inference.zip
↓ 复制解压到板卡推理工程模型目录
↓ 改 config.json 的 model_dir
↓ 跑 y3run.py 调摄像头实时检测

(:381:473)

书最后给的一条实战提示(:475:479): 「可能会遇到摄像头帧率足够高,但开发板的处理性能不足,导致识别卡顿的情况」—— 对策一是训练阶段就选与硬件性能匹配的轻量模型,对策二是推理程序性能调优和模型轻量化转换(指回 11.2.5)。


15. 全书主线(通读之后才排得出来的)

这本书的主线不是「学 Python」,也不是「学深度学习」,而是:

让一辆算力有限的小车,靠一个摄像头,自己把赛道跑完 —— 从零基础一路搭到这件事上。

一条从头贯到尾的推理链:

① 要让车自己跑,得先能告诉计算机怎么做事
↓ 于是要一门语言(第 1 章:为什么是 Python)
② 告诉计算机怎么做事,先得学会「输入—处理—输出」地拆问题
↓ (第 2 章 IPO;引子就是 ReLU 和差速转向,一开始就把话题拉到本行)
③ 车要根据情况做不同的事、反复地做
↓ (第 3 章 分支与循环;例子是电池电压检查)
④ 同一段逻辑要被反复用,不能复制粘贴
↓ (第 4 章 函数与类;落点是把单层感知器写两遍——函数版和类版)
⑤ 车要处理的不是一个数,是成千上万张图和标签
↓ (第 5 章 组合数据类型;落点是「图片名→转角」的字典)
⑥ 这些数据在硬盘上,得读进来、切好、变成数组
↓ (第 6 章 文件/csv/json/PIL/OpenCV;落点是解压—提标签—乱序—切分四步)
⑦ 数据齐了,可以开始「让机器自己找规律」
↓ (第 7 章 numpy/pandas/matplotlib + 机器学习三步 + 一元线性回归全推导)
⑧ 一条直线不够用,得把简单单元叠起来
↓ (第 8 章 感知机 → DNN → 前向/激活/损失/优化/反向传播;落点是车辆三分类)
⑨ 图像上全连接会参数爆炸,得换一种连法
↓ (第 9 章 局部连接/权值共享/下采样 → CNN → 五个经典模型;落点是斑马线二分类)
⑩ 现在可以正面回答「怎么让车自己跑」了 —— 而且有三种答法
↓ (第 10 章 OpenCV 阈值 / CNN 回归转角 / 语义分割;这一章是真正的落点)
⑪ 光会跑还不够,还要认出路上的东西,并且要在一块算力有限的板子上实时跑
↓ (第 11 章 目标检测 + 轻量化 + 两条部署路线)

真正的落点是第 10 章。 第 11 章是并列的第二个任务(竞赛的另一半), 第 1—9 章全部是为第 10、11 章做准备。

贯穿全书的那个具体东西: 「一张前置摄像头拍的车前道路图 + 一个 [-1,1] 的转角值」。 它第一次出现在第 2 章(03-ch02-2-python.txt:39), 最后一次出现在第 10 章模型的 tanh 输出层(11-ch10.txt:211)。 建议整本拆解就用这一对数据当主走查的输入。


16. 章节该怎么切(按新词密度,不按字数)

原书 11 章不适合直接照搬。理由:前 6 章新词密度极低(都是通用编程概念), 后 5 章新词密度极高(第 8 章一章就有前向传播、激活函数、梯度消失、损失函数、 五种优化器、反向传播、链式法则、计算图……)。照原章序拆,前面注水后面挤爆。

建议切成 8 章 + 总纲:

我们的章讲什么对应原书为什么这么切
index 总纲这本书回答什么、全书一条主线、章节地图、覆盖与不覆盖、我们的判断全书
01 比赛长什么样赛场 600×480cm、车道 50cm、四电机差速+麦轮、EdgeBoard、两个任务(巡航=回归 / 检测)、竞赛与本书的关系;并在这里把「一张图 + 一个 [-1,1] 转角」这对主走查数据立起来第 1 章 §1.2、第 10 章 §10.1读者不知道比赛长什么样,后面全读不懂。原书把这些拆在头尾两处,应当合并前置
02 为什么是 Python,以及它怎么被用起来编译/解释、动静态类型、IPO、缩进/标识符/赋值/input/print/eval、库引用、计算生态与「胶水语言」、pip、标准库 vs 第三方库第 1 章 §1.3、第 2 章 §2.1—2.2、第 7 章 §7.2原书把「语言分类」放第 1 章、「计算生态」放第 7 章,中间隔了 5 章,其实是一件事
03 数据怎么进到程序里数字/字符串/格式化 → 列表/元组/字典/集合 → 文件读写与句柄指针 → 一维/二维(csv)/高维(json) → 解压—提标签—乱序—切分四步第 2 章 §2.3、第 5 章、第 6 章 §6.1—6.2三章都在讲同一件事:把外面的数据变成程序里的结构。合并后新词密度正好
04 图像在计算机里是什么像素与灰度值、二维数组、三通道、PIL vs OpenCV(RGB vs BGR)、缩放/裁剪/通道分离/几何变换、GRAY/BGR/HSV 三个色彩空间第 6 章 §6.3—6.4单独成章。它是第 9、10 章的地基,压在「文件」那一章里会被淹没
05 让机器自己找规律代码复用 → 函数 → 类 → 单层感知器(函数版/类版) → 机器学习三步、任务分类、学习方式分类 → 一元线性回归三版损失函数 → 梯度下降与学习率 → 智能车路径拟合第 3 章、第 4 章、第 7 章 §7.4—7.5第 4 章的感知器和第 7 章的线性回归本来就是一件事的两个说法(书自己说「单层感知器可以简单理解为一个线性回归模型」),合并讲最省力
06 从一个神经元到一张网DNN 结构 → 前向传播走查 → 激活函数(为什么必须非线性 / 梯度消失 / ReLU 及其死区)→ 损失函数两大类 → 优化器演进链 → ★ BP 完整数值走查 → 计算图 → 三个框架 → 深度学习通用五步 → 车辆三分类第 8 章单章内容最多,但拆开会切断 BP 走查。用「小节」拆:一节一个机制,BP 走查独占两节
07 图像为什么不能用全连接参数爆炸算账 → 局部连接/权值共享/下采样 → 卷积五级(一维→二维→多核→多通道→多通道多核)→ 池化与感受野 → LeNet/AlexNet/VGG/GoogleNet/ResNet 演进 → 斑马线二分类第 9 章原样保留,它本身结构就好
08 让车跑起来:同一个任务的三种答法三条路线并列对比(OpenCV 阈值 / CNN 回归 / 语义分割):各自的数据要多少、算力要多少、调什么、什么时候该选哪一条;巡航 CNN 逐层尺寸走查;为什么几何增强在这里不能用;300 轮 vs 400 轮的过拟合教训;两套部署流程第 10 章全书落点。必须按「三条路线的取舍」重组,不能按书的节序流水账
09 认出路上的东西,并塞进一块小板子目标检测两个子任务 → 两代算法 → TP/FP/TN/FN 与 P/R/AP/mAP(并改正书里的错) → SSD/YOLO 系列 → 剪枝/蒸馏/MobileNet → 数据集构建现场经验 → PaddleDetection 五个配置文件 → EdgeBoard 编译量化 vs Jetson Nano 直装第 11 章原样保留

被整体移出的内容(要在总纲的「不覆盖什么」里写明):

  • 第 1 章的中国 AI 发展史与政策文件罗列(约整章 1/3);
  • 各章的思政插入段(循环像人生、考研要有预案、YOLO 像人要不断学习……);
  • 所有 API 手册式的表格(math 44 个函数、turtle 各类函数、numpy/pandas 方法清单、 字符串 43 种方法)—— 这些在书里就是图片,而且属于「查文档就有」;
  • jieba / wordcloud 两节(与主线无关,是通用 Python 教材的标配内容)。

17. ★ 缺口清单:书没讲透、需要补外部来源的地方

先翻书架的结果:12 个缺口里有 6 个在我们自己的书架上就有现成拆解,不必上网。

#缺口书里怎么说补什么 · 从哪儿补
G1Hinton 2006 论文名与正文对不上正文说 2006 年 Hinton 发表「Learning Mul-tiple Layers of Representation」(02-ch01.txt:51)书自己的参考文献 [16] 写的是 HINTON G E, OSINDERO S, TEH E W. A fast learning algorithm for deep belief nets, Neural Computation, 2006, 18(7):1527-1554(13-fm.txt:35)。正文与参考文献不一致,如实指出;「Learning multiple layers of representation」另有其文(Hinton, Trends in Cognitive Sciences),年份需外部核实
G2「深度学习之父」这个称号书直接给 Hinton(02-ch01.txt:51)我们书架有整本讲这段历史的:book=genius-makers §03-survivors(2006 年底 NIPS 演讲、「深度学习」这个名字的品牌重塑)
G3AI 要素是三个还是四个:11 四个(知识/数据/算法/算力),:55 三个(算法/算力/算料)书内不一致,如实指出即可,不必外补
G4为什么必须多层 —— 书讲了感知器也讲了 AI 低谷,但没连起来第 1 章讲低谷、第 4/8 章讲感知器,中间断了1969 年 Minsky & Papert《Perceptrons》与异或问题。 我们书架讲透了:book=genius-makers §02-winter-and-backprop(「明斯基的书证明的是『单层网络学不会异或』,而不是『神经网络不行』」)
G5PID 控制器只出现在第 4 章习题(05-ch04.txt:377:387),正文零讲解;第 10 章习题选择题的答案又是「PID 控制」(11-ch10.txt:425)第 10 章从「预测出转角」到「电机真的转起来」这一段是空的。需要补一段 PID 基础(比例/积分/微分各管什么、位置式 vs 增量式)。书架上没有,属 ④ 类通用知识
G6ReLU 为什么好第 2 章只给定义(03-ch02-2-python.txt:33)第 8 章自己回收了(梯度消失,09-ch08.txt:83)。不是外部缺口,是拆解的顺序问题 —— 我们把定义和理由放在一起讲即可
G7「静活值」05-ch04.txt:163 写「静活值函数 lr()」,第 8 章写「净活值 neth1」(09-ch08.txt:193)第 8 章用的是「净活值」,第 4 章的「静活值」是错字。书内自证,不必外补
G8wordcloud 安装命令印成了 jieba06-ch05.txt:279如实指出,给正确命令 pip install wordcloud(④ 类)
G9梅森旋转「不适用于加密目的」只给结论04-ch03.txt:165可补一句原因(状态可从有限输出反推),④ 类;或者干脆不展开
G10EdgeBoard 是什么全书当成已知(02-ch01.txt:185、第 10/11 章反复出现),从没解释已查(③ 类): 百度面向嵌入式/边缘场景的 AI 方案,基于赛灵思 Zynq(ARM + FPGA)架构;赛事用的 FZ3 基于 XCZU3EG,FZ5 基于 XCZU5EV(约 2.4 TOPS);Paddle Lite 调底层驱动调度 FPGA,FPGA 上的算子以 FP16/NHWC 输入输出,不支持的算子回落到 ARM 端跑。这正好解释了第 11 章那个莫名其妙的 Docker 编译 + quantize_num=50 离线量化步骤。来源:PaddlePaddle Lite FPGA 部署文档 https://www.paddlepaddle.org.cn/lite/v2.11/demo_guides/fpga.html、百度 AI 开放平台 EdgeBoard 页 https://ai.baidu.com/tech/hardware/deepkit(查阅于 2026-08-29)
G11「用简单函数组合出复杂函数是有理论支撑的」—— 但没点名是哪条定理09-ch08.txt:53 只举了傅里叶变换和泰勒展开当类比指的是通用逼近定理;书自己的参考文献 [15] 就是 CYBENKO G. Approximation by superpositions of a sigmoidal function, 1989(13-fm.txt:33),参考文献里有,正文没接上。我们书架讲透了这条以及它的边界:book=dive-into-deep-learning §06-mlp(「能表示 ≠ 能学到」)、book=deep-learning-with-pytorch-training-and §06-neural-networks-and-nn
G12从分割结果到转角10.4 节最后一句「辅以相关算法(如提取中心线),即可完成小车的自动巡航功能」(11-ch10.txt:409)书就此打住,整条控制链断在这里。要么补一段(与 G5 的 PID 合并讲),要么在「边界与局限」里如实写「书没交代」
G13罗森布拉特提出感知器的年份第 4 章写 1957(05-ch04.txt:143)参考文献 [14] 是 ROSENBLATT F. 1958, Psychological Review(13-fm.txt:31)。两个年份都有出处(1957 康奈尔技术报告 / 1958 期刊论文),如实说明即可,不算错
G14CNN 的更完整讲法第 9 章讲得已经不错,但没有反向传播在卷积层里怎么走、没有 BN 的机制、没有现代检测器需要时挂到我们书架的邻居上:book=dive-into-deep-learning §08-cnnbook=deep-learning-with-python-2e §08-convnetsbook=shen-du-xue-xi-quan-shu §06-cnn§08-object-detectionbook=deep-learning-crash-course §05-convolutions

18. 书内错误汇总(拆解里必须改正并注明的)

#位置书里写的实际严重程度
E412-ch11-11-cnn.txt:71「正样本识别为负样本(False Positive,FP)」「负样本识别为正样本(False Negative,FN)」FP 和 FN 的说明互换了。 FP = 负样本被判为正;FN = 正样本被判为负 —— 照此推 Precision/Recall 会全错
E110-ch09.txt:119LeNet 是 Yann LeCun 1988 年提出书自己的参考文献 [17] 是 1998 年
E210-ch09.txt:129同一段里先说 LeNet S2 层「采用最大池化(max pool)」,后说「采用平均池化后,均值乘上一个权值参数加上一个偏置」前后矛盾;LeNet-5 用的是带权重与偏置的平均池化(子采样)
E506-ch05.txt:279wordcloud 安装写成 pip install jieba,验证写成 import jieba应为 wordcloud低(但很显眼)
E605-ch04.txt:163「静活值函数 lr()」第 8 章用的是「净活值」低(错字)
E702-ch01.txt:11 vs :55AI 四要素 vs 三要素书内不一致
E802-ch01.txt:51Hinton 2006「Learning Mul-tiple Layers of Representation」与本书参考文献 [16] 不一致

19. 三个声音(拆解里必须分开标的)

声音这本书里长什么样例子
技术内容默认反向传播走查、CNN 三大特点、模型逐层尺寸
编者的价值判断 / 思政段落教材的规定动作,与技术论证无关「循环就像我们每天工作学习」(04-ch03.txt:35)、「考研失败要有预案」(:143)、「简单的事情重复做就会成为专家」(08-ch07-7-python.txt:435)、「YOLO 不断改进,我们每个人也是如此」(12-ch11-11-cnn.txt:149)、「相信飞桨会为我国自主产权的人工智能技术发展奠定更好的基础」(09-ch08.txt:337)、第 1 章 §1.1.2 整节
竞赛主办方的口径赛题规则、指定平台与硬件必须用 PaddlePaddle、必须用 EdgeBoard、AI Studio 是指定训练平台
我们判断块见下

我们大概会写的几条判断(留给写正文的人,现在只是候选):

  1. 这本书的技术密度集中在第 7—11 章,前 6 章是通用 Python 教材,可读性好但可替代性极高;
  2. 它的不可替代性在于「同一个任务三种做法 + 两条真实部署路线」,这在通用深度学习书里几乎找不到;
  3. 它把代码全放进图片(以及配套只给 AI Studio 链接),使得书本身无法脱离网络使用 —— 这既是版式选择也是编者的教学设计(配 MOOC + 视频 + 在线项目);
  4. 第 11 章的 TP/FP/FN 定义错误说明这本书缺少一轮技术校对,引用它的具体定义时要留心。

20. 篇幅与工作量估计(给写大纲的人)

  • 原书 161k 字符,其中可用于拆解的技术正文约 100k(扣掉习题、思政、政策罗列、API 表格图注);
  • 按样板 2.15 倍的比例,拆解总量应在 20 万字符上下,9 章 + 总纲,平均每章 2 万字符;
  • 不平均分配:01/02/03 各 1—1.5 万(概念少),06/07/08 各 2.5—3 万(机制最密),09 约 2.5 万;
  • 主走查建议贯穿全书用同一对数据:「一张 128×128 的车前道路图 → 一个 [-1,1] 的转角」, 第 06 章借 BP 那 10 个参数走小网络,第 07 章借参数爆炸算账,第 08 章走逐层尺寸表。