github地址https://github.com/huawei-noah/ghostnet
文章出自华为诺亚方舟实验室
Ghostnet的主要目的是对模型进行进一步的压缩,以便于在更少的计算量的情况下达到更好的特征提取效果,效果超过MobilenetV3。达到SOTA
1.introduction
可视化特征图后可以发现,如上图中标记的通道的特征图非常相似,就如同Ghost一样,所以就可以认为每一对相似特征图中的另一个特征图均可以由其中一个近似得到
以往压缩模型都是对模型进行prune,去掉对结果影响小的层
但作者提出,多余的特征图也是有用的,我们可以不去掉他们,而是采用一种计算开销很小的方法来近似得到
2.Approach
图中a代表的是传统的卷积,b代表GhostModule中采用的卷积方式
如第一部分所说,作者把特征图分为两部分,一部分叫做intrinsic部分,通过传统的卷积得到,我理解的就是核心的一部分特征,而其他近似的特征可以通过intrinsic部分通过简单的变换得到,最后再将这两部分在channel维度上拼接作为输出,这样就达到了减少计算量的目的,而又不会缺失特征
具体的计算量论文中有比较
下面是我自己根据论文结合自己理解写的GhostModule模块,与论文中的有差别,可以参考一下,经过depthwiseconv之后的conv1x1原文中并没有,是我自己后加的
# -*- coding: UTF-8 -*-
#!/usr/bin/python
from __future__ import absolute_import
import tensorflow as tf
import numpy as np
from core.cnn.layers import Conv
def DepthWiseConv(X, kernel_shape, stride=1, channel_mult=1,
padding='SAME',w_init = tf.truncated_normal_initializer(stddev=0.1)):
in_shape = X.get_shape().as_list()
in_channel = in_shape[3]
stride_shape = [1, stride, stride, 1]
# out_channel = in_channel * channel_mult
W = tf.get_variable('DW', [3,3,in_channel,channel_mult], initializer=w_init)
X = tf.nn.depthwise_conv2d(X, W, stride_shape, padding=padding)
return X
def GhostModule(X, kernel_size,intrinsic_out_channel, out_channel, name):
with tf.variable_scope(name):
X = Conv(X,3,intrinsic_out_channel,name='intrinsic_conv',
if_bn = False, if_se = False, if_cbam = False, if_biases = False, if_relu = False)
dw = DepthWiseConv(X, 3)
dw = Conv(dw,1,out_channel - intrinsic_out_channel,name = 'conv1x1')
X = tf.concat([X, dw], 3)
return X