现在看网上的很多 YOLOv1 的代码实现,基本都是使用新的 backbone,例如 ResNet 或者 VGG 来实现的,因为这些后面的通用的 backbone 可能比较方便的获得预训练模型,不需要从头开始训练。
但是我就是想看一下,一开始 YOLOv1 网络结构是咋样的,所以就当做学习了,来还原一下最初的 YOLOv1 网络结构。
比较常见的图有两张:
这张是原论文里面的图片,我后面根据下面的卷积参数进行复现的时候,发现如果严格按照上面的输出的话,有输出张量的通道数,图上应该是标错了的。
这里张图应该也是网友制作的图,但是其中的一个张量的尺寸也是错误的。
首先我们根据论文提供的第一张图的网络结构参数来复原一下:
layer | output size | module | |
---|---|---|---|
448x448x3 | |||
1 | 224x224x64 | Conv 7x7x64, s-2, p-3 | modified GoogLeNet backbone |
112x112x64 | Maxpool 2x2, s-2, p-0 | modified GoogLeNet backbone | |
2 | 112x112x192 | Conv 3x3x192, s-1, p-1 | modified GoogLeNet backbone |
56x56x192 | Maxpool 2x2, s-2, p-0 | modified GoogLeNet backbone | |
3 | 56x56x128 | Conv 1x1x128, s-1, p-0 | modified GoogLeNet backbone |
4 | 56x56x256 | Conv 3x3x256, s-1, p-1 | modified GoogLeNet backbone |
5 | 56x56x256 | Conv 1x1x256, s-1, p-0 | modified GoogLeNet backbone |
6 | 56x56x512 | Conv 3x3x512, s-1, p-1 | modified GoogLeNet backbone |
28x28x512 | Maxpool 2x2, s-2, p-0 | modified GoogLeNet backbone | |
7,9,11,13 | 28x28x256 | Conv 1x1x256, s-1, p-0 | modified GoogLeNet backbone |
8,10,12,14 | 28x28x512 | Conv 3x3x512, s-1, p-1 | modified GoogLeNet backbone |
15 | 28x28x512 | Conv 1x1x512, s-1, p-0 | modified GoogLeNet backnone |
16 | 28x28x1024 | Conv 3x3x1024, s-1, p-1 | modified GoogLeNet backbone |
14x14x1024 | Maxpool 2x2, s-2, p-0 | modified GoogLeNet backbone | |
17,19 | 14x14x512 | Conv 1x1x512, s-1, p-0 | modified GoogLeNet backbone |
18,20 | 14x14x1024 | Conv 3x3x1024, s-1, p-1 | modified GoogLeNet backbone |
21 | 14x14x1024 | Conv 3x3x1024, s-1, p-1 | |
22 | 7x7x1024 | Conv 3x3x1024, s-2, p-1 | |
23 | 7x7x1024 | Conv 3x3x1024, s-1, p-1 | |
24 | 7x7x1024 | Conv 3x3x1024, s-1, p-1 | |
25 | 4096x1 | FC1 | |
26 | 1470x1 | FC2 | |
7x7x30 | reshape |
从这个这个表格我们可以看到:
- 前 20 层是 backbone,属于魔改之后的 GoogLeNet 网络,修改的细节后续会给出。
- 在 backbone 后面,还接着 4 个卷积层和 2 个全连接层,最后进行 reshape,输出我们想要的张量维度。
YOLOv1 的 backbone 是根据 GoogLeNet 进行修改的。
首先看一下 GoogLeNet 的网络结构,之前出过一篇文章专门介绍 Inception 家族的,所以 GoogLeNet 的结构示意图如下:
具体来说,这里的 GoogLeNet modification(20 layers)就是采用 1×1 卷积层加 3×3 卷积层替换了
GoogLeNet 中的 Inception 模块,然后去掉了第二层 1x1 的卷积层和最后的 fc 层
这就是我们 YOLOv1 的网络结构图:
- 左边部分就是魔改之后的 GoogLeNet backbone,其中 Inception 的部分都使用 1x1 和 3x3 卷积替代了。简单来说,相当于将 Inception 模块中多条分支,只保留了 1x1 和 3x3 卷积单条分支。
- 中间部分就是紫色 Stem 模块的展开,其中如同上面描述的那样,第二层的 1x1 卷积去掉了
- 右边部分就是 YOLOv1 最后的输出部分
参考文献
- 目标检测 YOLO 系列: 开宗立派 YOLO v1
- You Only Look Once: Unified, Real-Time Object Detection