跳到主要内容

塞进一块小板子:数据集、训练与两条部署路线

这一章讲三件事: 一个真实数据集是怎么攒出来的(有全书最实的一句现场经验); 配置一个检测模型其实只要改五个文件; 以及两条部署路线 —— 同一个模型,一条装个包就跑,另一条要多做六件事。 它在全书链条里的位置是最后一级台阶,也是全书唯一讲「模型怎么真的跑在硬件上」的地方。 这一章的主走查是本章第 4 节训出来的那个 YOLOV3-MobileNetV1,同时走两条部署路 (它的检测头就是第 15 章讲的 YOLO 那一路,骨干见第 6 节)。 遇到的生词都在当场解释。

1. 顶层全景

书给了整条流程,这一章就是照它走1:

数据采集 → 数据标注 → 模型构建 → 模型训练 → 模型压缩 → 模型部署
│ │ │ │ │ │
第 2 节 第 3 节 ├── 第 4 节:五个配置文件 ──┤ │
第 5、6 节 第 7、8 节

图说:注意这条链比第 09 章那「五步固定动作」多了一环 —— **模型压缩**。
它是被最后一环(部署到一块算力有限的板子上)倒逼出来的。
**这就是全书那条主线最后一次现身:边缘部署反过来决定前面每一步。**

2. 数据采集:全书最实的一句现场经验

现象先行:采数据不就是多拍点图吗

书给了两种采法2:

采法怎么做适合什么
手动逐张拍键盘控制车走,按 p 拍照保存,按 q 退出,按 1—9 和 a—b 切换保存目录对特定场景下的特定目标做针对性补充
录视频再抽帧拍一段视频,再跑一个程序按指定间隔从视频里截图大批量构建数据集

抽完帧还有一道人工:书说部分图片会很模糊,要手动筛选剔除非常模糊的图片3

那句最实的话

为了平衡光照变化对数据样本的影响和车速变化造成的图像拖影的影响, 数据采集分多个时间段和多种车速在赛道场景下进行2

这一句里有两个独立的决定,拆开看:

① 分多个时间段采 ── 治**光照变化**
上午的光、下午的光、开灯和关灯,同一块地图布颜色是不一样的
(第 12 章那条路的死穴正是这个 —— 它治不了,只能重调阈值;
这里换了个治法:**把变化本身喂给模型**)

② 分多种车速采 ── 治**图像拖影**
车快的时候,快门期间车已经挪了一段,拍出来的图是糊的
**只用慢速采的数据训出来的模型,一到比赛的速度就懵**

图说:这两条都不是「多采一点」,是**把将来会遇到的变化提前放进训练集**。
和第 15 章那句「图像质量决定准确性的上限」是同一件事的两端 ——
那边说图糊了模型救不回来,这边说**那就让模型提前见过糊的图**。
(「快门期间车挪了一段」这个机理是我们补的;书只说了「车速变化造成的图像拖影」。)

3. 标注:两种工具,以及一条反直觉的口径

先把「标注」这个词钉一下:给每一份原始数据配上正确答案 —— 这里就是在图上画一个框、并说清框里是什么。 书给的定义是:把原始数据用标签或注释的方式进行加工处理, 以便监督学习算法能够识别、分类或预测4

一条反直觉的口径:框要画小,不要画大

这是这一节最值钱的一句,而且和直觉相反:

注意标注数据尽量不要包括多余的区域,防止后续可能出现的干扰5

为什么直觉是反的(我们补的解释): 人会觉得「框大一点保险,别把目标切掉了」。但模型学的是框里的东西。 框大了,框里那圈背景也会被当成「这个类别的特征」的一部分。 下次背景换了,它就认不出来了。

书还给了三个快捷键:W 建区块、A 向前翻、D 向后翻5。 —— 这种细节只有真标过几千张的人才会写。

两种工具的分工

书详细讲了两种6:

工具特点适合
LabelImg(本地软件)先在一个文件里写好标签名,切到 VOC 格式;每标一张产生一个 xml 文件小批量、要精修
EasyData(在线平台)建数据集(标注类型选「物体检测」、模板选「矩形框标注」)→ 上传压缩包(小于 5GB)→ 加标签 → 标注 → 智能标注 → 导出大批量

「智能标注」是这两者最大的差别,书给的说法是: 根据已有的标注智能标注其余样本,极大地减轻数据标注的工作量7

说人话(我们补):你先手标一小批,平台拿这一小批训一个粗模型, 再让它去把剩下的自动标了,你只需要检查和修正。 这是把第 14 章那个「上万张一张张画」的成本砍下来的主要办法。

导出的包里是两个文件夹8:Images(图像,从 1.jpg 递增) 和 Annotations(xml 标注文件,命名与图像依次对应,从 1.xml 递增)。

划分:三个东西摆好,跑一个脚本

书给的做法很具体9:

新建两个同级文件夹和一个同级 txt:
Annotations/ 放标注结果 xml
Image/ 放原始图像
classes.txt 写上所有标签名

