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