Skip to content

Commit a62cb2f

Browse files
committed
ssd multi dim det
1 parent 7693f6c commit a62cb2f

File tree

3 files changed

+49
-13
lines changed

3 files changed

+49
-13
lines changed

TERMINOLOGY.md

+4
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@
7878

7979
负采样,negative sampling
8080

81+
感受野,receptive field
82+
8183
共现词频,co-occurrence frequency
8284

8385
归一化,normalization
@@ -172,6 +174,8 @@ softmax回归,softmax regression
172174

173175
特征,feature
174176

177+
特征图,feature map
178+
175179
特征值,eigenvalue
176180

177181
梯度,gradient

chapter_computer-vision/anchor.md

+20
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,31 @@ $$(s_1, r_1), (s_1, r_2), \ldots, (s_1, r_m), (s_2, r_1), (s_3, r_1), \ldots, (s
3030
```{.python .input n=2}
3131
img = image.imread('../img/catdog.jpg').asnumpy()
3232
h, w = img.shape[0:2]
33+
34+
print(h,w)
3335
X = nd.random.uniform(shape=(1, 3, h, w)) # 构造输入数据。
3436
Y = contrib.nd.MultiBoxPrior(X, sizes=[0.75, 0.5, 0.25], ratios=[1, 2, 0.5])
3537
Y.shape
3638
```
3739

40+
```{.json .output n=2}
41+
[
42+
{
43+
"name": "stdout",
44+
"output_type": "stream",
45+
"text": "561 728\n"
46+
},
47+
{
48+
"data": {
49+
"text/plain": "(1, 2042040, 4)"
50+
},
51+
"execution_count": 2,
52+
"metadata": {},
53+
"output_type": "execute_result"
54+
}
55+
]
56+
```
57+
3858
我们看到,返回锚框变量`y`的形状为(批量大小,锚框个数,4)。将锚框变量`y`的形状变为(图像高,图像宽,以相同像素为中心的锚框个数,4)后,我们就可以通过指定像素位置来获取所有以该像素为中心的锚框了。下面例子里我们访问以(250,250)为中心的第一个锚框。它有四个元素,分别是锚框左上角和右下角的$x$和$y$轴坐标。其中$x$和$y$轴的坐标值分别已除以图像的宽和高,因此值域均为0和1之间。
3959

4060
```{.python .input n=3}

chapter_computer-vision/ssd.md

+25-13
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,15 @@
11
# 单发多框检测(SSD)
22

3-
我们在前几节分别介绍了边界框、锚框、数据集等背景知识,下面我们来构造一个目标检测模型:单发多框检测(single shot multibox detection,简称SSD)[1]。它简单、快速,并得到了广泛使用。本节也将通过单发多框检测来详解目标检测的实现细节
3+
我们在前几节分别介绍了边界框、锚框、数据集等背景知识,下面我们来构造一个目标检测模型:单发多框检测(single shot multibox detection,简称SSD)[1]。它简单、快速,并得到了广泛使用。该模型的部分设计思想和实现细节同样适用于其他目标检测模型
44

55

6-
## 模型
7-
8-
图9.4描述了SSD模型。给定输入图像,其首先使用主要由卷积层组成的模块来进行特征抽取。在其特征输出上,我们以每个像素为中心构建多个锚框(往左的箭头),然后使用softmax来对每个锚框判断其包含的目标类别,以及用卷积直接预测它到真实目标边界框的距离。卷积层的输出同时被输入到一个高宽减半模块(往上的箭头)来缩小图像尺寸。这个模块的输出将进入到另一个卷积模块抽取特征,并构建锚框来预测目标类别和边界框。这样设计的目的是在不同的尺度上进行目标检测,例如前一层的锚框主要检测图像中尺寸较小的目标,而这一层我们则检测尺寸稍大的目标。自然的,我们会重复这一过程多次以保证在多种不同的尺度下检测目标。
9-
10-
![SSD模型。](../img/ssd.svg)
11-
12-
接下来我们介绍并实现图中各个模块。由于这里锚框是由上小节介绍的方法生成而来,我们不再赘述。接下来直接介绍类别预测和边界框预测。
13-
14-
### 类别预测
6+
## 多尺度检测目标
157

16-
假设数据集中有$n$种不同的目标类别,那么我们将对每个锚框做$n+1$类分类,其中类0表示锚框只包含背景。因为我们对输入像素为中心生成多个锚框,记为$a$,我们将会预测$hwa$个锚框的分类结果,这里$h$和$w$分别是输入高和宽。如果使用全连接层作为输出,可能会导致有过多的模型参数。回忆[“网络中的网络:NiN](../chapter_convolutional-neural-networks/nin.md)这一节里我们介绍了使用卷积层的通道来输出类别预测,SSD采用同样的方法来降低模型复杂度
8+
[“锚框](anchor.md)一节中,我们在实验中以输入图像的每个像素为中心生成多个锚框。这些锚框是对输入图像不同区域的采样。然而,如果以图像每个像素为中心都生成锚框,很容易生成过多锚框而造成计算量过大。举个例子,假设输入图像高和宽都是512像素,如果以每个像素为中心生成4个不同形状的锚框,那么一张图像上则需要标注并预测一百多万个锚框($512 \times 512 \times 4$)
179

18-
具体来说,类别预测层使用一个保持输入高宽的卷积层,其输出的$(x,y)$像素通道里包含了以输入$(x,y)$像素为中心的所有锚框的类别预测。其输出通道数为$a(n+1)$,其中通道$i(n+1)$是第$i$个锚框预测的背景置信度,而通道$i(n+1)+j+1$则是第$i$锚框预测的第$j$类目标的置信度
10+
一个简单的方案是在输入图像中均匀采样一小部分像素,并以采样的像素为中心生成锚框。但仅仅这样还不够。直觉上,较小目标比较大目标在图像上出现位置的可能性更多。举个简单的例子,形状为$1 \times 1$、$1 \times 2$和$2 \times 2$的目标在形状为$2 \times 2$的图像上可能出现的位置分别有4、2和1种。因此,当使用较小锚框来检测较小目标时,我们可以采样较多的区域;而当使用较大锚框来检测较大目标时,我们可以采样较少的区域。这种方法叫做多尺度检测目标
1911

20-
下面我们定义一个这样的类别分类器,指定$a$和$n$后,它使用一个填充为1的$3\times3$卷积层。注意到我们使用了较小的卷积窗口,它可能不能覆盖锚框定义的区域。所以我们需要保证前面的卷积层能有效的将较大的锚框区域的特征浓缩到一个$3\times3$的窗口里
12+
为了演示多尺度检测目标,我们先读取一张图像。它的高和宽分别为512像素
2113

2214
```{.python .input}
2315
import sys
@@ -30,6 +22,10 @@ from mxnet.gluon import loss as gloss, nn
3022
import time
3123
3224
img = image.imread('../img/pikachu.jpg')
25+
img.shape[0:2]
26+
```
27+
28+
```{.python .input}
3329
bbox_scale = nd.array(img.shape[0:2] * 2)
3430
3531
def display_anchors(fmap_w, fmap_h, s):
@@ -48,6 +44,22 @@ display_anchors(fmap_w=2, fmap_h=2, s=[0.3])
4844
display_anchors(fmap_w=4, fmap_h=4, s=[0.15])
4945
```
5046

47+
## 模型
48+
49+
图9.4描述了SSD模型。给定输入图像,其首先使用主要由卷积层组成的模块来进行特征抽取。在其特征输出上,我们以每个像素为中心构建多个锚框(往左的箭头),然后使用softmax来对每个锚框判断其包含的目标类别,以及用卷积直接预测它到真实目标边界框的距离。卷积层的输出同时被输入到一个高宽减半模块(往上的箭头)来缩小图像尺寸。这个模块的输出将进入到另一个卷积模块抽取特征,并构建锚框来预测目标类别和边界框。这样设计的目的是在不同的尺度上进行目标检测,例如前一层的锚框主要检测图像中尺寸较小的目标,而这一层我们则检测尺寸稍大的目标。自然的,我们会重复这一过程多次以保证在多种不同的尺度下检测目标。
50+
51+
![SSD模型。](../img/ssd.svg)
52+
53+
接下来我们介绍并实现图中各个模块。由于这里锚框是由上小节介绍的方法生成而来,我们不再赘述。接下来直接介绍类别预测和边界框预测。
54+
55+
### 类别预测
56+
57+
假设数据集中有$n$种不同的目标类别,那么我们将对每个锚框做$n+1$类分类,其中类0表示锚框只包含背景。因为我们对输入像素为中心生成多个锚框,记为$a$,我们将会预测$hwa$个锚框的分类结果,这里$h$和$w$分别是输入高和宽。如果使用全连接层作为输出,可能会导致有过多的模型参数。回忆[“网络中的网络:NiN”](../chapter_convolutional-neural-networks/nin.md)这一节里我们介绍了使用卷积层的通道来输出类别预测,SSD采用同样的方法来降低模型复杂度。
58+
59+
具体来说,类别预测层使用一个保持输入高宽的卷积层,其输出的$(x,y)$像素通道里包含了以输入$(x,y)$像素为中心的所有锚框的类别预测。其输出通道数为$a(n+1)$,其中通道$i(n+1)$是第$i$个锚框预测的背景置信度,而通道$i(n+1)+j+1$则是第$i$锚框预测的第$j$类目标的置信度。
60+
61+
下面我们定义一个这样的类别分类器,指定$a$和$n$后,它使用一个填充为1的$3\times3$卷积层。注意到我们使用了较小的卷积窗口,它可能不能覆盖锚框定义的区域。所以我们需要保证前面的卷积层能有效的将较大的锚框区域的特征浓缩到一个$3\times3$的窗口里。
62+
5163
```{.python .input n=2}
5264
def cls_predictor(num_anchors, num_classes):
5365
return nn.Conv2D(num_anchors * (num_classes + 1), kernel_size=3,

0 commit comments

Comments
 (0)