跑划分程序 ⇒ 自动切出训练集、验证集、测试集
**训练集在总数据集中的默认占比是 0.9**(可以改)

最后把生成的 txt、图片、标注一起压成一个包,这就是最终用于训练的数据集。

注意这里出现的又是三个集合 —— 和第 14 章一样。 第 09 章讲过它们的分工:验证集用来决定什么时候停,测试集只在最后用一次。

4. 训练:真正要动的只有五个文件

这是本章第一个承重点,而且它是这一章最实用的一段。

现象先行:训练一个检测模型要写多少代码

答案是:一行都不用写。

书用的是一套端到端开发套件(PaddleDetection)。书给的定位10:

它提供了丰富的模型组件和测试基准……帮助开发者实现 数据准备、模型选型、模型训练、模型部署的全流程打通

「端到端开发套件」就地解释: 一套把整条流程都封装好的工具箱, 你不写模型代码,只填配置文件。 它支持的方向很广:2D/3D 目标检测、实例分割、 人脸检测、关键点检测、多目标跟踪、半监督学习等11

书给的环境和选型12:框架 2.2.2、Python 3.7、套件 release/2.4; 模型选 YOLOV3-MobileNetV1 —— 骨干网络是 MobileNetV1,检测头是 YOLOV3。 为什么是这个组合,第 6 节讲。

五个配置文件各管什么

书的口径是:用户仅需根据项目实际情况简单修改训练用参数文件13下面这张表就是这一节的全部干货 —— 看懂它就等于看懂了训练配置。

文件管的事里面有什么你多半要动的
① 数据集标签类别数量、训练集路径、验证集路径、测试集路径、标签文件路径14类别数(赛道上有几种标志)和几个路径
② 训练环境启用 GPU 训练、日志(程序一边跑一边往外打的运行记录)每隔几步输出一次、模型每隔几步存一次15一般不动
③ 训练过程训练轮次(就是第 09 章那个「轮」:整个训练集完整过一遍算一轮)、初始学习率、学习率的衰减方式、优化函数16轮次和学习率 —— 这是最常调的一个文件
④ 模型结构预训练模型的参数、模型的主干网络锚框的尺寸17换骨干、调锚框
⑤ 数据加载数据加载的线程数、模型输入图片的尺寸每批次图片的数量、各种数据增强方法18输入尺寸和批大小 —— 板子扛不住就往下调

④ 里那个「锚框的尺寸」,就是第 15 章讲的那个东西 —— 事先摆好的候选框,模型只学「把它往哪儿挪」。 第 15 章讲过它可以用聚类从训练集里自动算出来,而这里它是一个你可以手填的配置项。

「预训练模型」就地解释: 别人已经在一个大数据集上训好的一套参数, 你拿过来当起点,而不是从随机数开始。 好处是又快又准 —— 认边、认角这些底层本事是通用的,不必每个项目重学一遍。(补充:不在书里,来自通用知识。)

启动训练时的一个小开关

书给了一句很实用的话:加上 --eval 参数,会在训练过程中同时评估模型, 自动输出最佳模型19

为什么这个开关值得记(接第 13 章那个教训): 第 13 章那条经验是「训到 400 轮损失更低但实车更差」。 --eval 做的事正是:每训一段就用验证集考一次,把考得最好的那一版单独存下来。 这样即使你训过了头,最好的那一版也没丢。(这一句关联是我们补的。)

训完要转一次格式

训练结束后,把最佳模型导出 —— 书说的是「将动态图模型转换为静态图模型」20

这两个词就地解释(书没解释):

动态图静态图
什么时候搭那张计算图(第 08 章那张)每跑一次现搭一次先把整张图定死,再喂数据
好处好调试 —— 中间结果随时能打印出来看好优化、好部署 —— 结构固定了,才能提前编译和加速

⇒ 所以训练用动态图、部署转静态图,是一条通例。 (这一段是我们补的通用知识;书只给了「动态图转静态图」这个操作。)

5. 模型太大怎么办:四条路,而且各有代价

这是本章第二个承重点。

动机一句话

随着神经网络层数的不断加深,预测精度不断提高,然而 过多的参数量和巨大的算力要求也限制了算法在算力、内存有限设备上的部署21

这正是第 11 章那条演进线的另一面: 那一章讲的是「怎么变强」, 这一节讲的是「变强之后怎么塞得进去」。

书把办法分成两大类21:对训练好的大网络做减法,或者直接构建更轻、更紧凑的网络

做减法那一类书叫「剪枝」,字面意思:把模型里冗余的、不关键的那部分参数直接删掉, 就像给树剪掉多余的枝条。书的说法是「关注模型参数中的冗余性,去除冗余的参数和不关键的参数」。

四条路,以及各自的代价

