attention机制SENET、CBAM模块原理总结

参考博客:https://blog.csdn.net/weixin_33602281/article/details/85223216

def cbam_module(inputs,reduction_ratio=0.5,name=""):
    with tf.variable_scope("cbam_"+name, reuse=tf.AUTO_REUSE):
        #假如输入是[batsize,h,w,channel],
        #channel attension 因为要得到batsize * 1 * 1 * channel,它的全连接层第一层
      #隐藏层单元个数是channel / r, 第二层是channel,所以这里把channel赋值给hidden_num
        batch_size,hidden_num=inputs.get_shape().as_list()[0],inputs.get_shape().as_list()[3]
 
       #通道attension
        #全局最大池化,窗口大小为h * w,所以对于这个数据[batsize,h,w,channel],他其实是求每个h * w面积的最大值
      #这里实现是先对h这个维度求最大值,然后对w这个维度求最大值,平均池化也一样
        maxpool_channel=tf.reduce_max(tf.reduce_max(inputs,axis=1,keepdims=True),axis=2,keepdims=True)
        avgpool_channel=tf.reduce_mean(tf.reduce_mean(inputs,axis=1,keepdims=True),axis=2,keepdims=True)
        
        #上面全局池化结果为batsize * 1 * 1 * channel,它这个拉平输入到全连接层
      #这个拉平,它会保留batsize,所以结果是[batsize,channel]
        maxpool_channel = tf.layers.Flatten()(maxpool_channel)
        avgpool_channel = tf.layers.Flatten()(avgpool_channel)
        
        #将上面拉平后结果输入到全连接层,第一个全连接层hiddensize = channel/r = channel * reduction_ratio,
      #第二哥全连接层hiddensize = channel
        mlp_1_max=tf.layers.dense(inputs=maxpool_channel,units=int(hidden_num*reduction_ratio),name="mlp_1",reuse=None,activation=tf.nn.relu)
        mlp_2_max=tf.layers.dense(inputs=mlp_1_max,units=hidden_num,name="mlp_2",reuse=None)
        #全连接层输出结果为[batsize,channel],这里又降它转回到原来维度batsize * 1 * 1 * channel,
       mlp_2_max=tf.reshape(mlp_2_max,[batch_size,1,1,hidden_num])
 
        mlp_1_avg=tf.layers.dense(inputs=avgpool_channel,units=int(hidden_num*reduction_ratio),name="mlp_1",reuse=True,activation=tf.nn.relu)
        mlp_2_avg=tf.layers.dense(inputs=mlp_1_avg,units=hidden_num,name="mlp_2",reuse=True)
        mlp_2_avg=tf.reshape(mlp_2_avg,[batch_size,1,1,hidden_num])
 
        #将平均和最大池化的结果维度都是[batch_size,1,1,channel]相加,然后进行sigmod,维度不变
        channel_attention=tf.nn.sigmoid(mlp_2_max+mlp_2_avg)
         #和最开始的inputs相乘,相当于[batch_size,1,1,channel] * [batch_size,h,w,channel]
       #只有维度一样才能相乘,这里相乘相当于给每个通道作用了不同的权重
        channel_refined_feature=inputs*channel_attention
 
       
        #空间attension
        #上面得到的结果维度依然是[batch_size,h,w,channel],
      #下面要进行全局通道池化,其实就是一条通道里面那个通道的值最大,其实就是对channel这个维度求最大值
      #每个通道池化相当于将通道压缩到了1维,有两个池化,结果为两个[batch_size,h,w,1]feature map
        maxpool_spatial=tf.reduce_max(inputs,axis=3,keepdims=True)
        avgpool_spatial=tf.reduce_mean(inputs,axis=3,keepdims=True)

        #将两个[batch_size,h,w,1]的feature map进行通道合并得到[batch_size,h,w,2]的feature map
        max_avg_pool_spatial=tf.concat([maxpool_spatial,avgpool_spatial],axis=3)

       #然后对上面的feature map用1个7*7的卷积核进行卷积得到[batch_size,h,w,1]的feature map,因为是用一个卷积核卷的
     #所以将2个输入通道压缩到了1个输出通道
        conv_layer=tf.layers.conv2d(inputs=max_avg_pool_spatial, filters=1, kernel_size=(7, 7), padding="same", activation=None)
      #然后再对上面得到的[batch_size,h,w,1]feature map进行sigmod,这里为什么要用一个卷积核压缩到1个通道,相当于只得到了一个面积的值
     #然后进行sigmod,因为我们要求的就是feature map面积上不同位置像素的中重要性,所以它压缩到了一个通道,然后求sigmod
        spatial_attention=tf.nn.sigmoid(conv_layer)
 
       #上面得到了空间attension feature map [batch_size,h,w,1],然后再用这个和经过空间attension作用的结果相乘得到最终的结果
     #这个结果就是经过通道和空间attension共同作用的结果
        refined_feature=channel_refined_feature*spatial_attention
 
    return refined_feature
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值