哈哈?偶然在知乎上翻到了我旭神对CNN原理的通俗易懂的解释,看完以后简直醍醐灌顶呢。
下面上头像!!
哼,赶紧记录一下加强一下理解!
转自知乎我旭神
如果学过数字图像处理,对于卷积核的作用应该不陌生,比如你做一个最简单的方向滤波器,那就是一个二维卷积核,这个核其实就是一个模板,利用这个模板再通过卷积计算的定义就可以计算出一幅新的图像,新的图像会把这个卷积核所体现的特征突出显示出来。比如这个卷积核可以侦测水平纹理,那卷积出来的图就是原图水平纹理的图像。现在假设要做一个图像的分类问题,比如辨别一个图像里是否有一只猫,我们可以先判断是否有猫的头,猫的尾巴,猫的身子等等,如果这些特征都具备,那么我就判定这应该是一只猫(如果用心的话你就会发现这就是CNN最后的分类层,这一部分是我们传统的神经网络的范畴)。关键在于这些特征是高级的语义特征,这种特征怎么用卷积核提取呢?原来的卷积核都是人工事先定义好的,是经过算法设计人员精心设计的,他们发现这样或那样的设计卷积核通过卷积运算可以突出一个什么样的特征,于是就高高兴兴的拿去卷积了。但是现在我们所需要的这种特征太高级了,而且随任务的不同而不同,人工设计这样的卷积核非常困难。于是,利用机器学习的思想,我们可以让他自己去学习出卷积核来!也就是学习出特征!如前所述,判断是否是一只猫,只有一个特征不够,比如仅仅有猫头是不足的,因此需要多个高级语义特征的组合,所以应该需要多个卷积核,这就是为什么需要学习多个卷积核的原因。还有一个问题,那就是为什么CNN要设计这么多层呢?首先,应该要明白,猫的头是一个特征,但是对于充斥着像素点的图像来说,用几个卷积核直接判断存在一个猫头的还是太困难,怎么办?简单,把猫头也作为一个识别目标,比如猫头应该具有更底层的一些语义特征,比如应该有猫的眼睛、猫的耳朵、猫的鼻子等等。这些特征有的还是太高级了,没关系,继续向下寻找低级特征,一直到最低级的像素点,这样就构成了多层的神经网络。最好,CNN最不好理解的就要放大招了。虽然我们之前一直用一些我们人常见的语义特征做例子,但是实际上CNN会学习出猫头、猫尾巴、猫身然后经判定这是猫吗?显然我们的CNN完全不知道什么叫猫头、猫尾巴,也就是说,CNN不知道什么是猫头猫尾巴,它学习到的只是一种抽象特征,甚至可能有些特征在现实世界并没有对应的名词,但是这些特征组合在一起计算机就会判定这是一只猫!关于这一点,确实有些难以理解,比如一个人判断猫是看看有没有猫头、猫身子、猫尾巴,但是另一个选取的特征就是有没有猫的毛,猫的爪子,还有的人更加奇怪,他会去通过这张图像里是不是有老鼠去判断,而我们的CNN,则是用它自己学习到的特征去判断。
—————————————————分割线—————————————————————
最近又看了一些资料,在此纠正和阐明一些问题。目前CNN的可视化是一个很火的方向了,有些论文中已经提到了中间的卷积层特征其实也是具有现实的语义意义的,但是只是不那么清晰。CNN称之为深度学习,要义就在这个深字上,对于CNN而言,这个深其实就是意味着层层的特征表示。比如浅层的特征,例如点、线、面之类的简单几何形状,都是在底层训练出来的,对于这些底层的特征继续进行组合表示,就是后面的若干层的任务。最后把从低级特征组合而来的高级特征在进一步变成语义特征,就可以使用全连接层进行分类了。也就是说,最后一次分类并不一定要用神经网络,如果已经拿到了足够好的特征信息,使用其余的分类器也未尝不可。这就是为什么CNN可以fine-tune的原因,例如你要完成一个分类猫和狗的任务,你需要从头训练一个CNN网络吗?假设你的猫狗图片样本量并不是很大,这并不是一个好主意。好的办法是,拿一个经过大型图像数据集,你如ImageNet,训练过的大规模CNN(比如VGG NET)直接载入训练,这个过程称之为fine-tuning。因为这个CNN底层已经训练到了丰富的细节信息,你所需要训练的其实是上层对这些特征的组合信息,以及最后全连接层的分类信息,所以完全不需要从头再来。这也证明了CNN确实可以有迁移学习的能力。
——————————————————分割线————————————————————
之前有一点没有说,今天没啥事补充一下,也算是做个记录。CNN的部件其实大致分为三个,卷积层、池化层、全连接层,这也是LeNet-5的经典结构,之后大部分CNN网络其实都是在这三个基本部件上做各种组合和改进。卷积层之前已经介绍过了,全连接层就是连在最后的分类器,是一个普通的bp网络,实际上如果训练得到的特征足够好,这里也可以选择其他的分类器,比如SVM等。那么池化层是干什么的呢?池化,英文是pooling,字面上看挺难懂,但其实这可能是CNN里最简单的一步了。我们可以不按字面理解,把它理解成下采样(subsampling)。池化分为最大值池化和平均值池化,和卷积差不多,也是取一小块区域,比如一个5 x 5的方块,如果是最大值池化,那就选这25个像素点最大的那个输出,如果是平均值池化,就把25个像素点取平均输出。这样做有什么好处呢?1、应该很明显可以看出,图像经过了下采样尺寸缩小了,按上面的例子,原来5 x 5的一个区域,现在只要一个值就表示出来了!2、增强了旋转不变性,池化操作可以看做是一种强制性的模糊策略,举个不恰当的例子,假设一个猫的图片,猫的耳朵应该处于左上5 x 5的一个小区域内(实际上猫的耳朵不可能这么小),无论这个耳朵如何旋转,经过池化之后结果都是近似的,因为就是这一块取平均和取最大对旋转并不care。当然和之前的卷积一样,池化也是层层递进的,底层的池化是在模糊底层特征,如线条等,高层的池化模糊了高级语义特征,如猫耳朵。所以,一般的CNN架构都是三明治一样,卷积池化交替出现,保证提取特征的同时也强制模糊增加特征的旋转不变性。
——————————————————分割线———————————————————
更新一下比较advantage的东西。现代CNN相比于之前的远古CNN发生了很大变化,虽然这里的远古CNN大约在2014年论文中出现,距今也只有不到4年时间。这里也可以看出深度学习的发展日新月异,一日千里的可怕速度。理解了本身CNN的基础含义,再来看看这些先进的CNN,是很有必要的,不要指望只靠卷积层池化层就可以得到好的效果,后来加入CNN的trick不计其数,而且也都是里程碑式的成果。下面主要以图像分类的CNN来阐述。暴力加深流派:以AlexNet和VGGNet为首的模型,这一派观点很直接,就是不断交替使用卷积层池化层,暴力增加网络层数,最后接一下全连接层分类。这类模型在CNN早期是主流,特点是参数量大,尤其是后面的全连接层,几乎占了一般参数量。而且相比于后续的模型,效果也较差。因此这类模型后续慢慢销声匿迹了。Inception流派:谷歌流派,这一派最早起源于NIN,称之为网络中的网络,后被谷歌发展成Inception模型(这个单词真的不好翻译。。。)。这个模型的特点是增加模型的宽度,使得模型不仅仅越长越高,还越长越胖。也就是说每一层不再用单一的卷积核卷积,而是用多个尺度的卷积核试试。显然,如果你熟悉CNN,就不难发现,这样做会使每一层的feature map数量猛增,因为一种尺寸的卷积核就能卷出一系列的feature map,何况多个!这里google使用了1*1的卷积核专门用来降channel。*谷歌的特点是一个模型不玩到烂绝不算完,所以又发展出了Inception v2、Inception v3、Inception v4等等。残差流派:2015年ResNet横空出世,开创了残差网络。使用残差直连边跨层连接,居然得到了意想不到的好效果。最重要的是,这一改进几乎彻底突破了层数的瓶颈,1000层的resnet不是梦!之后,最新的DenseNet丧心病狂地在各个层中间都引入了残差连接。目前大部分模型都在尝试引入残差连接。注意,到此为止,大部分模型已经丢弃了全连接层,改为全局平均池化。大大降低了参数量。混合流派:这一派不说了,就是看到哪几类模型效果好,就把这类技术混杂起来。典型的就是Xception和ResIception,将Inception和残差网络结合起来了。BatchNromalization:不得不提这个批量标准化技术,在此技术出现之前,CNN收敛很慢,此技术出现后,大大加快了模型收敛速度,还兼具一定的防过拟合效果。当然,这个技术不仅仅限于CNN。