SKnet,Inception思想的延续,以及SEnet的进化

前言

自13年以后出现的inception体系的网络,其主要的目的是认为识别物体所占图像的占比不同,所适合的卷积核大小不同,如下图所示,这是经典的inception V1的结构,其主要采用了大小为3,5,1的卷积核,但是这种做法也有一些粗暴,因为在设计网络的时候,不同卷积核的通道数是固定的,很难适应多种算法。
在这里插入图片描述
那么能否有一种网络模块,帮助我们针对于目标物不同占比的图像,选用不同的卷积核,答案是有的,2019CVPR的SKnet就是来解决这种问题的。
在这里插入图片描述
SKnet的基本结构如图所示,主要分为三个部分,分离,融合和选择,其中融合(红框内)采用了SEnet的思想,压缩感知。分离就是在同一层中采用不同大小卷积核,选择就选择不同大小卷积核所占的比重

代码

本节主要根据公式复现SKnet结构
在这里插入图片描述

其中的两个U都是X通过卷积得到的,实现方法:

    ############Spilt
    U1=tf.layers.conv2d(x,channel,kernel1,strides=1, padding='same')
    U2=tf.layers.conv2d(x,channel,kernel2,strides=1, padding='same')
    ############Fuse    
    U=U1+U2

在这里插入图片描述

这个公式主要是GAP,这里只用一行代码就可以实现:

S=tf.keras.layers.GlobalAvgPool2D()(U)

在这里插入图片描述
这个公式有batcnorm和relu函数,其中Ws的这个公式我们用1*1的卷积来代替:

    S=tf.reshape(S,[-1,1,1,channel])
    print(S)
    Z=tf.nn.relu(tf.layers.batch_normalization(tf.layers.conv2d(S,32,1,strides=1, padding='same'),axis=-1,momentum=0.99,epsilon=0.001, center=True, scale=True,))
    print(Z)

在这里插入图片描述

其中d的维度我们和文章选择一样,为32.

在这里插入图片描述
最后的softmax的实现比较巧妙采用了现conbine,然后在split的方案:

    a=tf.layers.conv2d(Z,channel,1,strides=1, padding='same')
    b=tf.layers.conv2d(Z,channel,1,strides=1, padding='same')
    print(a,b)
    combine=tf.concat([a,b],1)
    print(combine)
    combine=tf.nn.softmax(combine,axis=1)
    print(combine)
    a,b=tf.split(combine,num_or_size_splits=2, axis=1)
    print(a,b)

完整代码以及结果

import tensorflow as tf


x = tf.placeholder(tf.float32,[None, 224, 224, 3])#输入图片大小

def SK_block(x,kernel1,kernel2,channel):
    ############Spilt
    U1=tf.layers.conv2d(x,channel,kernel1,strides=1, padding='same')
    U2=tf.layers.conv2d(x,channel,kernel2,strides=1, padding='same')
    ############Fuse    
    U=U1+U2
    S=tf.keras.layers.GlobalAvgPool2D()(U)
    print(S)
    S=tf.reshape(S,[-1,1,1,channel])
    print(S)
    Z=tf.nn.relu(tf.layers.batch_normalization(tf.layers.conv2d(S,32,1,strides=1, padding='same'),axis=-1,momentum=0.99,epsilon=0.001, center=True, scale=True,))
    print(Z)
    a=tf.layers.conv2d(Z,channel,1,strides=1, padding='same')
    b=tf.layers.conv2d(Z,channel,1,strides=1, padding='same')
    print(a,b)
    combine=tf.concat([a,b],1)
    print(combine)
    combine=tf.nn.softmax(combine,axis=1)
    print(combine)
    a,b=tf.split(combine,num_or_size_splits=2, axis=1)
    print(a,b)
    V=a*U1+b*U2
    print(V)
    return V
    
    
    
    
    
    
    
layer1=tf.layers.conv2d(x,256,3,strides=1, padding='same')
layer1=tf.nn.relu(layer1)
SK_block(layer1,3,5,256)

输出:

Tensor("global_average_pooling2d_19/Mean:0", shape=(?, 256), dtype=float32)
Tensor("Reshape_18:0", shape=(?, 1, 1, 256), dtype=float32)
Tensor("Relu_32:0", shape=(?, 1, 1, 32), dtype=float32)
Tensor("conv2d_96/BiasAdd:0", shape=(?, 1, 1, 256), dtype=float32) Tensor("conv2d_97/BiasAdd:0", shape=(?, 1, 1, 256), dtype=float32)
Tensor("concat_18:0", shape=(?, 2, 1, 256), dtype=float32)
Tensor("transpose_11:0", shape=(?, 2, 1, 256), dtype=float32)
Tensor("split_3:0", shape=(?, 1, 1, 256), dtype=float32) Tensor("split_3:1", shape=(?, 1, 1, 256), dtype=float32)
Tensor("add_21:0", shape=(?, 224, 224, 256), dtype=float32)
  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值