深度学习

深度学习入门:几幅手稿讲解CNN

javascript

JohnHany的博客

编程 手绘 文字

深度学习入门:几幅手稿讲解CNN

        学习深度神经网络方面的算法已经有一段时间了,对目前比较经典的模型也有了一些了解。这种曾经一度低迷的方法如今已经吸引了不少领域的目光,在几年前仅仅存在于研究者想象中的应用,近几年也相继被深度学习方法实现了。不管是对数据的分析或是生成,不管数据形式是图像、视频、音频、文本仍是其它复杂维度,也不管是下棋、玩游戏仍是无人驾驶汽车导航,彷佛总有人会发掘出这种强大工具的新用途。人类刚刚将仿生学运用到“如何创造智能”这个问题上,就发现了光明的前景。php

        我把在组里介绍深度学习(Deep Learning)基础知识时画的几幅手稿分享出来,但愿能帮助新人更快的了解这种方法。我在讲解的过程当中参考了李宏毅老师的PPT(网络上他的PPT也有不止一个版本,YouTube也有视频教程),推荐读者结合起来阅读。css


        任何一个算法均可以看做一个函数。输入x通过函数f产生输出y,咱们指望得到的输出是\hat{y},因此咱们的目的是找到一个函数f,使得y\hat{y}尽量的接近。html

        同时,函数y由一组参数W肯定,因此输出y能够看做是输入x和参数W的因变量。当参数W固定时,每当输入不一样的x,其对应的输出y通常也会不一样。这时,y\hat{y}之间的差别称做偏差(loss)。描述xW\hat{y}与偏差loss之间关系的函数叫做偏差函数(loss function)。对于实际问题,通常偏差函数总会存在一个最小值。寻找最优函数f的过程,实际上就是寻找一组参数W,使得不管输入x如何(固然是位于定义域内的x),其偏差老是最小的。html5

        对于分类问题,函数f就是分类器,W就是须要经过训练得到的分类器参数。java


        在神经网络算法中,最基本的组成单位如图中左上所示,前一层神经元a_1a_2a_3(有时还有一个按层独立的叠加项b,称为偏置节点bias),通过权边w_1w_2w_3链接到下一层的节点z。权重w与节点a之间能够是简单的相乘再求和(线性网络),也能够是卷积后再求和(卷积神经网络,Convolutional Neural Networks,CNN),或者是其余的计算形式。即使是简单的线性运算,一个基本的单元能够用来表示一个线性分类器(左下),也能够用于线性拟合(右下),并且通过多层的累积计算以后还能够处理更复杂的问题。mysql


        卷积神经网络当中的“卷积”(convolution)与图像处理中的滤波器(filter)十分类似,只不过在滤波器中求和时输入元素与窗口元素是同向的,而在卷积计算中输入元素与窗口元素是反向的(注意公式中w的下标)。因此,一些依赖第三方库(好比OpenCV)的实现会直接把二维的卷积核作水平和竖直两个方向的翻转(或者旋转180度)以后直接调用一个滤波器函数(filter2D)就完成了卷积的计算。android

        在特征提取方面,卷积运算的做用与滤波器相同。如图中下方所示,假设在数轴上的输入数据是通过{2,-1,1}的一条曲线,与一个{1,-2,1}的核进行滤波(或者通过水平翻转后进行卷积),会获得一个比较大的输出(5),通过激活函数(actiation function)会产生一个十分接近于1的激活输出。这时,咱们能够说输入a符合特征w的模式(pattern)。git


        计算机科学中的神经网络算法只是从仿生学上部分借鉴了人类大脑的结构。上面的截图来自CrashCourse的科普视频。在大脑的神经元(Neuron)中,输入信号通过树突(dendrite)传入,而后再从轴突(Axon)传递出去。在神经元内部,信息以电信号方式传递,在神经元之间则以化学信号传递。在传递的过程当中,信号的强度和速度是必定的,但频率是可变的。因此信号的强弱(好比痛感、情绪等)是以信号频率的高低来区分的。另外神经元之间的链接是多对多的,即一个神经元能够有多个输入和输出。github

        与之相比,神经网络算法通常没有信号频率的概念,即每一个节点只向外产生一次激活(RNN递归计算的节点能够看做展开成一条节点链,可是链上每一个节点依然只通过一次计算)。并且,目前的算法大可能是严格按层级进行计算,并不像生物体神经元那样在三维空间中呈现纷繁复杂的结构。


        在神经网络中,层与层之间的链接分为全连通(fully-connected)与局部连通(local connected)两种。一些比较古老的文献认为局部连通的计算形式能够用卷积的形式来表示,因此错误地把这种通过简化计算的局部连通网络称为卷积网络。局部连通与全连通相比,参数数量要少得多,因此在过去计算机性能不佳时是一个比较有效的性能优化有段。但与此同时,局部连通也不可避免地引入了只有相邻节点(a_1a_2a_3)的输出才与下层节点(z_1)有关的约束,对大多实际问题是不合理的。直到Dropout的出现,结合了两者的优势,同时还提升了网络的泛化能力,成为目前十分流行的技术。


        对于一个机器学习算法来讲(也能够推广到其余领域的算法),最关键的三点是模型、数据和偏差函数。模型即肯定输入、参数与输出之间的关系;数据即我设计的模型是针对什么样的数据,指望获得什么样的输出;偏差函数是评价一个算法好坏的关键,须要用明确的表达式合理地衡量实际输出与理想输出之间的差别。前文说过,寻找一个最优函数f的过程,即寻找一个使偏差e最小的参数W的过程。若是咱们规定的偏差e是可微的,那么最优参数W^*必然落在偏差函数的驻点处(eW的偏导等于0)。可是稍微复杂一点的问题都没法一会儿肯定最优参数W^*,咱们只能从一个猜想的W_0出发来寻找最优值。这就很天然地引入了梯度降低法(Gradient Descent)。

        对于一个可微函数(偏差函数),其上任意一点处的偏导大小表明该点处切线斜率大小,方向(正负号)表明这条切线是向上仍是向下的。由于咱们须要在变量W的方向上寻找最低点,因此要向梯度方向的反方向(即降低方向)进行搜索。须要注意在一些问题中,偏差越大并不表明错误得越离谱,而是为了对模型的纠正过程当中施加一个更大的做用力。

        网络上有不少关于梯度降低法的介绍,这里再也不赘述。推荐阅读An overview of gradient descent optimization algorithms来了解一些经常使用的梯度方法。


        这张图来自李宏毅老师的PPT,是为了说明可能会形成训练收敛缓慢的缘由。在函数平缓的区域,因为偏导自己数值很小,会致使参数的更新量也很小,这时就须要比较大的步长。在鞍点时,某一轴上是极小点,但在其余轴上并非极小点,但因为偏差函数形式的缘由(好比涉及到对偏差取偶数次幂),会表现为在鞍点周围偏差都大于鞍点,因此使得训练过程误“收敛”于鞍点。因为大量的局部极小点和鞍点的存在,深度神经网络训练的调参也是一个十分精细的工做。关于在鞍点方面的分析,请参考Identifying and attacking the saddle point problem in high-dimensional non-convex optimization


        深度神经网络通常用反向传播训练方法(Back Propagation)来迭代地更新参数。上图是以线性网络为例解释BP的计算过程,公式应该能够自明,我就不用文字赘述了。对于卷积网络,其实计算过程是相同的,只不过把偏导项之间的乘法替换为卷积(卷积核在水平和竖直翻转以后的卷积)。推荐阅读Backpropagation in Convolutional Neural Network了解CNN中BP算法的细节。


        当训练结果很差时,可能会有两种结果,欠拟合与过拟合。欠拟合是指模型不足以对训练集产生比较高的分类精度,从偏差-迭代曲线上表现为不管是训练期间仍是测试期间,偏差都比较高。这说明模型对特征的提取不够,不足以用来描述样本间的差别。这时通常须要优化方法来解决这个问题,好比改变激活函数、偏差函数,或者换一种梯度降低方法(以及调整梯度方法的参数)。过拟合是指模型对训练集有比较高的分类精度,但对测试集表现不佳,从偏差-迭代曲线上表现为在训练期间偏差可以收敛到一个较小值,但测试期间偏差却比较大。这说明模型过度地依赖训练样本的特征,对没有碰见过新样本不知所措,缺少泛化能力。这时须要正则化方法来提升模型对通常性样本的适应性,好比Dropout和Batch Normalization。

        偏差不收敛的一个更常见的缘由——尤为是在一个新模型刚刚创建时——是梯度消失或梯度爆炸。在网络中缺乏比较可靠的正则化技术时,在网络不断迭代训练的过程当中(甚至第二次迭代开始)会发现新样本产生的偏差梯度在反向传播的过程当中愈来愈小(或愈来愈大),有时呈现每一两层就减少(或增大)一个数量级。梯度趋向消失时,不管训练多久,会发现最浅层(前一两层)的参数与初始值并无太大变化,这就使得浅层的存在失去了意义,并且这也会使训练过程变得很是缓慢。梯度爆炸时,仅仅几回迭代以后就会发现某一层全部节点的输出都变成了1(或者十分接近于1),这时网络也就失去了分类的能力。


        既然已经知道网络的输入和参数会影响最终输出的偏差,那么也就能够假设咱们能够在一个三维坐标上画出三者的关系。如图中所示,当参数(parameter)固定时,每输入不一样的样本(sample),就会产生不一样的偏差(loss),由于真实样本x与理想样本x^*相比老是存在偏差的。而对于同一个样本,变化的参数通常也会产生变化的偏差。因此训练网络的过程其实是在sample和parameter两个轴上不断变化时找到loss的最低点。

        在训练模型时,通常会将训练集等分为若干小集合(mini-batch),一次将一个mini-batch输入网络,计算完全部mini-batch后——若是以为网络精度还达不到要求——将全部样本随机排序,再分割为若干mini-batch进行训练。这个过程能够看做在sample轴上随机跳跃,在parameter轴上逐步前进地搜索,可以尽量地保证搜索到的最低点是全部样本的最低点。


        特征提取是一个分类器的核心,深度学习的优点就在于它能自动从原始数据提炼出特征,并以层级的逻辑组合这些特征来描述原始样本。我在最后一幅图中用一个简单的例子来讲明CNN的层级结构是如何解决图像分类问题的。

        假设咱们须要用机器视觉方法对图A(两个三角形构成松树的形状)和图B(两个三角形构成钻石的形状)进行区分。在神经网络方法出现以前,一种比较可行的方法是经过图像处理中的直线检测方法找到图像中全部直线,而后经过直线参数之间的关系来肯定以下判断规则:若是下面的三角形尖角朝上,即为松树;若是尖角朝下,即为钻石。通过细致的调参,这个算法应该已经能够完美解决区分图A与图B的问题了。若是如今又来了一副图C(也许是两个三角形水平排列构成小山的形状,也可能根本不包含三角形),须要用以前的算法来同时区分这三幅图片,怎么办?

        好在咱们能够用CNN来解决这个问题。首先须要注意,我在这一小节所指“卷积”其实是滤波操做,由于卷积涉及翻转,不利用直观理解。假设咱们训练好的网络有两层隐层,第一层包含两个节点(图中第二列蓝色图形,分别为一条左斜线与一条右斜线),第二层包含四个节点(图中第四列蓝色图形,分别为一条水平线,一条竖直线,一条左斜线与一条右斜线)。图A通过第一隐层,获得图中第三列黑色的图形。黑色的圆点表明原始图像中对某个卷积核激活值高的区域,白色表明激活值低的区域。图A松树左侧的两条斜边通过“左斜线”卷积核计算获得位于图像左侧的两个黑色圆点,其余区域都不符合“左斜线”这个特征,因此输出值所有忽略为0。同时,只有松树右侧的两条斜边会对“右斜线”卷积核产生高激活(获得两个位于右侧的黑色圆点),其余区域产生的激活都为0。同理,图B钻石图像通过“左斜线”与“右斜线”卷积核产生两幅不一样的图像(一副在左上和右下有黑点,一副在右上和左下有黑点)。这时,第一层的计算就完成了。

        与通常的CNN模型同样,咱们把第一层的结果(图中第三列)输入第二隐层以前要缩小一下图像的尺度。通过缩小以后(你能够眯起眼睛离屏幕稍远些观察),第三列的四个图形分别变成了一条在左侧的竖线,一条在右侧的竖线,一条右斜线和一条左斜线。如今,咱们拿第二层的四个卷积核(第四列蓝色图形)来对这四个结果进行卷积再求和。为了简化,若是在图像中存在一个区域使其与某卷积核的激活输出值较高,就将该卷积核的对应输出记为1;若是不存在这样的一个区域即记为0。这样,图中第三列第一个图像对四个卷积核分别产生(0,1,0,0),第二个图像产生(0,1,0,0),因此图A的最终结果是这两个向量的和,为(0,2,0,0)。而图B的结果为(0,0,0,1)+(0,0,1,0)=(0,0,1,1)。虽然图A与图B有类似之处,但通过两次卷积获得的向量是彻底不一样的,经过这两个向量,咱们就能惟一地肯定图A与图B。

        若是有新的样本加入,咱们只须要改变一下图例中的卷积核数目和形状(或者甚至不对网络作任何修改)也可以轻松地实现分类。固然,CNN方法在实际运用时是不须要人为地设计卷积核的,而是依靠对样本的训练逐渐构造的。


        其实,做为一个还没有成熟的工具,深度学习的优势与缺点一样明显。其优势毋庸置疑,是推进其在各领域蔓延的高分类精度,确切地说是它可以自主概括特征,免去了过去慢慢手工筛选特征来提升精度的过程。深度学习方法的缺点也十分致命,即训练结果彻底的不可预测性。在训练完成、进行测试以前,即使是有经验的工程师也难以给出其精度的界,更没法预知训练后的参数会变成什么样。虽然这种说法对于一个机器学习方法来讲有些苛刻,毕竟在数值计算领域有不少迭代算法也会由于微小的参数变化而难以收敛。可是做为一个参数量级惊人的算法,人类对其参数含义的解读也是困难的。其在多个领域的普遍运用产生的一个结果是,参数的不可预测性会带来其行为的不可预测性。虽然技术的推广者常常会如何保证甚至如何吹嘘他们训练出来的模型在不少条件下都有很高的精度(或者说,执行设计者所指望的行为),但更有可能的是,吹牛的人并不知道模型究竟为何会在特定条件下产生特定的结果。做为一个“黑盒”算法,其对外的表征是高分经过全部测试,但对于测试内容没有考虑到的状况才是值得担忧的。一个廉价而高效的工具在市场上的阻力是比较小的,那么比市场上现有算法更复杂更强大的算法势必会被不断推出。若是咱们可以假定“智能”只是一个不断收集和处理数据的过程,那么咱们也能够说《终结者》所描述的世界也并纯粹的想象了。

类别:模式识别标签:机器学习深度学习

文章导航

共有1条评论

  1. 开发者头条 说道:

    感谢分享!已推荐到《开发者头条》:https://toutiao.io/posts/yjns32 欢迎点赞支持!
    欢迎订阅《JohnHany的收藏夹》https://toutiao.io/subjects/266685

发表评论

电子邮件地址不会被公开。 必填项已用*标注

 

            
 

 

 

 

累积阅读

406885

分类目录

最多阅读

最新评论

文章归档

经常使用标签

Gravityscan Badge
Proudly powered by WordPress | Theme: Hany Dark based on Underscores.