剪掉/换掉什么好处代价
结构性剪枝剪除的基本单元是神经元在现有硬件条件下就能实现明显的推理加速以及存储优势颗粒度较大,往往对精度产生较大影响22
非结构性剪枝剪除的基本单元是单个权重精度损失更小会产生稀疏的权值矩阵,需要下层硬件和计算库有良好的支持才能实现加速23
知识蒸馏一个字都不剪,另起一个小网络,让大模型去教它小网络能达到更好的性能要先有一个训好的大模型
轻量化模块设计从一开始就设计一个轻的不用后处理得会设计(第 6 节)

前两条那个对照值得单独讲清楚,因为它藏着一条重要的工程直觉:

结构性剪枝:整个神经元拿掉
⇒ 剩下的还是一张**规整的**网,该多厚就多厚,只是薄了一圈
⇒ **任何硬件跑起来都直接变快**
✗ 但一刀下去砍掉的东西多,精度掉得也多

非结构性剪枝:只把某些权重清成 0,神经元还在
⇒ 剩下的是一张**满是窟窿的**网(书叫「稀疏的权值矩阵」)
✓ 精度掉得少 —— 因为砍得精细
✗ **但普通硬件不会因为某个数是 0 就跳过它,照样乘一遍**
⇒ **参数是少了,速度一点没快** —— 除非底层库和硬件专门支持

图说:**这是一条通用的工程直觉 ——「理论上省了」和「实际跑得快」是两回事,
中间隔着硬件认不认。** 第 7 节那个离线量化也是同一条道理的另一个例子。
(这段拆解是我们补的;书给了两条的定义和代价,没有把这层直觉点破。)

知识蒸馏这条,书给了它的来历和核心思想24:

知识蒸馏由 Hinton 提出,核心思想是知识在教师模型和学生模型之间的迁移。 教师模型网络设计复杂、参数量庞大、表现力更强;学生模型结构精简。 知识蒸馏就是利用性能更好的教师模型的监督信息,来指导紧凑的学生模型训练。

说人话: 不让小模型直接去啃标准答案,而是让它去学大模型的答题过程。 大模型给出的是「这张图 85% 像斑马线、10% 像路口标线、5% 像别的」—— 这里面比一个「是斑马线」的标准答案多带了很多信息。 (这一句解释是我们补的;书只说了「监督信息」。)

6. MobileNet:把一次卷积拆成两层

轻量化模块设计着眼于什么

书给的三处25:卷积核尺寸、输出卷积通道数、瓶颈层 —— 第 11 章讲 ResNet 的 Bottleneck 时,那个「先降后升」就是瓶颈层的一个例子。

代表性的网络结构是 MobileNet。

V1 的招:深度可分离卷积

这个名字要留住 —— 你出门在任何一个轻量模型的文档、任何一份框架 API 里都会撞见它。

书给的做法:把标准卷积拆分成两个分卷积25:

第几层名字干什么
第一层深度卷积对每个输入通道应用单通道的轻量级滤波器
第二层逐点卷积计算输入通道的线性组合,构建新的特征

这两层合起来的名字,就叫深度可分离卷积。

拆开对照第 10 章讲的标准卷积:

标准卷积(第 10 章讲的那种):
一个核立方体**同时**干两件事 ——
① 在平面上扫(认出「这里有一条边」)
② 把所有通道的结果加起来(把几个通道的信息混在一起)

深度可分离卷积:**把这两件事拆开做**
① 深度卷积:每个通道各用一个 3×3 的单通道核,**各扫各的,不混通道**
② 逐点卷积:用 1×1 的核,**只混通道,不扫平面**
(1×1 卷积第 11 章讲 GoogleNet 时讲过:一个像素的视野都不加,只管调厚薄)

── 拿具体的数算一遍(这组数是我们为演示定的,书没给) ──

设定:输入 32 个通道,输出 64 个通道,核 3×3

标准卷积: 32 × 64 × 3 × 3 = **18 432** 个参数
(每个输入通道到每个输出通道,各配一个 3×3 的小方块)

深度可分离:
深度卷积:32 个通道各一个 3×3 单通道核 = 32 × 9 = **288**
逐点卷积:1×1,32 通道 → 64 通道 = 32 × 64 = **2 048**
─────────────────
**2 336**

18 432 → 2 336,**降到原来的八分之一**

图说:降幅的来源一句话 —— **原来「扫平面」和「混通道」是乘在一起的,
拆开之后变成了加在一起。**

后面两代,以及一条很实用的判断

书讲了 V2 和 V3 各自加了什么25:

加了什么
V2增加了跨层连接(第 11 章 ResNet 那条直连);用逐点卷积先对输入特征升维,再在升维后的特征上用激活函数,减少激活函数对特征的破坏
V3综合三家:V1 的深度可分离卷积、V2 的线性瓶颈逆残差结构、以及另一个模型的轻量级注意力结构;把最后一步的平均池化层前移、移除最后一个卷积层;引入新的激活函数

然后书给了一条非常有价值的实用判断25:

相比于 MobileNetV1,MobileNetV2 和 MobileNetV3 在精度方面的提升有限, 却增加了较多的计算量,在工程实际中,使用较多的是 MobileNetV1 网络。

