各位同学好,今天和大家分享一下如何使用 注意力机制 和 深度可分离卷积 优化 YOLOV4 的 PANet 特征金字塔。看本篇博客之前,建议大家先看以下几篇:

YOLOV4主干网络:https://blog.csdn.net/dgvv4/article/details/123818580

混合域注意力机制:https://blog.csdn.net/dgvv4/article/details/123888724

轻量化网络:https://blog.csdn.net/dgvv4/article/details/123476899


1. PANet原理

网络在不同深度下提取到的特征图关注的特征的倾向有所区别。高层的特征图更加关注物体整体特征如形状大小低层的特征图关注物体的细节特征如纹理图案使用低层特征图中蕴含的信息可以对需要检测的物体进行更好地定位

由于神经网络的前向计算路径过长,通常有几十层,不利于特征信息从下向上流动,因为特征信息每经过一次卷积就会被稀释一次。

PANet 因此在自上向下的FPN网络结构中额外增加了自底向上的路径聚合模块PAN将低层特征图的信息又传导到高层中特征图去,同时在自上向下的路径中减少了高层特征图到低层特征图的信息流通需要穿过的卷积层的数量。


2. CBAM 注意力机制

CBAM注意力机制在之前的文章中已经详细讲解过,有疑问的可以看上面开头链接对应的博文。这里简单复习一下。

CBAM 模块将卷积层输出的结果作为输入特征图先通过一个通道注意力模块,得到加权结果之后,会再经过一个空间注意力模块,随后对上一步中已经经过通道注意力模块处理过的中间特征图再进行加权,最后将注意力分配权重与输入特征图之间相乘就能够实现自适应的特征优化工作

对于一幅给定的输入图像,CBAM 模块的通道注意力部分关注“什么”是有意义的,而空间注意力部分更加关注“哪里”是信息更加丰富的部分,两者之间互相补充,能够更好的帮助网络进行特征提取工作。

代码展示:

#(1)CBAM注意力机制
# 通道注意力
def channel_attenstion(inputs, ratio=0.25):'''ratio代表第一个全连接层下降通道数的倍数'''channel = inputs.shape[-1]  # 获取输入特征图的通道数# 分别对输出特征图进行全局最大池化和全局平均池化# [h,w,c]==>[None,c]x_max = layers.GlobalMaxPooling2D()(inputs)x_avg = layers.GlobalAveragePooling2D()(inputs)# [None,c]==>[1,1,c]x_max = layers.Reshape([1,1,-1])(x_max)  # -1代表自动寻找通道维度的大小x_avg = layers.Reshape([1,1,-1])(x_avg)  # 也可以用变量channel代替-1# 第一个全连接层通道数下降1/4, [1,1,c]==>[1,1,c//4]x_max = layers.Dense(channel*ratio)(x_max)x_avg = layers.Dense(channel*ratio)(x_avg)# relu激活函数x_max = layers.Activation('relu')(x_max)x_avg = layers.Activation('relu')(x_avg)# 第二个全连接层上升通道数, [1,1,c//4]==>[1,1,c]x_max = layers.Dense(channel)(x_max)x_avg = layers.Dense(channel)(x_avg)# 结果在相叠加 [1,1,c]+[1,1,c]==>[1,1,c]x = layers.Add()([x_max, x_avg])# 经过sigmoid归一化权重x = tf.nn.sigmoid(x)# 输入特征图和权重向量相乘,给每个通道赋予权重x = layers.Multiply()([inputs, x])  # [h,w,c]*[1,1,c]==>[h,w,c]return x# 空间注意力机制
def spatial_attention(inputs):# 在通道维度上做最大池化和平均池化[b,h,w,c]==>[b,h,w,1]# keepdims=Fale那么[b,h,w,c]==>[b,h,w]x_max = tf.reduce_max(inputs, axis=3, keepdims=True)  # 在通道维度求最大值x_avg = tf.reduce_mean(inputs, axis=3, keepdims=True)  # axis也可以为-1# 在通道维度上堆叠[b,h,w,2]x = layers.concatenate([x_max, x_avg])# 1*1卷积调整通道[b,h,w,1]x = layers.Conv2D(filters=1, kernel_size=(1,1), strides=1, padding='same')(x)# sigmoid函数权重归一化x = tf.nn.sigmoid(x)# 输入特征图和权重相乘x = layers.Multiply()([inputs, x])return x# CBAM注意力
def CBAM_attention(inputs):# 先经过通道注意力再经过空间注意力x = channel_attenstion(inputs)x = spatial_attention(x)return x

