HTML5技术

【深度学习系列】用PaddlePaddle和Tensorflow实现经典CNN网络GoogLeNet - Charlot

字号+ 作者:H5之家 来源:H5之家 2017-12-21 09:26 我要评论( )

【深度学习系列】用PaddlePaddle和Tensorflow实现经典CNN网络GoogLeNet 前面讲了LeNet、AlexNet和Vgg,这周来讲讲GoogLeNet。GoogLeNet是由google的Christian Szegedy等人在2014年的论文《Going Deeper with Convolutions》提出,其最大的亮点是提出一种叫In

【深度学习系列】用PaddlePaddle和Tensorflow实现经典CNN网络GoogLeNet

  前面讲了LeNet、AlexNet和Vgg,这周来讲讲GoogLeNet。GoogLeNet是由google的Christian Szegedy等人在2014年的论文《Going Deeper with Convolutions》提出,其最大的亮点是提出一种叫Inception的结构,以此为基础构建GoogLeNet,并在当年的ImageNet分类和检测任务中获得第一,ps:GoogLeNet的取名是为了向YannLeCun的LeNet系列致敬。

(本系列所有代码均在github:https://github.com/huxiaoman7/PaddlePaddle_code)

关于深度网络的一些思考

  在本系列最开始的几篇文章我们讲到了卷积神经网络,设计的网络结构也非常简单,属于浅层神经网络,如三层的卷积神经网络等,但是在层数比较少的时候,有时候效果往往并没有那么好,在实验过程中发现,当我们尝试增加网络的层数,或者增加每一层网络的神经元个数的时候,对准确率有一定的提升,简单的说就是增加网络的深度与宽度,但这样做有两个明显的缺点:

  •  更深更宽的网络意味着更多的参数,提高了模型的复杂度,从而大大增加过拟合的风险,尤其在训练数据不是那么多或者某个label训练数据不足的情况下更容易发生;
  • 增加计算资源的消耗,实际情况下,不管是因为数据稀疏还是扩充的网络结构利用不充分(比如很多权重接近0),都会导致大量计算的浪费。
  •   解决以上两个问题的基本方法是将全连接或卷积连接改为稀疏连接。不管从生物的角度还是机器学习的角度,稀疏性都有良好的表现,回想一下在讲AlexNet这一节提出的Dropout网络以及ReLU激活函数,其本质就是利用稀疏性提高模型泛化性(但需要计算的参数没变少)。 
      简单解释下稀疏性,当整个特征空间是非线性甚至不连续时:

  •  学好局部空间的特征集更能提升性能,类似于Maxout网络中使用多个局部线性函数的组合来拟合非线性函数的思想;
  • 假设整个特征空间由N个不连续局部特征空间集合组成,任意一个样本会被映射到这N个空间中并激活/不激活相应特征维度,如果用C1表示某类样本被激活的特征维度集合,用C2表示另一类样本的特征维度集合,当数据量不够大时,要想增加特征区分度并很好的区分两类样本,就要降低C1和C2的重合度(比如可用Jaccard距离衡量),即缩小C1和C2的大小,意味着相应的特征维度集会变稀疏。
  •   不过尴尬的是,现在的计算机体系结构更善于稠密数据的计算,而在非均匀分布的稀疏数据上的计算效率极差,比如稀疏性会导致的缓存miss率极高,于是需要一种方法既能发挥稀疏网络的优势又能保证计算效率。好在前人做了大量实验(如《On Two-Dimensional Sparse Matrix Partitioning: Models, Methods, and a Recipe》),发现对稀疏矩阵做聚类得到相对稠密的子矩阵可以大幅提高稀疏矩阵乘法性能,借鉴这个思想,作者提出Inception的结构。

     

     图1 Inception结构

    这个网络的最大问题是5×5卷积带来了巨大计算负担,例如,假设上层输入为:28×28×192:

  • 直接经过96个5×5卷积层(stride=1,padding=2)后,输出为:28×28×96,卷积层参数量为:192×5×5×96=460800;
  • 借鉴NIN网络(Network in Network,后续会讲),在5×5卷积前使用32个1×1卷积核做维度缩减,变成28×28×32,之后经过96个5×5卷积层(stride=1,padding=2)后,输出为:28×28×96,但所有卷积层的参数量为:192×1×1×32+32×5×5×96=82944,可见整个参数量是原来的1/5.5,且效果上没有多少损失。 
    新网络结构为
  •  

     图2 新Inception结构

     

     

     GoogLeNet网络结构

      利用上述Inception模块构建GoogLeNet,实验表明Inception模块出现在高层特征抽象时会更加有效(我理解由于其结构特点,更适合提取高阶特征,让它提取低阶特征会导致特征信息丢失),所以在低层依然使用传统卷积层。整个网路结构如下:

     图3 GoogLeNet网络结构

     

     图4 GoogLeNet详细网络结构示意图

    网络说明:

    网络结构详细说明: 

      输入数据为224×224×3的RGB图像,图中"S"代表做same-padding,"V"代表不做。

  • Inception (3a):由4部分组成 
  • Inception (3b):由4部分组成 
  •  

    用PaddlePaddle实现GoogLeNet

      1.网络结构 googlenet.py

      在PaddlePaddle的models下面,有关于GoogLeNet的实现代码,大家可以直接学习拿来跑一下:

    1 import paddle.v2 as paddle = [] inception(name, input, channels, filter1, filter3R, filter3, filter5R, 7 filter5, proj): 8 cov1 = paddle.layer.img_conv( , 10 input=input, 11 filter_size=1, 12 num_channels=channels, 13 num_filters=filter1, 14 stride=1, 15 padding=0) 16 17 cov3r = paddle.layer.img_conv( , 19 input=input, 20 filter_size=1, 21 num_channels=channels, 22 num_filters=filter3R, 23 stride=1, 24 padding=0) 25 cov3 = paddle.layer.img_conv( , 27 input=cov3r, 28 filter_size=3, 29 num_filters=filter3, 30 stride=1, 31 padding=1) 32 33 cov5r = paddle.layer.img_conv( , 35 input=input, 36 filter_size=1, 37 num_channels=channels, 38 num_filters=filter5R, 39 stride=1, 40 padding=0) 41 cov5 = paddle.layer.img_conv( , 43 input=cov5r, 44 filter_size=5, 45 num_filters=filter5, 46 stride=1, 47 padding=2) 48 49 pool1 = paddle.layer.img_pool( , 51 input=input, 52 pool_size=3, 53 num_channels=channels, 54 stride=1, 55 padding=1) 56 covprj = paddle.layer.img_conv( , 58 input=pool1, 59 filter_size=1, 60 num_filters=proj, 61 stride=1, 62 padding=0) 63 64 cat = paddle.layer.concat(name=name, input=[cov1, cov3, cov5, covprj]) 65 return cat googlenet(input, class_dim): conv1 = paddle.layer.img_conv( , 72 input=input, 73 filter_size=7, 74 num_channels=3, 75 num_filters=64, 76 stride=2, 77 padding=3) 78 pool1 = paddle.layer.img_pool( , input=conv1, pool_size=3, num_channels=64, stride=2) conv2_1 = paddle.layer.img_conv( , 84 input=pool1, 85 filter_size=1, 86 num_filters=64, 87 stride=1, 88 padding=0) 89 conv2_2 = paddle.layer.img_conv( , 91 input=conv2_1, 92 filter_size=3, 93 num_filters=192, 94 stride=1, 95 padding=1) 96 pool2 = paddle.layer.img_pool( , input=conv2_2, pool_size=3, num_channels=192, stride=2) ince3a = inception(, pool2, 192, 64, 96, 128, 16, 32, 32) , ince3a, 256, 128, 128, 192, 32, 96, 64) 102 pool3 = paddle.layer.img_pool( , input=ince3b, num_channels=480, pool_size=3, stride=2) ince4a = inception(, pool3, 480, 192, 96, 208, 16, 48, 64) , ince4a, 512, 160, 112, 224, 24, 64, 64) , ince4b, 512, 128, 128, 256, 24, 64, 64) , ince4c, 512, 112, 144, 288, 32, 64, 64) , ince4d, 528, 256, 160, 320, 32, 128, 128) 111 pool4 = paddle.layer.img_pool( , input=ince4e, num_channels=832, pool_size=3, stride=2) ince5a = inception(, pool4, 832, 256, 160, 320, 32, 128, 128) , ince5a, 832, 384, 192, 384, 48, 128, 128) 117 pool5 = paddle.layer.img_pool( , 119 input=ince5b, 120 num_channels=1024, 121 pool_size=7, 122 stride=7, 123 pool_type=paddle.pooling.Avg()) 124 dropout = paddle.layer.addto( 125 input=pool5, 126 layer_attr=paddle.attr.Extra(drop_rate=0.4), 127 act=paddle.activation.Linear()) 128 129 out = paddle.layer.fc( 130 input=dropout, size=class_dim, act=paddle.activation.Softmax()) pool_o1 = paddle.layer.img_pool( , 135 input=ince4a, 136 num_channels=512, 137 pool_size=5, 138 stride=3, 139 pool_type=paddle.pooling.Avg()) 140 conv_o1 = paddle.layer.img_conv( , 142 input=pool_o1, 143 filter_size=1, 144 num_filters=128, 145 stride=1, 146 padding=0) 147 fc_o1 = paddle.layer.fc( , 149 input=conv_o1, 150 size=1024, 151 layer_attr=paddle.attr.Extra(drop_rate=0.7), 152 act=paddle.activation.Relu()) 153 out1 = paddle.layer.fc( 154 input=fc_o1, size=class_dim, act=paddle.activation.Softmax()) pool_o2 = paddle.layer.img_pool( , 159 input=ince4d, 160 num_channels=528, 161 pool_size=5, 162 stride=3, 163 pool_type=paddle.pooling.Avg()) 164 conv_o2 = paddle.layer.img_conv( , 166 input=pool_o2, 167 filter_size=1, 168 num_filters=128, 169 stride=1, 170 padding=0) 171 fc_o2 = paddle.layer.fc( , 173 input=conv_o2, 174 size=1024, 175 layer_attr=paddle.attr.Extra(drop_rate=0.7), 176 act=paddle.activation.Relu()) 177 out2 = paddle.layer.fc( 178 input=fc_o2, size=class_dim, act=paddle.activation.Softmax()) out, out1, out2

     

      2.训练模型

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • IT连创业系列:App产品上线后,运营怎么搞?(中) - 路过秋天

      IT连创业系列:App产品上线后,运营怎么搞?(中) - 路过秋天

      2017-12-01 11:10

    • IT连创业系列:App产品上线后,运营怎么搞?(上) - 路过秋天

      IT连创业系列:App产品上线后,运营怎么搞?(上) - 路过秋天

      2017-11-29 08:59

    • Vue 学习之el、template、replace和vue的生命周期 参考网址:https://segmentfaul

      Vue 学习之el、template、replace和vue的生命周期 参考网址:https:/

      2017-11-27 11:09

    • 【深度学习系列】卷积神经网络详解(二)——自己手写一个卷积神经网络 - Charlotte77

      【深度学习系列】卷积神经网络详解(二)——自己手写一个卷积神经网络

      2017-11-23 08:01

    网友点评