⇒ 这就是第 4 节那个 YOLOV3-MobileNetV1 里「V1」的由来。

判断(我们的,不是书里的):这一句是这一章最该带走的一条 —— 因为它示范了一种在这本书里反复出现、但很少被明说的判断方式: 「更新的那一版」不等于「你该用的那一版」。 第 11 章那条演进线上每一代都比上一代强,但那是在「不限算力」的前提下比的; 一旦加上「必须跑在这块板子上」,排序就重来一次。 如果错,会错在: 如果后来的框架针对 V2/V3 的那些算子做了专门优化 (轻量模型的实际速度非常依赖底层实现),那「计算量增加」不一定等于「跑得更慢」。 判据是:在这块具体的板子上,把三代各跑一遍,比 FPS —— 而这正是第 15 章那条口径要求的做法。

7. 两条部署路线:一条要多做六件事

这是本章第三个承重点,也是全书的收尾。

书把话说在前面

关于目标检测模型的部署,本节提供了两种部署方式,分别适用于 EdgeBoard 板和 Jetson Nano 开发板。 对于 EdgeBoard 板的部署,需要对训练过的模型进行编译,以便能够成功部署; 而对于 Jetson Nano 开发板的部署,读者可以直接跳转……无须进行模型转换过程26

同一个模型,一条路要先编译,另一条不用。这一节讲那条要编译的路多做了什么、以及为什么。

左边这条路:七步

书给的流程27:

① 装 Docker Desktop(书基于 Windows 10 讲)
「容器」就地解释:**一个装好了全套环境的、隔离的小盒子。**
编译工具链对系统版本很挑剔,装进盒子里就不必污染你自己的电脑。

② 导入镜像 —— 「镜像」就是那个盒子的模板文件

③ 建一个目录当**共享文件夹**(让盒子里外能互相看到文件),
把编译工具包解压进去,挂载共享目录、启动容器

④ 进容器,导入环境变量和相关路径

⑤ **准备工作:建一个目录,里面放 model 和 image 两个文件夹**
model 放导出的模型
image 放测试集里的图片 ——
⚠ **确保图片数量大于 50 张,并覆盖所有的类别**

⑥ 改配置文件里的三项:
model_dir —— 上一步那个目录
shape —— **模型输入尺寸,必须与模型实际尺寸保持一致**
quantize_num —— **离线量化依赖的图片数量,默认 50 张**

⑦ 启动编译 ⇒ 生成一个推理包,复制解压到板卡上的推理工程模型目录

然后才是真正的部署:装 Python 推理环境 → 把包放上去、把配置文件放进去 →
改配置里的 model_dir → 跑检测程序,调摄像头实时检测

右边这条路:三步

书给的流程28:

① 配好基础开发环境(JetPack 4.6.1、Python 3.7.1),
去官网找与 JetPack 版本对应的框架包并安装
(**这一步第 14 章讲过,同一块板子、同一件事**)

② 把训练好的模型下载到板子上,解压,
改推理脚本里的**配置文件、模型、权重参数三个路径**

③ 运行推理脚本,调摄像头

那 50 张图不是仪式:它是硬件逼出来的

书没有解释为什么要 50 张覆盖全类别的真实图片。 这一段是我们补的。

先把「量化」这个词讲清楚(补充:不在书里,来自通用知识):

模型里那些参数,训练时通常是「32 位浮点数」—— 每个数占 4 个字节,精度很高。
**量化就是把它们换成更省的格式**,比如 16 位浮点数(2 字节)甚至 8 位整数(1 字节)。

好处:占的内存小一半到四分之三,而且很多芯片算低精度数快得多。
代价:精度会掉一点。

**「离线量化」的意思是:不重新训练,直接拿训好的模型换格式。**
可换格式要知道一件事 —— **原来那些数大致落在什么范围**。
范围定窄了会截断,定宽了会不够精细。

⇒ **所以要拿一批真实图片跑一遍,统计每一层的数值实际落在哪个区间。**
**那 50 张图就是干这个用的** ——
「覆盖所有类别」是因为不同类别激发的数值分布不一样,漏了一类,那一类的范围就统计不到。

补充(不在书里):EdgeBoard 是百度面向嵌入式与边缘场景的 AI 方案, 它的板子采用「ARM 处理器 + 可编程逻辑芯片」的架构 —— 也就是说,除了一颗常规处理器,板子上还有一块可以被配置成专用电路的芯片。 模型要跑在那块专用电路上,而它收发数据用的是半精度浮点(16 位); 不被它支持的算子会退回到 ARM 那一侧跑。

这正好解释了左边那条路为什么要多做六件事: 模型必须先离线量化成那块芯片认的格式、并且把不支持的算子挑出来分流 —— 这件事没法在板子上现做,只能在编译阶段离线做完。 而 Jetson Nano 那一侧是常规的显卡架构,框架直接支持,所以装个包就能跑。

来源: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)。

