给妹纸的深度学习教学(1)——从LeNet开始
几天前,远方的妹纸给我发来微信,说她们组的导师心血来潮要搞Deep Learning,希望快速入门,让我给她指导一下,吖,我是拒绝呢,还是拒绝呢,哦?所以此系列文章,诞生了!
妹纸:花花,我们导师要我们弄深度学习,主要是图像的分类,最近我看了一些卷积神经网络的基本知识,你能给我讲讲常见的CNN架构吗,还有怎么写代码吖。
花花:唔,那我们从头最简单的架构讲起吧。(天哪,其实我也啥都不会啊,捂脸)
考虑到妹纸刚刚入门,我给她推荐了tensorflow,
又考虑到tf也不好写,我给她推荐了更high-level的Keras
用来学习的dataset,选用了cifar-10. 原因有二,一是资料量足,二是image大小不会太大,训练起来时间不至于太久,写完代码很快能看到训练的效果。
1. 所有代码都在 Github 上
2. 介于妹纸需要学习的资料,我刚好整理了一下 请戳我
花花:首先我们来讲第一个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的,还有强行帮妹纸,是不是在做死,咿??万一,明天,她还会打来呢?(可我明明也是妹纸的说!!)
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
欢迎关注公众号学习交流~
欢迎加入交流群交流学习