3. 深度可分离卷积

普通卷积是一个卷积核处理所有的通道,输入特征图有多少个通道,卷积核就有几个通道,一个卷积核生成一张特征图。

深度可分离卷积 可理解为 深度卷积 + 逐点卷积

深度卷积只处理长宽方向的空间信息逐点卷积只处理跨通道方向的信息。能大大减少参数量,提高计算效率

深度卷积: 一个卷积核只处理一个通道,即每个卷积核只处理自己对应的通道。输入特征图有多少个通道就有多少个卷积核。将每个卷积核处理后的特征图堆叠在一起。输入和输出特征图的通道数相同。

由于只处理长宽方向的信息会导致丢失跨通道信息,为了将跨通道的信息补充回来,需要进行逐点卷积。

逐点卷积: 是使用1x1卷积对跨通道维度处理,有多少个1x1卷积核就会生成多少个特征图。

代码展示:

#(2)# 深度可分离卷积+BN+relu
def conv_block(inputs, filters, kernel_size, strides):# 深度卷积x = layers.DepthwiseConv2D(kernel_size, strides,padding='same', use_bias=False)(inputs)  # 有BN不要偏置# 逐点卷积x = layers.Conv2D(filters, kernel_size=(1,1), strides=1, padding='same', use_bias=False)(x)  x = layers.BatchNormalization()(x)x = layers.Activation('relu')(x)return x#(3)5次卷积操作提取特征减少参数量
def five_conv(x, filters):x = conv_block(x, filters, (1,1), strides=1)x = conv_block(x, filters*2, (3,3), strides=1)x = conv_block(x, filters, (1,1), strides=1)    x = conv_block(x, filters*2, (3,3), strides=1)x = conv_block(x, filters, (1,1), strides=1)return x

4. 改进的 PANet 金字塔

采用 CBAM注意力机制 和 深度可分离卷积 优化PANet金字塔。

(1)使用深度可分离卷积块代替所有的标准卷积块。

(2)在上采样Upsample和下采样Downsample之后,对输出特征图使用CBAM注意力机制。

深度可分离卷积可以显著降低模型的计算量和参数量

由于 CBAM 是轻量级的通用模块,因此可以忽略该模块的开销而将其无缝集成到任何 CNN 架构中,并且可以与基础的卷积神经网络一起进行端到端训练。实验表明,CBAM 模块在各种模型上都能够起到一定的作用,并在分类和检测性能方面对模型起到了较好的改进效果

主干网络代码如下,p5是经过SPP模块之后的第三个有效特征层,feat1和feat2分别是网络输出的第一和二个有效特征层。