判断(我们的,不是书里的):那 50 张图和整套 Docker 编译流程, 不是这套工具链做得繁琐,是这块板子的硬件架构决定的。 如果错,会错在: 如果后来的工具链把量化这一步也搬到了板上、或者做成了一键脚本, 那这六件事就只是当时的版本问题,不是架构问题。 判据是:换一个更新版本的部署工具,还需不需要准备那 50 张图。

8. 主走查:同一个模型,同时走两条部署路

这是本章的主走查。上面每个机制在它上面各占一步。

━━ 起点:本章第 4 节训出来的那个模型 ━━━━━━━━━━━━━━━━━━━

模型:YOLOV3-MobileNetV1(这个选型是本章第 4 节定的)
骨干 = MobileNetV1(第 6 节:深度可分离卷积,同一段参数从
**18 432** 降到 **2 336**,八分之一)
检测头 = YOLOV3(第 15 章:锚框 + 交并比 + 非极大值抑制)
训练:改了**五个配置文件**,加 `--eval` 跑,自动存下最佳模型
导出:动态图 → **静态图**

━━━━━━━━━━━━━━━━━ 分岔 ━━━━━━━━━━━━━━━━━━━━━━━━━━

左边:EdgeBoard 路线 右边:Jetson Nano 路线
──────────────────────────── ────────────────────────────
① 装 Docker Desktop ① 配好 JetPack 4.6.1
② 导入镜像 + Python 3.7.1
③ 建共享目录、解压工具包、
挂载、起容器 ② 去官网找**对应 JetPack 版本**的
④ 进容器,导入环境变量与路径 框架包,装上
⑤ 建 model / image 两个文件夹
**image 里放 >50 张真实图片,
而且要覆盖所有类别** ③ 把模型下载到板子上,解压
⑥ 改配置三项:
model_dir
shape(**要和模型实际尺寸一致**)
quantize_num(默认 **50**) 改推理脚本里的**三个路径**:
⑦ 启动编译 → 生成推理包 配置文件 / 模型 / 权重
→ 复制解压到板卡

再装 Python 推理环境、放配置、
改 model_dir、跑检测程序 跑推理脚本
──────────────────────────── ────────────────────────────
**七步 + 四步收尾** **三步**

━━ 那多出来的六件事,全是硬件逼出来的 ━━━━━━━━━━━━━━━━━

容器 / 镜像 / 共享目录 / 环境变量 / 50 张图 / 编译量化
↑ 它们服务的是同一件事:
**把模型改写成板子上那块专用电路认得的格式(半精度),
并把它不支持的算子挑出来退回常规处理器。**
而那 50 张图,是量化时用来**统计每一层数值范围**的样本(第 7 节)。

━━ 两条路都跑起来之后 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━

摄像头实时进图 → 模型吐框 → 非极大值抑制 → 画在屏幕上
⇒ 车认出了路上的东西。**全书到此结束。**

9. 板子跑不动怎么办:书给的两条对策,以及全书的收尾

书的最后一段,很实在

在实际运行中,可能会遇到摄像头帧率足够高,但开发板的处理性能不足,导致识别卡顿的情况29

书给了两条对策,而且它们落在完全不同的两端29:

对策落在哪一端具体做什么
① 训练阶段就选适合的模型结构设计端「选择与硬件性能相匹配的模型非常重要」—— 套件里有许多轻量级模型可选
② 推理程序性能调优 + 模型轻量化转换部署端指回第 5、6 节那四条路

这两条对策的顺序值得注意:书把「设计端」放在第一条。

合上全书那条主线

第 01 章说过一句话,当时你只能先记着:板子的算力约束反过来决定后面每一处模型设计。 这本书用四次兑现了它:

在哪怎么兑现的
第 13 章巡航模型不用 AlexNet,自己设计一个小的;输入压到 128×128 —— 理由就是板子算力有限
第 14 章分割那条路换了一块板子;而装框架必须对上系统版本 —— 部署环境本身就是约束
第 6 节(本章)骨干选 MobileNetV1 而不是更新的 V2、V3 —— 因为后两者计算量更大而精度提升有限
第 9 节(本章)板子跑不动时,第一条对策是回到训练阶段重选模型,不是在部署这一端硬调

判断(我们的,不是书里的):这四处合起来,就是这本书在整个书架上最值钱的东西。 通用的深度学习书讲到「模型训好了」就结束了,部署被当成一件事后的工程杂活; 这本书从第 01 章就把那块板子摆在桌上,让它一路反向约束前面每一个设计决定。

一句话收尾:边缘部署从来不是最后一步 —— 它从第一天起就在决定模型长什么样。

如果错,会错在: 如果算力在几年内变得足够便宜(板子上能直接跑大模型), 那这条约束就会松开,这本书的这套思路也就退化成一段历史。 判据是:同一块价位的车载板子,今天能不能跑得动第 11 章那些大模型 —— 目前还不能。

10. 作者的判断与证据

