shuffleNet之原理及tensorflow实现

为了解决常规模型过大且计算量过大,除了出现mobilenet属于轻量级网络,shuffleNet同样也为新型的轻量级网络,shuffleNet主要由group convolution跟channel shuffle两部分组成.

Group convolution:

对于常规卷积,假如输入Dk*Dk*m的tensor,使用n个大小为Dw*Dw的卷积核进行卷积,输出Dk*Dk*n的tensor.

而对于分组卷积,我们对输入的Dk*Dk*m进行按channel切分分成s份,每份大小为Dk*Dk*m/s,,然后将n个大小为Dw*Dw的卷积核也平均分成s份.每份拥有n/s个卷积核,分别与s份输入tensor进行卷积.每一份都分别卷积都输出Dk*Dk*n/s的tensor,再将s份Dk*Dk*n/s进行channel的concat,最终得出Dk*Dk*n的tensor.

对比与常规卷积的参数大小: Dw*Dw*m*n

而对于分组卷积的参数大小: Dw*Dw*m/s * n/s *s = Dw*Dw*m*n/s ,比原来缩小了s倍.

具体的卷积图可参考如下:

常规卷积:

分组卷积:

 

Channel shuffle:

因为groupconvolution会导致channel具有局部性,这样对模型的泛化能力有点弱,影响模型的准确率,因此加入channel shuffle,对groupconvolotion的卷积结果进行channel的shuffle,将输出的channel进行重新分组.

具体的实现图如下:

 

但channel shuffle具有以下缺点:

(1). channel shuffle需要很多的指针跳转和Memory set,这种计算操作比较耗时间.

(2). channel shuffle的shuffle规则是人定的,不是训练得出,不符合网络负反馈学习的规则.

 

shuffleNet:

shuffleNet是对resnet结构了,使用了group convolution跟channel shuffle:

图中a跟b是sufllenet_v1结构图,区别在于输出是否缩放尺寸.注意GConv(group convolution)卷积,输入跟输出的channel是一致的

图中c跟d是sufllenet_v2结构图,对比sufllenet_v1,sufllenet_v2将GConv更改回常规的Conv,c跟d的区别在于输出是否缩放尺寸,且c中加了一个channel Split,对输入的channel分割成两部分,一部分进行卷及操作,一部分直接往下走,在最后与另一部分进行cancat.

 

他人实验结果:

可以看出.

在相同的浮点数计算量的条件下做比较,shuffleNet的准确率是高于mobileNet,但速度却慢与mobileNet.

 

group convolution跟channel shuffle的tensorflow代码实现如下:

def channel_shuffle(x, num_groups):
     with tf.variable_scope('channel_shuffle'):
        n, h, w, c = x.shape.as_list()
        x_reshaped = tf.reshape(x, [-1, h, w, num_groups, c // num_groups])
        x_transposed = tf.transpose(x_reshaped, [0, 1, 2, 4, 3])
        output = tf.reshape(x_transposed, [-1, h, w, c])
        return output
    
def shuffle_conv(x, input_filters, output_filters, kernel, strides , mode , num_groups=4):
    with tf.variable_scope('shuffle_conv'):
        conv_side_layers_tmp = tf.split(x, num_groups ,3)
        conv_side_layers = []
        for layers in conv_side_layers_tmp:
             conv_side_layers.append(conv(layers, input_filters//num_groups, output_filters//num_groups, kernel, strides ))
        x = tf.concat(conv_side_layers, axis=-1)
        x = channel_shuffle(x , num_groups)
        return x

对shuffleNet的个人看法:

官方测试,在相同的条件下,shuffleNet的准确率是优于mobilenet网络.

但个人实验,模型大小可以成倍数的降低,卷积效果也能媲美普通卷积,但速度,并不会因为卷积参数的减少而相同减少,主要在与无法并行化计算,出现碎片化,时间耗时基本与常用卷积基本持平.

 

 

你可能感兴趣的:(机器学习,tensorflow,图像)