吴恩达《深度学习》之看懂 YOLO 目标检测的“鹰眼”直觉
今天我们来拆解一个让整个计算机视觉界“速度飙升”的传奇算法——YOLOYou Only Look Once目标检测。在 YOLO 诞生之前目标检测比如在一张图里同时框出猫、狗和汽车的传统流派如 R-CNN 系列是非常笨重的。它们通常分为两步第一步用各种复杂的算法在图像上密密麻麻地推荐几千个“可能包含物体的候选区域”第二步把这几千个区域挨个裁剪下来像喂给普通分类网络一样一个个去判断里面是什么。这种方法虽然准确但慢得让人绝望。每看一张图网络都要“看好几千次”。而 YOLO 的作者约瑟夫·雷德蒙Joseph Redmon说“人类看一眼照片就能瞬间知道里面有什么、在哪里。为什么神经网络不能只看一次You Only Look Once”核心知识点直觉解释将图像划分为网格通过单次卷积网络前向传播同时预测所有物体的类别和精确边界框实现实时检测。数学核心每个网格输出目标向量y[pc,bx,by,bh,bw,c1,c2,c3]y [p_c, b_x, b_y, b_h, b_w, c_1, c_2, c_3]y[pc​,bx​,by​,bh​,bw​,c1​,c2​,c3​]。常见变体及适用场景使用 Anchor Boxes处理一格多物适用于自动驾驶、视频监控等需要实时反馈的场景。现在。我们继续用最爽快的物理直觉把 YOLO 这一眼看穿世界的底层逻辑彻底剥开。第一步把图像切成“地盘分明”的网格为了实现“只看一次”YOLO 在拿到一张图片后第一件事就是做空间切分。提问假设我们把一张普通的图片像切豆腐一样切成一个S×SS \times SS×S例如19×1919 \times 1919×19的网格Grid。现在有一辆汽车恰好停在图片中间。这辆车的中心点Center Point不偏不倚刚好落在了第 (row 9, col 9) 的那个小网格里。请问按照 YOLO 的霸道规矩整张图里这么多网格应该由哪一个网格来负责把这个完整的汽车给框出来并识别出来解析答案是物体的中心点落在哪个网格那个网格就必须认领这个物体成为它的“专属负责人”。其他网格哪怕擦到了汽车的边也不需要操心。第二步解构那个神秘的“目标向量yyy”既然每一个小网格都要对它地盘上的物体负责那么每个网格在经过网络卷积计算后都必须吐出一串极其硬核的结构化判决书。这就是我们今天公式的核心y[pc,bx,by,bh,bw,c1,c2,c3]y [p_c, b_x, b_y, b_h, b_w, c_1, c_2, c_3]y[pc​,bx​,by​,bh​,bw​,c1​,c2​,c3​]别怕这串字母我们现在化身那个网格的“负责人”来逐字逐句翻译这份判决书提问 1. 第一个参数pcp_cpc​Probability of Class代表“我这个网格里到底有没有包含任何物体的中心点”如果网格里只有一片纯净的蓝天根本没有物体的中心那么这个pcp_cpc​应该等于多少后面那些预测位置的参数还有意义吗2. 接下来的四个参数[bx,by,bh,bw][b_x, b_y, b_h, b_w][bx​,by​,bh​,bw​]如果pc1p_c 1pc​1有物体这四个数字分别代表什么有了这四个数我们能干什么3. 最后的[c1,c2,c3][c_1, c_2, c_3][c1​,c2​,c3​]这是一个 One-Hot 编码。假设我们要检测三种东西c1c_1c1​是猫c2c_2c2​是狗c3c_3c3​是汽车。如果这个网格认领的是一辆车那么这三个数字会呈现出什么样的状态推演闭环蓝天网格y[0,?,?,?,?,?,?,?]y [0, ?, ?, ?, ?, ?, ?, ?]y[0,?,?,?,?,?,?,?]没东西pc0p_c0pc​0后面全是无意义的垃圾值。汽车网格y[1,0.5,0.4,0.8,0.6,0,0,1]y [1, 0.5, 0.4, 0.8, 0.6, 0, 0, 1]y[1,0.5,0.4,0.8,0.6,0,0,1]有东西方框相对位置在这且 100% 是一辆汽车。有了[bx,by,bh,bw][b_x, b_y, b_h, b_w][bx​,by​,bh​,bw​]四个相对坐标我们就能在图上精准地画出那个红色的回归方框。第三步如何实现“只需看一次”呢这就是全网最精妙的高潮部分了。提问既然每一个网格都要吐出一个长度为 8 的向量yyy我们整张图一共有19×1919 \times 1919×19个网格。那么整张图最终的预测结果在数学上是不是可以完美打包成一个大三维张量Tensor尺寸为19×19×819 \times 19 \times 819×19×8我们之前学过CNN 的强项不就是灌进去一张彩色图片最后吐出一个尺寸被压缩、但通道数变多的特征图Feature Map吗如果我们设计一个全卷积网络让它吐出的最终输出尺寸恰好就是19×19×819 \times 19 \times 819×19×8呢物理画面在这整个过程中我们没有像传统算法那样把图片裁剪成几千个碎片。我们自始至终只把整张完整的图片扔进网络跑了一次正向传播Single Forward Pass就通过最后的特征通道同时拿到了所有网格的预测结果这就是为什么它快到飞起每秒能跑几十甚至上百帧视频能够完美适用在自动驾驶和视频监控这种一秒钟都不能耽误的实时场景里。第四步PyTorch 里的“一眼看穿”代码落地在 PyTorch 的概念实现中YOLO 最后的输出层不是全连接层而是一个直接吐出全盘预测张量的卷积层importtorchimporttorch.nnasnnclassYOLOLastLayer(nn.Module):def__init__(self,in_channels,S19,B1,C3):super(YOLOLastLayer,self).__init__()# S: 网格大小 (19x19)# B: 每个网格预测多少个边界框 (假设为1)# C: 类别数 (猫、狗、车共3种)# 每个框需要 5 个参数 (pc, bx, by, bh, bw) C 个类别概率 5*1 3 8out_channelsB*5C# 用一个 1x1 卷积直接把通道数调整为 8self.conv_outnn.Conv2d(in_channels,out_channels,kernel_size1)defforward(self,x):# 输入一张大图的特征层 xoutself.conv_out(x)# 输出尺寸: [Batch, 8, 19, 19]# 调整轴的顺序变成标准的 [Batch, 19, 19, 8]outout.permute(0,2,3,1)returnout难点攻坚如果是“一格多物”怎么办注意考点里提到的一个小硬核变体Anchor Boxes锚框。如果在某一个网格里不巧同时出现了一只猫和一辆车比如猫正坐在车顶上它们的中心点重合了。那一个网格如果只能吐出一个长度为 8 的向量该把名额给谁为了解决这种尴尬YOLO 引入了Anchor Boxes机制。它提前让网格准备好两个不同形状的“预设框”一个高瘦的用来套猫一个扁宽的用来套车让向量长度翻倍从 8 变成 16从而在同个网格里同时把两个截然不同的东西都框出来。总结报告我们再次用清晰的极客因果链复盘 YOLO 的伟大直觉图片划分为 S×S 网格 ⟹ 每个网格认领中心落在其内部的物体 ⟹ 利用 CNN 一键吐出 S×S×向量 的大张量 ⟹ 无裁剪、单次前向传播 ⟹ 实时多目标检测爆发\text{图片划分为 } S \times S \text{ 网格} \implies \text{每个网格认领中心落在其内部的物体} \implies \text{利用 CNN 一键吐出 } S \times S \times \text{向量 的大张量} \implies \text{无裁剪、单次前向传播} \implies \text{实时多目标检测爆发}图片划分为S×S网格⟹每个网格认领中心落在其内部的物体⟹利用CNN一键吐出S×S×向量的大张量⟹无裁剪、单次前向传播⟹实时多目标检测爆发传统的检测算法像是一个效率低下的审查官把一张图剪得粉碎拿着放大镜看了几千次而YOLO则像是一个拥有绝顶天赋的鹰眼刺客在风驰电掣的瞬间抬眼一瞥便将世间万物的类别与坐标尽收眼底。欢迎在评论区留下你的思考YOLO 追求极致的速度但在面对非常细小且密集的物体比如远处的鸟群时往往容易漏检。结合今天学到的网格认领机制你认为导致小目标检测性能下降的根本原因是什么

相关新闻