查看原文
其他

给妹纸的深度学习教学(1)——从LeNet开始

2017-08-21 李韡 机器学习算法与自然语言处理


1蒙圈的我


几天前,远方的妹纸给我发来微信,说她们组的导师心血来潮要搞Deep Learning,希望快速入门,让我给她指导一下,吖,我是拒绝呢,还是拒绝呢,哦?所以此系列文章,诞生了!


妹纸:花花,我们导师要我们弄深度学习,主要是图像的分类,最近我看了一些卷积神经网络的基本知识,你能给我讲讲常见的CNN架构吗,还有怎么写代码吖。
花花:唔,那我们从头最简单的架构讲起吧。(天哪,其实我也啥都不会啊,捂脸)

  • 考虑到妹纸刚刚入门,我给她推荐了tensorflow,

  • 又考虑到tf也不好写,我给她推荐了更high-level的Keras

  • 用来学习的dataset,选用了cifar-10. 原因有二,一是资料量足,二是image大小不会太大,训练起来时间不至于太久,写完代码很快能看到训练的效果。


1. 所有代码都在  Github 上      
2. 介于妹纸需要学习的资料,我刚好整理了一下  请戳我


2从LeNet开始


花花:首先我们来讲第一个CNN Architecture : LeNet ,它的架构图如下:



  • input: 在原始的架构中,神经网络的输入是一张  的灰度图像,不过这里我们选用的dataset是cifar10,是RGB图像,也就是  噢

  • conv1: 第一层是一个卷积层啦,卷积核(kernel size)大小  ,步长(stride)为  ,不进行padding哦,所以刚才的输入图像,经过这层后会输出6张  的特征图(feature map)

  • maxpooling2: 接下来是一个降采样层,用的是maxpooling哦,stride为  , kernel size为  ,恩,所以很明显subsampling之后,输出6张 的feature map哦

  • conv3: 第三层又是一个卷积层,kernel size和stride均与第一层相同噢,不过最后要输出16张feature map哦

  • maxpooling4:第四层,恩,又是一个maxpooling

  • fc5:对,第五层开始就是全连接(fully connected layer)层了哦,把第四层的feature map摊平,然后做最直白的举证运算哦,输入是120个结点

  • fc6:输出是84个结点哦

  • output:我们的dataset是cifar10,刚好也是10类哦,所以就是接一个softmax分成10类哦

  • 如果你看不太懂为什么卷积核是这样计算的,下面是两个非常不错的教程

    • Convolutional Neural Networks

    • CNN Architectures

    • YouTube 视频

妹纸:恩,这个架构看起来还是比较简单,你讲得我大概懂了哦,那代码要怎么写呢?
花花:恩,我准备了4份代码,一一来看吧,shy


第一份简单的代码


花花:main函数里面的东西你先不要管哦,就是用来读取training data以及进行训练的,
我们先来看build_model()这个函数。

  • 最开始有一个Sequential模型,中文好像叫做序贯模型??它用于多个网络层的线性堆叠,也就是“一条路走到黑”,所以我们后面都在用model.add来添加新的layer啦。

  • 紧接着就是Conv2D,这个是keras内建的卷积层哦,具体的参数你可以在官方文档里面找到噢,当然,还有某群聚聚们写的Keras中文文档哦。你可以看到我这里设置了输出卷积核的数目,卷积核的大小,移动的步长,激活函数等等哦。

  • 再来就是MaxPooling2D,池化层啦,也很简单哦,按照我们前面介绍的架构来写参数就对了。

  • 最后是用Flatten层来将输入“压平”,然后用最常用的全连接Dense层啦,记得最后的激活函数是softmax哦。

  • 然后我们需要确定我们的目标函数,以及我们的优化器,并用compile把它们编译起来(这里我们的loss是cross entropy,opt是SGD,嗯嗯)
    这样,整个model就完成啦,就才几行,是不是很简单!

