SSD目标检测网络
1、SSD网络概述
SSD网络将输入的图片resize成300×300的大小。用深度神经网络进行特征提取。得到不同大小的特征层
(38×38×512,19×19×1024,10×10×512, 5×5×6, 3×3×256, 1×1×256)
。
每个特征层可以看做对图片划分成不同的网格,每个网格对应若干先验框。训练的过程是对先验框进行调整的过程。
这6中不同大小网格,每一个网格对应的先验框的个数为:(4, 6, 6, 6, 4, 4)
。
计算得到一共需要计算先验框的个数为:
38×38×4+19×19×6+10×10×6+5×5×6+3×3×4+1×1×4=8732
通过非极大值抑制得到最终的预测结果。
2、SSD主干特征提取网络
SSD网络的输入特征层大小规定为300×300×3
。经过9个block特征提取,得到6个有效特征层。
block1代码如下:
net['conv1_1'] = Conv2D(64, kernel_size=(3,3),
activation='relu',
padding='same',
name='conv1_1')(net['input'])
net['conv1_2'] = Conv2D(64, kernel_size=(3,3),
activation='relu',
padding='same',
name='conv1_2')(net['conv1_1'])
net['pool1'] = MaxPooling2D((2, 2), strides=(2, 2), padding='same',
name='pool1')(net['conv1_2'])
对于输入的特征层,经过两次3×3卷积+1次步长为2的最大池化层得到特征层大小为150×150×64
。
block2代码如下:
net['conv2_1'] = Conv2D(128, kernel_size=(3,3),
activation='relu',
padding='same',
name='conv2_1')(net['pool1'])
net['conv2_2'] = Conv2D(128, kernel_size=(3,3),
activation='relu',
padding='same',
name='conv2_2')(net['conv2_1'])
net['pool2'] = MaxPooling2D((2, 2), strides=(2, 2), padding='same',
name='pool2')(net['conv2_2'])
经过两次3×3卷积+一次步长为2的最大池化层,输出特征层大小为75×75×128
。
block3代码如下:
net['conv3_1'] = Conv2D(256, kernel_size=(3,3),
activation='relu',
padding='same',
name='conv3_1')(net['pool2'])
net['conv3_2'] = Conv2D(256, kernel_size=(3,3),
activation='relu',
padding='same',
name='conv3_2')(net['conv3_1'])
net['conv3_3'] = Conv2D(256, kernel_size=(3,3),
activation='relu',
padding='same',
name='conv3_3')(net['conv3_2'])
net['pool3'] = MaxPooling2D((2, 2), strides=(2, 2), padding='same',
name='pool3')(net['conv3_3'])
经过3次3×3卷积+一次步长为2的最大池化层,输出特征层大小为38×38×256
。
block4代码如下:
net['conv4_1'] = Conv2D(512, kernel_size=(3,3),
activation='relu',
padding='same',
name='conv4_1')(net['pool3'])
net['conv4_2'] = Conv2D(512, kernel_size=(3,3),
activation='relu',
padding='same',
name='conv4_2')(net['conv4_1'])
net['conv4_3'] = Conv2D(512, kernel_size=(3,3),
activation='relu',
padding='same',
name='conv4_3')(net['conv4_2'])
net['pool4'] = MaxPooling2D((2, 2), strides=(2, 2), padding='same',
name='pool4')(net['conv4_3'])
经过3次3×3卷积+1次步长为2的最大池化层,经过三次卷积输出特征层大小为38×38×512
该特征层作为有效特征层进行下一步操作。 block4输出特征层大小为19×19×512
。
block5代码如下:
net['conv5_1'] = Conv2D(512, kernel_size=(3,3),
activation='relu',
padding='same',
name='conv5_1')(net['pool4'])
net['conv5_2'] = Conv2D(512, kernel_size=(3,3),
activation='relu',
padding='same',
name='conv5_2')(net['conv5_1'])
net['conv5_3'] = Conv2D(512, kernel_size=(3,3),
activation='relu',
padding='same',
name='conv5_3')(net['conv5_2'])
net['pool5'] = MaxPooling2D((3, 3), strides=(1, 1), padding='same',
name='pool5')(net['conv5_3'])
经过3次3×3卷积+1次步长为1的最大池化层,输出特征层大小为19×19×512
。
FC6、FC7代码如下:
net['fc6'] = Conv2D(1024, kernel_size=(3,3), dilation_rate=(6, 6),
activation='relu', padding='same',
name='fc6')(net['pool5'])
net['fc7'] = Conv2D(1024, kernel_size=(1,1), activation='relu',
padding='same', name='fc7')(net['fc6'])
空洞卷积+1×1卷积,输出特征层大小为19×19×1024
。该特征层作为有效特征层进行下一步操作。
block6代码如下:
net['conv6_1'] = Conv2D(256, kernel_size=(1,1), activation='relu',
padding='same',
name='conv6_1')(net['fc7'])
net['conv6_2'] = ZeroPadding2D(padding=((1, 1), (1, 1)), name='conv6_padding')(net['conv6_1'])
net['conv6_2'] = Conv2D(512, kernel_size=(3,3), strides=(2, 2),
activation='relu',
name='conv6_2')(net['conv6_2'])
经过1次1×1卷积+zeropadding+步长为2的3×3卷积,输出通道数为10×10×512
。该特征层作为有效特征层进行下一步操作。
block7代码如下:
net['conv7_1'] = Conv2D(128, kernel_size=(1,1), activation='relu',
padding='same',
name='conv7_1')(net['conv6_2'])
net['conv7_2'] = ZeroPadding2D(padding=((1, 1), (1, 1)), name='conv7_padding')(net['conv7_1'])
net['conv7_2'] = Conv2D(256, kernel_size=(3,3), strides=(2, 2),
activation='relu', padding='valid',
name='conv7_2')(net['conv7_2'])
经过1次1×1卷积+zeropadding+一次步长为2的3×3卷积,输出特征层大小为5×5×256
。该特征层作为有效特征层进行下一步操作。
block8代码如下: