2.1 SqueezeNet V1思考

作者: 深度学习模型优化 | 来源:发表于2019-04-16 15:39 被阅读3次

SqueezeNet知乎文章

  • SqueezeNetV1
  • SqueezeNetV2

1 动机

         我们的目标是

  • 在达到一定的精度的条件下,最大程度的提高运算速度

         主要从两个方向来优化模型设计:

  • 降低参数数量
  • 降低网络的计算量

这么做的优点有:

  • forward速度更快
  • 模型参数文件小,利于存储和传输
  • 对运算内存的要求更低

2 SqueezeNet分析

模型优化策略:

  • 3\times 3卷积替换成1\times 1卷积
  • 减少3\times 3卷积的通道数
  • 将降采样后置

SqueezeNet的核心模块是Fire模块,其由Squeeze部分和Expand部分组成。如下图所示。


图1 Fire模块
  • squeeze部分由多个1\times 1卷积核构成
  • expand部分由多个1\times 13\times 3卷积核构成
    假设squeeze部分的1\times 1卷积核的数量为s_{1\times 1},expand部分的1\times 1卷积核的数量为e_{1\times 1}3\times 3卷积核的数量为e_{3 \times 3}。SqueezeNet作者建议s_{1\times 1} < e_{1\times 1} + e_{3 \times 3}。可以设置
    s_{1\times 1} = \frac {e_{1\times 1}}{4} = \frac {e_{3 \times 3}}{4}
    下面的代码是用keras实现的,可以参考:
def fire(x, s_1x1, e_1x1, e_3x3, fire_name):
  # squeeze part
  squeeze_x = Conv2D(kernel_size = (1, 1), filters = s_1x1, padding='same', activation='relu', name = fire_name + '_s1')(x)
  # expand part
  expand_x_1 = Conv2D(kernel_size = (1, 1), filter = e_1x1, padding = 'same', activation='relu', name = fire_name + '_e1')(squeeze_x)
  expand_x_3 = Conv2D(kernel_size = (3,3), filter = e_3x3, padding = 'same', activation = 'relu', name = fire_name + '_e3')(squeeze_x)
  expand = merge([expand_x_1, expand_x_3], mode = 'concat', concat_axis=3)
  return expand
图2 SqueezeNet的典型示例
         图2中输入特征图个数为96,,输出特征图的个数为128,一般来说特征图个数为64或者128就能保证网络的表示能力已经不错了,后面就是要注意寻优的工作。

3 SqueezeNet的一些结构

在fire模块组合设计中有一些原则:

  • 使用ReLU
  • fire9使用0.5的dropout
  • 使用same卷积
    卷积没有使用降采样,使用池化进行降采样
图3 SqueezeNet网络结构

下面代码是keras的简单实现

def SqueezeNet(x):
  conv1 = Conv2D(input_shape=(224, 224, 3), stride=2, filter=96, kernel_size=(7, 7), padding='same', activation='relu')(x)
  pool1 = MaxPool2D((2, 2))(conv1)
  fire2 = fire(pool1, 16, 64, 64, 'fire2')
  fire3 = fire(fire2, 16, 64, 64, 'fire3')
  fire4 = fire(fire3, 32, 128, 128, 'fire4')
  pool2 = MaxPool2D((2, 2))(fire4)
  fire5 = fire(pool2, 32, 128, 128, 'fire5')
  fire6 = fire(fire5, 48, 192, 192, 'fire6')
  fire7 = fire(fire6, 48, 192, 192, 'fire7')
  fire8 = fire(fire7, 64, 256, 256, 'fire8')
  pool3 = MaxPool2D((2, 2))(fire8)
  fire9 = fire(pool3, 64, 256, 256, 'fire9')
  dropout1 = Dropout(0.5)(fire9)
  conv10 = Conv2D(kernel_size=(1, 1), filters = 1000, padding='same', activation='relu')(dropout1)
  gap = GlobalAveragePooling2D()(conv10)
  return gap

最后将结果送入softmax分类器进行分类即可。当然也可以使用迁移学习的方法来做。

4 SqueezeNet的缺点

  • SqueezeNet的侧重的应用方向是嵌入式环境,目前嵌入式环境主要问题是实时性。SqueezeNet的通过更深的深度置换更少的参数数量虽然能减少网络的参数,但是其丧失了网络的并行能力,测试时间反而会更长,这与目前的主要挑战是背道而驰的;
  • 纸面上是减少了50倍的参数,但是问题的主要症结在于AlexNet本身全连接节点过于庞大,50倍参数的减少和SqueezeNet的设计并没有关系,考虑去掉全连接之后3倍参数的减少更为合适。
  • SqueezeNet得到的模型是5MB左右,0.5MB的模型还要得益于Deep Compression。虽然Deep Compression也是这个团队的文章,但是将0.5这个数列在文章的题目中显然不是很合适。

相关文章

网友评论

    本文标题:2.1 SqueezeNet V1思考

    本文链接:https://www.haomeiwen.com/subject/govbwqtx.html