说法是哪一类
「数据采集分多个时间段和多种车速」有证据(现场经验),而且给了两个理由。 这是全书关于数据集质量最实的一句
两种采集方式的分工;抽帧后要人工剔除模糊图有证据(现场经验)
「标注数据尽量不要包括多余的区域」有证据,而且是反直觉的一条。 书给了理由(防止后续干扰)但没有展开机理
两种标注工具的分工;智能标注有证据(操作事实)
五个配置文件各管什么有证据,而且是这一章最实用的一段
四条轻量化路线各自的代价有证据,写得很平衡 —— 尤其非结构性剪枝那条「要硬件支持才提得了速」
知识蒸馏由 Hinton 提出有证据,与公开资料一致
深度可分离卷积拆成两层有证据(机制描述准确),但书没有给任何参数账,第 6 节那笔账是我们算的
「工程实际中使用较多的是 MobileNetV1」作者的实用判断,没有给对比数据。 方向可信,但它是经验不是测量
两条部署路线的完整步骤有证据(操作记录),完整可照做
那 50 张图、编译、离线量化书只给了操作,没有给任何理由。 第 7 节那段解释是我们补的外部资料 + 通用知识
板子跑不动的两条对策有证据,而且把设计端放在了第一条
「非结构性剪枝那条藏着的工程直觉」「动态图 vs 静态图」「预训练模型」「容器」不在书里,是我们补的

11. 边界与局限

  • 这一章对应原书 §11.2.5 与 §11.3—11.5。 §11.2.5(轻量化)按原书编号属于上一节,但它讲的是「怎么塞进板子」,和部署是同一件事, 所以我们把它放在这一章而不是第 15 章。
  • 书没有给这个检测模型的任何量化结果。 没有 mAP、没有 FPS、没有量化前后的精度对比 —— 而第 15 章刚刚定下「报 FPS 必须同时报环境」那条口径。 这一章一个 FPS 都没报。
  • 书没有解释离线量化是什么、那 50 张图干什么用。 只给了「默认 50 张」这个配置项。
  • 书没有给数据集的规模。 采了多少张、标了多少个框、有几个类别,一概没有。
  • 书没有讲标注质量怎么控。 多人分头标时口径怎么统一,一个字没提。 (补充:不在书里,来自通用知识。)
  • 书没有讲模型压缩这一环实际做了没有。 第 5、6 节讲了四条路, 但这个项目里除了「选 MobileNetV1」之外,有没有真的剪枝或蒸馏,书没说。
  • 书没有代码。 所有实例都在配套资源里,书里只有截图和命令行的图片。
  • 两条部署路线的步骤都绑死在特定厂商的工具链上。 换一家的板子,这一章要重写。 但那条主线(硬件反过来约束设计)是通用的。

12. 可带走的

全章主走查一行写完:

第 4 节选定的 YOLOV3-MobileNetV1(检测头是第 15 章讲的 YOLO 那一路, 骨干靠深度可分离卷积,同一段参数从 18 432 降到 2 336)→ 改五个配置文件、加 --eval 训练、导出时动态图转静态图左边:装容器 → 导镜像 → 挂共享目录 → 设好环境变量(告诉盒子里的程序去哪儿找工具)→ 备 50 张覆盖全类别的真实图 → 改三项配置(路径 / 输入尺寸 / 量化图片数 50)→ 编译 → 拷进板卡 → 改路径 → 跑; 右边:装对应版本的包 → 下载模型 → 改三个路径 → 跑。

同一个模型,一条路要多做六件事 —— 那六件事全是硬件逼出来的。

  1. 整条流程比第 09 章那五步多一环:模型压缩。 它是被最后一环倒逼出来的;
  2. 数据采集要分多个时间段、多种车速 —— 分时段治光照变化,变车速治图像拖影。 这不是「多采一点」,是把将来会遇到的变化提前放进训练集;
  3. 抽帧之后还有一道人工:把太模糊的挑出去扔掉;
  4. 标注框要画小,不要画大 —— 多出来的那圈背景会被模型当成这个类别的特征;
  5. 本地工具适合小批量精修,在线平台能用已标好的样本去自动标其余的 —— 这是把标注成本砍下来的主要办法;
  6. 训练一个检测模型一行代码都不用写,真正要动的只有五个配置文件: 数据集 / 训练环境 / 训练过程 / 模型结构(含锚框尺寸)/ 数据加载(含输入尺寸和批大小);
  7. --eval 这个开关会边训边评、自动存下最好的那一版 —— 正好接住第 13 章那个「训过头」的教训;
  8. 训练用动态图、部署转静态图 —— 前者好调试,后者好优化;
  9. 模型太大有四条路: 结构性剪枝(硬件直接受益,但伤精度)、 非结构性剪枝(精度损失小,但普通硬件不会因为某个数是 0 就跳过它)、 知识蒸馏(拿大模型的答题过程去教小模型)、直接设计轻量结构;
  10. 一条通用的工程直觉:「理论上省了」和「实际跑得快」是两回事,中间隔着硬件认不认;
  11. 深度可分离卷积 = 深度卷积 + 逐点卷积 —— 把「扫平面」和「混通道」拆开做, 原来是乘在一起的,拆开变成加在一起;
  12. 书的实用判断:工程实际中用得多的是 MobileNetV1,不是更新的 V2、V3 —— 「更新的那一版」不等于「你该用的那一版」;
  13. 两条部署路线差六件事,而那六件事全是为了同一件事: 把模型改写成板子上那块专用电路认得的格式。那 50 张图是量化时用来统计数值范围的;
  14. 板子跑不动时,书给的第一条对策是回到训练阶段重选模型,不是在部署端硬调;
  15. 全书的收尾:边缘部署从来不是最后一步 —— 它从第一天起就在决定模型长什么样。