#(4)主干网络
def panet(feat1, feat2, p5):# 对网络的有效输出特征层采用CBAM注意力feat1 = CBAM_attention(feat1)feat2 = CBAM_attention(feat2)p5 = CBAM_attention(p5)#(1)# 对spp结构的输出进行卷积和上采样# [13,13,512]==>[13,13,256]==>[26,26,256]p5_upsample = conv_block(p5, filters=256, kernel_size=(1,1), strides=1)p5_upsample = layers.UpSampling2D(size=(2,2))(p5_upsample)# 对feat2特征层卷积后再与p5_upsample堆叠# [26,26,512]==>[26,26,256]==>[26,26,512]p4 = conv_block(feat2, filters=256, kernel_size=(1,1), strides=1)# 上采样后使用注意力机制p4 = CBAM_attention(p4)# 通道维度上堆叠p4 = layers.concatenate([p4, p5_upsample])# 堆叠后进行5次卷积[26,26,512]==>[26,26,256]p4 = five_conv(p4, filters=256)#(2)# 对p4卷积上采样# [26,26,256]==>[26,26,512]==>[52,52,512]p4_upsample = conv_block(p4, filters=128, kernel_size=(1,1), strides=1)p4_upsample = layers.UpSampling2D(size=(2,2))(p4_upsample)# feat1层卷积后与p4_upsample堆叠# [52,52,256]==>[52,52,128]==>[52,52,256]p3 = conv_block(feat1, filters=128, kernel_size=(1,1), strides=1)# 上采样后使用注意力机制p3 = CBAM_attention(p3)# 通道维度上堆叠p3 = layers.concatenate([p3, p4_upsample])# 堆叠后进行5次卷积[52,52,256]==>[52,52,128]p3 = five_conv(p3, filters=128)# 存放第一个特征层的输出p3_output = p3#(3)# p3卷积下采样和p4堆叠# [52,52,128]==>[26,26,256]==>[26,26,512]p3_downsample = conv_block(p3, filters=256, kernel_size=(3,3), strides=2)# 下采样后使用注意力机制p3_downsample = CBAM_attention(p3_downsample)# 通道维度上堆叠p4 = layers.concatenate([p3_downsample, p4])# 堆叠后的结果进行5次卷积[26,26,512]==>[26,26,256]p4 = five_conv(p4, filters=256)# 存放第二个有效特征层的输出p4_output = p4#(4)# p4卷积下采样和p5堆叠# [26,26,256]==>[13,13,512]==>[13,13,1024]p4_downsample = conv_block(p4, filters=512, kernel_size=(3,3), strides=2)# 下采样后使用注意力机制p4_downsample = CBAM_attention(p4_downsample)# 通道维度上堆叠p5 = layers.concatenate([p4_downsample, p5])# 堆叠后进行5次卷积[13,13,1024]==>[13,13,512]p5 = five_conv(p5, filters=512)# 存放第三个有效特征层的输出p5_output = p5# 返回输出层结果return p3_output, p4_output, p5_output

查看网络架构,参数量从原来的两千多万下降到六百万

if __name__ == '__main__':# 构造输入feat1 = keras.Input(shape=[52,52,256])feat2 = keras.Input(shape=[26,26,512])p5 = keras.Input(shape=[13,13,1024])# 返回panet结果p3_output, p4_output, p5_output = panet(feat1, feat2, p5)inputs = [feat1, feat2, p5]outputs = [p3_output, p4_output, p5_output]# 构建网络model = keras.Model(inputs, outputs)model.summary()
Total params: 6,846,037
Trainable params: 6,826,837
Non-trainable params: 19,200