妹纸:恩,代码只有不到60行,还是很容易看懂的。
花花:恩,这份代码很“朴实”,没有加其他任何trick,不过它的效果不太好噢。


花花:刚才的代码LeNet_keras.py,我们训练180个epoch,在GTX980TI上仅仅需要6分36秒的时间。但是它的testing准确度只有53.87%(图中的桔黄色线),好低啊。


一点点修改:数据预处理(data prepossessing)


我们只对第一份代码改一个地方:
LeNet_keras.py LeNet_dp_keras.py


花花:对,就是把原来的数据只是除以255,换成减掉自己的均值再除以自己的标准差
这是一个很常见的数据预处理(数据归一化)喔,要记得啦
然后我们再重新training一次,这次得到的testing准确度达到了61.97%(图中的浅蓝色线)


再来一点改进:数据增强(data augmentation)


我们来看看training 的loss,你会发现,overfitting很严重啊,那我再教你一招,简单的数据增强,这里我们就以 随机水平翻转 和 图片水平/垂直偏移 为例吧,还是只要改一小段代码:

LeNet_dp_keras.py LeNet_dp_da_keras.py


同样,我们再训练一次,这次训练的时间变长了,需要30分钟,原因是我们在每次迭代前都会对数据做在线的变换,但是,很明显可以看到,这次训练得到的testing准确度达到了75.28%(图中的紫色线),远高于前面,对,这就是data augmentation的厉害之处。


再做一点小改进:权值衰减(weight decay)


妹纸:对了,我记得书上有个东西叫做权值衰减,那个是什么啊,也可以提高准确度吗?
花花:权值衰减也可以防止过度拟合哦,哈哈,我刚好也帮你实现了一下:

LeNet_dp_da_keras.py LeNet_dp_da_wd_keras.py

还是一样再次训练,这次的testing准确度达到了76.11%,又比刚才高了。
看吧,书上说的,还是管用的吧,虽然你实践地少,但是还是学到不少嘛。

回过头分析准确率

花花:同样的架构,运用不同的trick,也会得到不同的结果,当然我今天只是和你讲了很少的一部分,不过你回去要练习自己写一下代码哦,下一次,我们讲NIN(Network in Network)唔.
妹纸:嗯嗯,好的,我回去也用keras写一下。
花花:恩,我陆陆续续给和你讲Vgg19 Network,Residual Network,Wide Residual Network,ResNeXt,DenseNet哦,这些都架构都可以把cifar10的测试准确率提高到90%以上哦,甚至95%以上哦,另外,记得多翻文档哦,加油啦。
妹纸:嗯嗯,谢谢花花喔,今天好开心!!明天再聊噢!

......

......

微信的语音通话结束了,我陷入了沉思,明明就不是搞CNN的,还有强行帮妹纸,是不是在做死,咿??万一,明天,她还会打来呢?(可我明明也是妹纸的说!!)


3会涉及的paper


  • The first CNN model: LeNet-5 - Yann LeCun

  • Network in Network: Network In Network

  • Vgg19Network: Very Deep Convolutional Networks for Large-Scale Image Recognition

  • Residual Network:  

    • Deep Residual Learning for Image Recognition

    • Identity Mappings in Deep Residual Networks

  • Wide Residual Network: Wide Residual Networks

  • ResNeXt(TODO):  Aggregated Residual Transformations for Deep Neural Networks

  • DenseNet(TODO)  Densely Connected Convolutional Networks


下一篇: 给妹纸的深度学习教学(2)——拿NIN试水
下下篇: 给妹纸的深度学习教学(3)——用VGG19开荒


公众号回复20170821,即可获得文章代码github地址,祝好!

推荐阅读:

精选干货|近半年干货目录汇总

干货|台湾大学林轩田机器学习基石课程学习笔记5 -- Training versus Testing

干货|MIT线性代数课程精细笔记[第一课]


               欢迎关注公众号学习交流~          

欢迎加入交流群交流学习


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存