13. 原文地图

主题原书章原文位置
整条流程:采集—标注—构建—训练—压缩—部署第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:175(搜「数据采集—数据标注—模型构建」)
数据采集分多个时间段和多种车速第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:179(搜「分多个时间段和多种车速」)
手动采图的按键;录视频抽帧;剔除模糊图片第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:183(搜「按p键拍摄并保存图片」) · text/12-ch11-11-cnn.txt:189(搜「手动筛选剔除非常模糊的图片」)
标注工具清单第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:195(搜「CVAT、Labelme」)
「标注数据尽量不要包括多余的区域」;三个快捷键第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:209(搜「尽量不要包括多余的区域」)
LabelImg 的用法:先写标签名、切 VOC 格式第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:203(搜「切换到VOC格式」)
EasyData:建集、上传(<5GB)、智能标注第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:227(搜「矩形框标注」) · text/12-ch11-11-cnn.txt:249(搜「智能标注功能」)
导出包里的两个文件夹第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:263(搜「Annotations」)
划分:三个东西摆好,训练集默认占比 0.9第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:273(搜「默认为0.9」)
开发套件的定位与覆盖范围第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:283(搜「端到端开发套件」) · text/12-ch11-11-cnn.txt:285(搜「多目标跟踪、半监督学习」)
环境版本;模型选 YOLOV3-MobileNetV1第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:291(搜「YOLOV3-MobileNetV1」)
五个配置文件各管什么第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:317(搜「简单修改训练用参数文件」) · text/12-ch11-11-cnn.txt:321(搜「标签类别数量」) · text/12-ch11-11-cnn.txt:327(搜「日志文件输出的步数」) · text/12-ch11-11-cnn.txt:331(搜「学习率的衰减方式」) · text/12-ch11-11-cnn.txt:337(搜「锚框的尺寸」) · text/12-ch11-11-cnn.txt:345(搜「每批次图片的数量」)
--eval 自动输出最佳模型第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:355(搜「自动输出最佳模型」)
导出:动态图转静态图第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:363(搜「动态图模型转换为静态图模型」)
轻量化的动机;两大类办法第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:153(搜「限制了算法在算力、内存有限设备上的部署」)
结构性剪枝 vs 非结构性剪枝的代价第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:159(搜「剪枝的颗粒度较大」) · text/12-ch11-11-cnn.txt:161(搜「稀疏的权值矩阵」)
知识蒸馏:Hinton 提出、教师与学生第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:165(搜「知识蒸馏由Hinton提出」)
深度可分离卷积;V2 与 V3;「工程实际中使用较多的是 MobileNetV1」第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:169(搜「深度可分离卷积」) · text/12-ch11-11-cnn.txt:169(搜「使用较多的是MobileNetV1网络」)
两条部署路线的分岔口第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:379(搜「无须进行模型转换过程」)
编译环境:Docker、镜像、共享文件夹、启动容器第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:399(搜「以充当镜像与Windows之间的共享文件夹」)
50 张覆盖全类别的图;配置三项;quantize_num 是离线量化依赖的图片数量第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:415(搜「确保图片数量大于50张」) · text/12-ch11-11-cnn.txt:423(搜「离线量化依赖的图片数量」)
编译产出与拷贝到板卡第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:429(搜「inference.zip」)
Jetson Nano 路线:装包、改三个路径、跑第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:455(搜「JetPack版本为4.6.1」) · text/12-ch11-11-cnn.txt:465(搜「权重参数等路径进行修改」)
板子跑不动的两条对策(设计端优先)第11章 智能车竞赛目标检测任务的CNN模型设计与部署text/12-ch11-11-cnn.txt:475(搜「开发板的处理性能不足」) · text/12-ch11-11-cnn.txt:477(搜「选择与硬件性能相匹配的模型」)