【目标检测】(9) 改进PANet特征提取金字塔,附Tensorflow完整代码相关推荐

  1. 【目标检测】(15) YOLOV4 损失函数,附TensorFlow完整代码

    大家好,今天和各位分享一下 YOLOV4 的损失函数的构建方法,YOLOV4和损失函数的组成和YOLOV3类似,只是YOLOV4使用了CIOU损失作为目标边界框的定位损失.强烈建议大家在阅读本文之前, ...

  2. 【神经网络】(12) MobileNetV2 代码复现,网络解析,附Tensorflow完整代码

    各位同学好,今天和大家分享一下如何使用 Tensorflow 复现谷歌轻量化神经网络 MobileNetV2. 在上一篇中我介绍了MobileNetV1,探讨了深度可分离卷积,感兴趣的可以看一下:ht ...

  3. 【YOLOV4】(7) 特征提取网络代码复现(CSPDarknet53+SPP+PANet+Head),附Tensorflow完整代码

    各位同学好,今天和大家分享一下如何使用 TensorFlow 构建YOLOV4目标检测算法的特征提取网络. 完整代码在我的Gitee中,有需要的自取:https://gitee.com/dgvv4/y ...

  4. 【神经网络】(19) ConvNeXt 代码复现,网络解析,附Tensorflow完整代码

    各位同学好,今天和大家分享一下如何使用 Tensorflow 构建 ConvNeXt 卷积神经网络模型. 论文地址:https://arxiv.org/pdf/2201.03545.pdf 完整代码在 ...

  5. 【图像分类案例】(2) DenseNet 天气图片四分类(权重迁移学习),附Tensorflow完整代码

    各位同学好,今天和大家分享一下使用 Tensorflow 构建 DenseNet 卷积神经网络模型,并使用预训练模型的权重,完成对四种天气图片的分类. 完整代码在我的 Gitee 中,有需要的自取: ...

  6. 【图像分类案例】(1) ResNeXt 交通标志四分类,附Tensorflow完整代码

    各位同学好,今天和大家分享一下如何使用 Tensorflow 构建 ResNeXt 神经网络模型,通过案例实战 ResNeXt 的训练以及预测过程.每个小节的末尾有网络.训练.预测的完整代码.想要数据 ...

  7. 【神经网络】(18) EfficientNetV2 代码复现,网络解析,附Tensorflow完整代码

    各位同学好,今天和大家分享一下如何使用 Tensorflow 搭建 EfficientNetV2 卷积神经网络模型. EfficientNetV2 在 EfficientNetV1 的基础上进行了改进 ...

  8. 【神经网络】(16) MobileNetV3 代码复现,网络解析,附Tensorflow完整代码

    各位同学好,今天和大家分享一下如何使用 Tensorflow 构建 MobileNetV3 轻量化网络模型. MobileNetV3 做了如下改动(1)更新了V2中的逆转残差结构:(2)使用NAS搜索 ...

  9. 【神经网络】(15) Xception 代码复现,网络解析,附Tensorflow完整代码

    各位同学好,今天和大家分享一下如何使用 Tensorflow 构建 Xception 神经网络模型. 在前面章节中,我已经介绍了很多种轻量化卷积神经网络模型,感兴趣的可以看一下:https://blo ...

最新文章

  1. mysql 半同步复制_Mysql半同步复制原理及问题排查
  2. 从共享租车成绿色消费首选,看共享经济未来
  3. 大马哈鱼的C#学习笔记(3):Invoke/BeginInvoke/DynamicInvoke
  4. 今天又看到的Acm指南
  5. COLINUX的安装与网络配置
  6. B. 重载技术(overloading)
  7. 信息学奥赛一本通 1073:救援 | OpenJudge NOI 1.5 19:救援
  8. c语言复杂函数转换,详解C语言常用的一些转换工具函数.pdf
  9. apscheduler executors
  10. 无人车创业正驶入分水岭
  11. oracle数据库文件默认的安装位置,Oracle 10g数据库默认安装应该注意的问题
  12. paip.环境配置整合 ibatis mybatis proxool
  13. foremost 原理和使用
  14. 原型工具Axure:通用操作(快捷键、常用元件、常用交互、元件库与母版、原型规范、小记)
  15. 如何站在巨人的肩膀上学习
  16. matlab pid buck,基于MATLAB的BUCK电路设计与PID闭环仿真
  17. STM32进入低功耗模式以及唤醒(RTC+中断)
  18. excel计算二元线性回归_用Excel做回归分析
  19. Git之深入解析如何替换数据库中的Git对象
  20. Vue ElementUI 实现 Table 多列数据 checkBox选择框

热门文章

  1. win10远程桌面连接计算机密码错误,win10远程桌面连接提示身份验证错误怎么办?...
  2. IT项目管理第八次作业
  3. nyoj523 亡命逃窜
  4. postgres-数据库自动备份
  5. 海外网红营销的概念与发展,网红是如何赚钱的?
  6. HDU 4284 Travel(12年天津 状态DP)
  7. c定义一个整型数组_C语言学习|数组
  8. 你知道的宽动态有多宽?
  9. 漫谈软件测试的心理学和经济学
  10. vue中组件间通信的6种方式