您现在的位置是:网站首页> 编程资料编程资料
python神经网络Keras搭建RFBnet目标检测平台_python_
2023-05-26
408人已围观
简介 python神经网络Keras搭建RFBnet目标检测平台_python_
什么是RFBnet目标检测算法
RFBnet是SSD的一种加强版,主要是利用了膨胀卷积这一方法增大了感受野,相比于普通的ssd,RFBnet也是一种加强吧
RFBnet是改进版的SSD,其整体的结构与SSD相差不大,其主要特点是在SSD的特征提取网络上用了RFB模块。
RFB的全称Receptive Field Block,是一种轻量级的、而且集成了各类检测算法优点的模块,结合了Inception、虫洞卷积的思想,以提高感受野的方式提高网络的特征提取能力。

RFBnet实现思路
一、预测部分
1、主干网络介绍

RFBnet采用的主干网络是VGG网络,关于VGG的介绍大家可以看我的另外一篇博客https://www.jb51.net/article/246917.htm,这里的VGG网络相比普通的VGG网络有一定的修改,主要修改的地方就是:
1、将VGG16的FC6和FC7层转化为卷积层。
2、增加了RFB模块。
主要使用到的RFB模块有两种,一种是BasicRFB,另一种是BasicRFB_a。
二者使用的思想相同,构造有些许不同。
BasicRFB的结构如下:

BasicRFB_a和BasicRFB类似,并联结构增加,有8个并联。
实现代码:
from keras.layers import (Activation, BatchNormalization, Conv2D, Lambda, MaxPooling2D, UpSampling2D, concatenate) def conv2d_bn(x,filters,num_row,num_col,padding='same',stride=1,dilation_rate=1,relu=True): x = Conv2D( filters, (num_row, num_col), strides=(stride,stride), padding=padding, dilation_rate=(dilation_rate, dilation_rate), use_bias=False)(x) x = BatchNormalization()(x) if relu: x = Activation("relu")(x) return x def BasicRFB(x,input_filters,output_filters,stride=1,map_reduce=8): #-------------------------------------------------------# # BasicRFB模块是一个残差结构 # 主干部分使用不同膨胀率的卷积进行特征提取 # 残差边只包含一个调整宽高和通道的1x1卷积 #-------------------------------------------------------# input_filters_div = input_filters//map_reduce branch_0 = conv2d_bn(x, input_filters_div*2, 1, 1, stride=stride) branch_0 = conv2d_bn(branch_0, input_filters_div*2, 3, 3, relu=False) branch_1 = conv2d_bn(x, input_filters_div, 1, 1) branch_1 = conv2d_bn(branch_1, input_filters_div*2, 3, 3, stride=stride) branch_1 = conv2d_bn(branch_1, input_filters_div*2, 3, 3, dilation_rate=3, relu=False) branch_2 = conv2d_bn(x, input_filters_div, 1, 1) branch_2 = conv2d_bn(branch_2, (input_filters_div//2)*3, 3, 3) branch_2 = conv2d_bn(branch_2, input_filters_div*2, 3, 3, stride=stride) branch_2 = conv2d_bn(branch_2, input_filters_div*2, 3, 3, dilation_rate=5, relu=False) branch_3 = conv2d_bn(x, input_filters_div, 1, 1) branch_3 = conv2d_bn(branch_3, (input_filters_div//2)*3, 1, 7) branch_3 = conv2d_bn(branch_3, input_filters_div*2, 7, 1, stride=stride) branch_3 = conv2d_bn(branch_3, input_filters_div*2, 3, 3, dilation_rate=7, relu=False) #-------------------------------------------------------# # 将不同膨胀率的卷积结果进行堆叠 # 利用1x1卷积调整通道数 #-------------------------------------------------------# out = concatenate([branch_0,branch_1,branch_2,branch_3],axis=-1) out = conv2d_bn(out, output_filters, 1, 1, relu=False) #-------------------------------------------------------# # 残差边也需要卷积,才可以相加 #-------------------------------------------------------# short = conv2d_bn(x, output_filters, 1, 1, stride=stride, relu=False) out = Lambda(lambda x: x[0] + x[1])([out,short]) out = Activation("relu")(out) return out def BasicRFB_a(x, input_filters, output_filters, stride=1, map_reduce=8): #-------------------------------------------------------# # BasicRFB_a模块也是一个残差结构 # 主干部分使用不同膨胀率的卷积进行特征提取 # 残差边只包含一个调整宽高和通道的1x1卷积 #-------------------------------------------------------# input_filters_div = input_filters//map_reduce branch_0 = conv2d_bn(x,input_filters_div,1,1,stride=stride) branch_0 = conv2d_bn(branch_0,input_filters_div,3,3,relu=False) branch_1 = conv2d_bn(x,input_filters_div,1,1) branch_1 = conv2d_bn(branch_1,input_filters_div,3,1,stride=stride) branch_1 = conv2d_bn(branch_1,input_filters_div,3,3,dilation_rate=3,relu=False) branch_2 = conv2d_bn(x,input_filters_div,1,1) branch_2 = conv2d_bn(branch_2,input_filters_div,1,3,stride=stride) branch_2 = conv2d_bn(branch_2,input_filters_div,3,3,dilation_rate=3,relu=False) branch_3 = conv2d_bn(x,input_filters_div,1,1) branch_3 = conv2d_bn(branch_3,input_filters_div,3,1,stride=stride) branch_3 = conv2d_bn(branch_3,input_filters_div,3,3,dilation_rate=5,relu=False) branch_4 = conv2d_bn(x,input_filters_div,1,1) branch_4 = conv2d_bn(branch_4,input_filters_div,1,3,stride=stride) branch_4 = conv2d_bn(branch_4,input_filters_div,3,3,dilation_rate=5,relu=False) branch_5 = conv2d_bn(x,input_filters_div//2,1,1) branch_5 = conv2d_bn(branch_5,(input_filters_div//4)*3,1,3) branch_5 = conv2d_bn(branch_5,input_filters_div,3,1,stride=stride) branch_5 = conv2d_bn(branch_5,input_filters_div,3,3,dilation_rate=7,relu=False) branch_6 = conv2d_bn(x,input_filters_div//2,1,1) branch_6 = conv2d_bn(branch_6,(input_filters_div//4)*3,3,1) branch_6 = conv2d_bn(branch_6,input_filters_div,1,3,stride=stride) branch_6 = conv2d_bn(branch_6,input_filters_div,3,3,dilation_rate=7,relu=False) #-------------------------------------------------------# # 将不同膨胀率的卷积结果进行堆叠 # 利用1x1卷积调整通道数 #-------------------------------------------------------# out = concatenate([branch_0,branch_1,branch_2,branch_3,branch_4,branch_5,branch_6],axis=-1) out = conv2d_bn(out, output_filters, 1, 1, relu=False) #-------------------------------------------------------# # 残差边也需要卷积,才可以相加 #-------------------------------------------------------# short = conv2d_bn(x, output_filters, 1, 1, stride=stride, relu=False) out = Lambda(lambda x: x[0] + x[1])([out, short]) out = Activation("relu")(out) return out #--------------------------------# # 取Conv4_3和fc7进行特征融合 #--------------------------------# def Normalize(net): # 38,38,512 -> 38,38,256 branch_0 = conv2d_bn(net["conv4_3"], 256, 1, 1) # 19,19,512 -> 38,38,256 branch_1 = conv2d_bn(net['fc7'], 256, 1, 1) branch_1 = UpSampling2D()(branch_1) # 38,38,256 + 38,38,256 -> 38,38,512 out = concatenate([branch_0,branch_1],axis=-1) # 38,38,512 -> 38,38,512 out = BasicRFB_a(out,512,512) return out def backbone(input_tensor): #----------------------------主干特征提取网络开始---------------------------# # RFB结构,net字典 net = {} # Block 1 net['input'] = input_tensor # 300,300,3 -> 150,150,64 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']) # Block 2 # 150,150,64 -> 75,75,128 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']) # Block 3 # 75,75,128 -> 38,38,256 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']) # Block 4 # 38,38,256 -> 19,19,512 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']) # Block 5 # 19,19,512 -> 19,19,512 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']) # FC6 # 19,19,512 -> 19,19,1024 net['fc6'] = Conv2D(1024, kernel_size=(3,3), dilation_rate=(6, 6), activation='relu', padding='same', name='fc6')(net['pool5']) # x = Dropout(0.5, name='drop6')(x) # FC7 # 19,19,1024 -> 19,19,1024 net['fc7'] = Conv2D(1024, kernel_size=(1,1), activation='relu', padding='same', name='fc7')(net['fc6']) #------------------------------------------------
相关内容
- 如何对numpy 矩阵进行通道间求均值_python_
- Python中itertools模块的使用教程详解_python_
- 使用numpy.mean() 计算矩阵均值方式_python_
- python利用opencv调用摄像头实现目标检测_python_
- Pandas 如何处理DataFrame中的inf值_python_
- python之NAN和INF值处理方式_python_
- mAP计算目标检测精确度实现源码_python_
- Python判断Nan值的五种方式小结_python_
- Python图片视频超分模型RealBasicVSR的使用教程_python_
- 基于Python制作图像完美超分处理工具_python_
点击排行
本栏推荐