Footnotes

  1. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 175 段(text/12-ch11-11-cnn.txt:175,搜「数据采集—数据标注—模型构建」)。

  2. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 179 段(text/12-ch11-11-cnn.txt:179,搜「分多个时间段和多种车速」)与第 183、187 段(text/12-ch11-11-cnn.txt:183,搜「按p键拍摄并保存图片」)。「快门期间车挪了一段」这个机理是我们补的,书只说了「车速变化造成的图像拖影」。 2

  3. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 189 段(text/12-ch11-11-cnn.txt:189,搜「手动筛选剔除非常模糊的图片」)。

  4. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 193 段(text/12-ch11-11-cnn.txt:193,搜「数据标注是指」)。原文还说:数据标注的意义在于让未加标注的数据能够被监督学习算法等计算机程序所识别和应用。

  5. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 209 段(text/12-ch11-11-cnn.txt:209,搜「尽量不要包括多余的区域」)。同段给了三个快捷键。「为什么直觉是反的」那段解释是我们补的,书只给了「防止后续可能出现的干扰」这个理由。 2

  6. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 195 段(text/12-ch11-11-cnn.txt:195,搜「CVAT、Labelme」)、第 203 段(text/12-ch11-11-cnn.txt:203,搜「切换到VOC格式」)与第 227 段(text/12-ch11-11-cnn.txt:227,搜「矩形框标注」)。上传压缩包的大小限制在第 235 段。

  7. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 249 段(text/12-ch11-11-cnn.txt:249,搜「智能标注功能」)。「先手标一小批再让它自动标其余」这个机理是我们补的通用知识,书只说了「根据已有的标注智能标注其余样本」。

  8. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 263 段(text/12-ch11-11-cnn.txt:263,搜「Annotations」)。

  9. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 273 段(text/12-ch11-11-cnn.txt:273,搜「默认为0.9」)。

  10. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 283 段(text/12-ch11-11-cnn.txt:283,搜「端到端开发套件」)。

  11. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 285 段(text/12-ch11-11-cnn.txt:285,搜「多目标跟踪、半监督学习」)。

  12. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 291 段(text/12-ch11-11-cnn.txt:291,搜「YOLOV3-MobileNetV1」)。

  13. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 317 段(text/12-ch11-11-cnn.txt:317,搜「简单修改训练用参数文件」)。

  14. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 321 段(text/12-ch11-11-cnn.txt:321,搜「标签类别数量」)。

  15. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 327 段(text/12-ch11-11-cnn.txt:327,搜「日志文件输出的步数」)。

  16. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 331 段(text/12-ch11-11-cnn.txt:331,搜「学习率的衰减方式」)。

  17. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 337 段(text/12-ch11-11-cnn.txt:337,搜「锚框的尺寸」)。「预训练模型」是什么是我们补的通用知识。

  18. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 345 段(text/12-ch11-11-cnn.txt:345,搜「每批次图片的数量」)。

  19. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 355 段(text/12-ch11-11-cnn.txt:355,搜「自动输出最佳模型」)。它和第 13 章那条「训过头」的教训之间的关联是我们补的。

  20. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 363 段(text/12-ch11-11-cnn.txt:363,搜「动态图模型转换为静态图模型」)。动态图与静态图的差别是我们补的通用知识,书没有解释这两个词。

  21. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 153 段(text/12-ch11-11-cnn.txt:153,搜「限制了算法在算力、内存有限设备上的部署」)。原文把办法分成两大类:对训练好的大网络剪枝或权重轻量化,以及构建更轻型紧凑的网络。 2

  22. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 159 段(text/12-ch11-11-cnn.txt:159,搜「剪枝的颗粒度较大」)。

  23. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 161 段(text/12-ch11-11-cnn.txt:161,搜「稀疏的权值矩阵」)。第 5 节那段「理论上省了 ≠ 实际跑得快」的工程直觉是我们补的。

  24. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 165 段(text/12-ch11-11-cnn.txt:165,搜「知识蒸馏由Hinton提出」)。「大模型的答题过程比标准答案多带信息」这一句解释是我们补的通用知识。

  25. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 169 段(text/12-ch11-11-cnn.txt:169,搜「深度可分离卷积」;同段搜「使用较多的是MobileNetV1网络」)。第 6 节那笔参数账(18 432 → 2 336)是我们按书给的机制算的,书没有给任何数字。 2 3 4

  26. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 379 段(text/12-ch11-11-cnn.txt:379,搜「无须进行模型转换过程」)。

  27. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 399 段(text/12-ch11-11-cnn.txt:399,搜「以充当镜像与Windows之间的共享文件夹」)、第 415 段(text/12-ch11-11-cnn.txt:415,搜「确保图片数量大于50张」)、第 423 段(text/12-ch11-11-cnn.txt:423,搜「离线量化依赖的图片数量」)与第 429 段(text/12-ch11-11-cnn.txt:429,搜「inference.zip」)。「容器」「镜像」的解释以及量化是什么,是我们补的通用知识 —— 书只给了操作步骤。

  28. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 455 段(text/12-ch11-11-cnn.txt:455,搜「JetPack版本为4.6.1」)与第 465 段(text/12-ch11-11-cnn.txt:465,搜「权重参数等路径进行修改」)。

  29. 出处:「第11章 智能车竞赛目标检测任务的CNN模型设计与部署」第 475 段(text/12-ch11-11-cnn.txt:475,搜「开发板的处理性能不足」)与第 477 段(text/12-ch11-11-cnn.txt:477,搜「选择与硬件性能相匹配的模型」)。第 479 段把第二条对策指回了轻量化那一节。 2