相关链接:
- 《RefineDet:Single-Shot Refinement Neural Network for Object Detection》论文笔记
- RefineDet:(2)检测部分网络解析
- RefineDet:(3)C++测试代码
1. 概述
RefineDet的相关原理介绍已经在之前的博客中做了介绍:
这里主要就所用到的训练脚本中做一些分析,这里选用的网络是VGG16作为基础训练网络,相关训练脚本的参数解释如下
'''
所用文件位于:RefineDet-master\examples\refinedet\VGG16_VOC2007_512.py
'''
# Add extra layers on top of a "base" network (e.g. VGGNet or ResNet).
# AddExtraLayers函数是网络结构构造中比较重要的函数,主要实现的就是论文中的
# transfer connection block (TCB)部分,也就是类似FPN算法的特征融合操作。
def AddExtraLayers(net, use_batchnorm=True, arm_source_layers=[], normalizations=[], lr_mult=1):
use_relu = True
# Add additional convolutional layers.
# 添加论文中所说的后面几层卷积
# 512/32: 16 x 16
from_layer = net.keys()[-1]
# 512/64: 8 x 8
out_layer = "conv6_1"
ConvBNLayer(net, from_layer, out_layer, use_batchnorm, use_relu, 256, 1, 0, 1, lr_mult=lr_mult)
from_layer = out_layer
out_layer = "conv6_2"
ConvBNLayer(net, from_layer, out_layer, use_batchnorm, use_relu, 512, 3, 1, 2, lr_mult=lr_mult)
# 按照指定的ARM特征图构建FPN网络结构
arm_source_layers.reverse() # ARM模块的特征图来源层
normalizations.reverse()
num_p = 6
for index, layer in enumerate(arm_source_layers):
out_layer = layer
# 对conv4_3与conv5_3层归一化操作,scale分别为10与8
# 文中讲到这两个层由于之前层的特征差异,这里对其归一化,并且不断学习scale
if normalizations:
if normalizations[index] != -1:
norm_name = "{}_norm".format(layer)
net[norm_name] = L.Normalize(net[layer], scale_filler=dict(type="constant", value=normalizations[index]),
across_spatial=False, channel_shared=False)
out_layer = norm_name
arm_source_layers[index] = norm_name
from_layer = out_layer
out_layer = "TL{}_{}".format(num_p, 1)
ConvBNLayer(net, from_layer, out_layer, use_batchnorm, use_relu, 256, 3, 1, 1, lr_mult=lr_mult)
if num_p == 6: # 网络的最后一个TCB模块,没有后面的输入
from_layer = out_layer
out_layer = "TL{}_{}".format(num_p, 2)
ConvBNLayer(net, from_layer, out_layer, use_batchnorm, use_relu, 256, 3, 1, 1, lr_mult=lr_mult)
from_layer = out_layer
out_layer = "P{}".format(num_p)
ConvBNLayer(net, from_layer, out_layer, use_batchnorm, use_relu, 256, 3, 1, 1, lr_mult=lr_mult)
else: # 其它TCB模块的创建
from_layer = out_layer
out_layer = "TL{}_{}".format(num_p, 2)
ConvBNLayer(net, from_layer, out_layer, use_batchnorm, False, 256, 3, 1, 1, lr_mult=lr_mult)
from_layer = "P{}".format(num_p+1)
out_layer = "P{}-up".format(num_p+1)
DeconvBNLayer(net, from_layer, out_layer, use_batchnorm, False, 256, 2, 0, 2, lr_mult=lr_mult)
from_layer = ["TL{}_{}".format(num_p, 2), "P{}-up".format(num_p+1)]
out_layer = "Elt{}".format(num_p)
EltwiseLayer(net, from_layer, out_layer)
relu_name = '{}_relu'.format(out_layer)
net[relu_name] = L.ReLU(net[out_layer], in_place=True)
out_layer = relu_name
from_layer = out_layer
out_layer = "P{}".format(num_p)
ConvBNLayer(net, from_layer, out_layer, use_batchnorm, use_relu, 256, 3, 1, 1, lr_mult=lr_mult)
num_p = num_p - 1
return net
### Modify the following parameters accordingly ###
# The directory which contains the caffe code.
# We assume you are running the script at the CAFFE_ROOT.
caffe_root = os.getcwd()
# Set true if you want to start training right after generating all files.
run_soon = True
# Set true if you want to load from most recently saved snapshot.
# Otherwise, we will load from the pretrain_model defined below.
resume_training = True # 是否需要从上次训练中断的地方继续训练
# If true, Remove old model files.
remove_old_models = False # 是否删除老的模型
# The database file for training data. Created by data/VOC0712/create_