卷积神经网络 公开课哪些层需要激活函数

卷积神经网络在自然语言处理的应用
发表于 12:22|
来源WildML|
作者Denny Britz
摘要:CNN作为当今绝大多数计算机视觉系统的核心技术,在图像分类领域做出了巨大贡献。本文从计算机视觉的用例开始,介绍CNN及其在自然语言处理中的优势和发挥的作用。
当我们听到卷积神经网络(Convolutional&Neural&Network,&CNNs)时,往往会联想到计算机视觉。CNNs在图像分类领域做出了巨大贡献,也是当今绝大多数计算机视觉系统的核心技术,从Facebook的图像自动标签到自动驾驶汽车都在使用。最近我们开始在自然语言处理(Natural&Language&Processing)领域应用CNNs,并取得了一些引人注目的成果。我将在本文中归纳什么是CNNs,怎样将它们应用于NLP。CNNs背后的直觉知识在计算机视觉的用例里更容易被理解,因此我就先从那里开始,然后慢慢过渡到自然语言处理。什么是卷积运算?对我来说,最容易的理解方式就是把卷积想象成作用于矩阵的一个滑动窗口函数。这么说有些拗口,但是用动画显示就很直观了。3x3的滤波器做卷积运算。图片来源:把左侧的矩阵想象成一幅黑白图像。每一个元素对应一个像素点,0表示黑点,1表示白点(灰度图的像素值一般是0~255)。移动窗口又称作核、滤波器或是特征检测器。这里我们使用3x3的滤波器,将滤波器与矩阵对应的部分逐元素相乘,然后求和。我们平移窗口,使其扫过矩阵的所有像素,对整幅图像做卷积运算。你也许有些疑惑,刚才的操作究竟会有什么效果呢。我们就来看几个直观的例子。用邻近点像素值的均值替换其原值,实现图像模糊的效果:& & & & & &&用邻近点像素值与自身的差值替换其原值,实现边缘检测的效果:(为了直观地来理解,想想图像中平滑的那些部分,那些像素点与周围像素的颜色几乎一致:求和的结果趋近于0,相当于黑色。如果有一条明显的边缘线,比如黑白分界线,那么像素值的差值将会很大,相当于白色)&&里还有一些其它的例子。想要深入了解卷积运算的原理,我推荐阅读Chris&Olah写的。什么是卷积神经网络?现在你明白了什么是卷积运算了吧。那CNNs又是什么呢?CNNs本质上就是多层卷积运算,外加对每层的输出用非线性激活函数做转换,比如用和。在传统的前馈神经网络中,我们把每个输入神经元与下一层的输出神经元相连接。这种方式也被称作是全连接层,或者仿射层。在CNNs中我们不这样做,而是用输入层的卷积结果来计算输出。这相当于是局部连接,每块局部的输入区域与输出的一个神经元相连接。对每一层应用不同的滤波器,往往是如上图所示成百上千个,然后汇总它们的结果。这里也涉及到池化层(降采样),我会在后文做解释。在训练阶段,CNN基于你想完成的任务自动学习滤波器的权重值。举个例子,在图像分类问题中,第一层CNN模型或许能学会从原始像素点检测到一些边缘线条,然后根据边缘线条在第二层检测出一些简单的形状,然后基于这些形状检测出更高级的特征,比如脸部轮廓等。最后一层是利用这些高级特征的一个分类器。这种计算方式有两点值得我们注意:位置不变性和组合性。比如说你想对图片中是否包含大象做分类。因为滤波器是在全图范围内平移,所以并不用关心大象究竟在图片的什么位置。事实上,池化也有助于平移、旋转和缩放的不变性,它对克服缩放因素的效果尤其好。第二个关键因素是(局部)组合性。每个滤波器对一小块局部区域的低级特征组合形成更高级的特征表示。这也是CNNs对计算机视觉作用巨大的原因。我们可以很直观地理解,线条由像素点构成,基本形状又由线条构成,更复杂的物体又源自基本的形状。那么,如何将它们用于NLP呢?NLP任务的输入不再是像素点了,大多数情况下是以矩阵表示的句子或者文档。矩阵的每一行对应于一个分词元素,一般是一个单词,也可以是一个字符。也就是说每一行是表示一个单词的向量。通常,这些向量都是word&embeddings(一种底维度表示)的形式,如和,但是也可以用one-hot向量的形式,也即根据词在词表中的索引。若是用100维的词向量表示一句10个单词的句子,我们将得到一个10x100维的矩阵作为输入。这个矩阵相当于是一幅“图像”。在计算机视觉的例子里,我们的滤波器每次只对图像的一小块区域运算,但在处理自然语言时滤波器通常覆盖上下几行(几个词)。因此,滤波器的宽度也就和输入矩阵的宽度相等了。尽管高度,或者区域大小可以随意调整,但一般滑动窗口的覆盖范围是2~5行。综上所述,处理自然语言的卷积神经网络结构是这样的(花几分钟时间理解这张图片,以及维度是如何变化的。你可以先暂时忽略池化操作,我们在稍后会解释它):用于句子分类器的卷积神经网络(CNN)结构示意图。这里我们对滤波器设置了三种尺寸:2、3和4行,每种尺寸各有两种滤波器。每个滤波器对句子矩阵做卷积运算,得到(不同程度的)特征字典。然后对每个特征字典做最大值池化,也就是只记录每个特征字典的最大值。这样,就由六个字典生成了一串单变量特征向量(univariate&feature&vector),然后这六个特征拼接形成一个特征向量,传给网络的倒数第二层。最后的softmax层以这个特征向量作为输入,用其来对句子做分类;我们假设这里是二分类问题,因此得到两个可能的输出状态。来源:Zhang,&Y.,&&&Wallace,&B.&(2015).&A&Sensitivity&Analysis&of&(and&Practitioners’&Guide&to)&Convolutional&Neural&Networks&for&Sentence&Classification.计算机视觉完美的直观感受这里还存在吗?位置不变性和局部组合性对图像来说很直观,但对NLP却并非如此。你也许会很在意一个词在句子中出现的位置。相邻的像素点很有可能是相关联的(都是物体的同一部分),但单词并不总是如此。在很多种语言里,短语之间会被许多其它词所隔离。同样,组合性也不见得明显。单词显然是以某些方式组合的,比如形容词修饰名词,但若是想理解更高级特征真正要表达的含义是什么,并不像计算机视觉那么明显了。由此看来,卷积神经网络似乎并不适合用来处理NLP任务。(Recurrent&Neural&Network)更直观一些。它们模仿我们人类处理语言的方式(至少是我们自己所认为的方式):从左到右的顺序阅读。庆幸的是,这并不意味着CNNs没有效果。。实际上CNNs对NLP问题的效果非常理想。正如(Bag&of&Words&model),它明显是基于错误假设的过于简化模型,但这不影响它多年来一直被作为NLP的标准方法,并且取得了不错的效果。CNNs的主要特点在于速度快。非常的快。卷积运算是计算机图像的核心部分,在GPU级别的硬件层实现。相比于,CNNs表征方式的效率也更胜一筹。由于词典庞大,任何超过3-grams的计算开销就会非常的大。即使Google也最多不超过5-grams。卷积滤波器能自动学习好的表示方式,不需要用整个词表来表征。那么用尺寸大于5行的滤波器完全合情合理了。我个人认为许多在第一层学到的滤波器扑捉到的特征与n-grams非常相似(但不局限),但是以更紧凑的方式表征。CNN的超参数在解释如何将CNNs用于NLP任务之前,先来看一下构建CNN网络时需要面临的几个选择。希望这能帮助你更好地理解相关文献。窄卷积&vs&宽卷积在上文中解释卷积运算的时候,我忽略了如何使用滤波器的一个小细节。在矩阵的中部使用3x3的滤波器没有问题,在矩阵的边缘该怎么办呢?左上角的元素没有顶部和左侧相邻的元素,该如何滤波呢?解决的办法是采用补零法(zero-padding)。所有落在矩阵范围之外的元素值都默认为0。这样就可以对输入矩阵的每一个元素做滤波了,输出一个同样大小或是更大的矩阵。补零法又被称为是宽卷积,不使用补零的方法则被称为窄卷积。1D的例子如图所示:窄卷积&vs&宽卷积。滤波器长度为5,输入长度为7。来源:A&Convolutional&Neural&Network&for&Modelling&Sentences&(2014)当滤波器长度相对输入向量的长度较大时,你会发现宽卷积很有用,或者说很有必要。在上图中,窄卷积输出的长度是&(7-5)+1=3,宽卷积输出的长度是(7+2*4-5)+1=11。一般形式为步长卷积运算的另一个超参数是步长,即每一次滤波器平移的距离。上面所有例子中的步长都是1,相邻两个滤波器有重叠。步长越大,则用到的滤波器越少,输出的值也越少。下图来自斯坦福的,分别是步长为1和2的情况:卷积步长。左侧:步长为1,右侧:步长为2。来源:&在文献中我们常常见到的步长是1,但选择更大的步长会让模型更接近于,其结构就像是一棵树。池化层卷积神经网络的一个重要概念就是池化层,一般是在卷积层之后。池化层对输入做降采样。常用的池化做法是对每个滤波器的输出求最大值。我们并不需要对整个矩阵都做池化,可以只对某个窗口区间做池化。例如,下图所示的是2x2窗口的最大值池化(在NLP里,我们通常对整个输出做池化,每个滤波器只有一个输出值):CNN的最大池化。来源:&为什么要池化呢?有许多原因。&池化的特点之一就是它输出一个固定大小的矩阵,这对分类问题很有必要。例如,如果你用了1000个滤波器,并对每个输出使用最大池化,那么无论滤波器的尺寸是多大,也无论输入数据的维度如何变化,你都将得到一个1000维的输出。这让你可以应用不同长度的句子和不同大小的滤波器,但总是得到一个相同维度的输出结果,传入下一层的分类器。池化还能降低输出结果的维度,(理想情况下)却能保留显著的特征。你可以认为每个滤波器都是检测一种特定的特征,例如,检测句子是否包含诸如“not&amazing”等否定意思。如果这个短语在句子中的某个位置出现,那么对应位置的滤波器的输出值将会非常大,而在其它位置的输出值非常小。通过采用取最大值的方式,能将某个特征是否出现在句子中的信息保留下来,但是无法确定它究竟在句子的哪个位置出现。这个信息出现的位置真的很重要吗?确实是的,它有点类似于一组n-grams模型的行为。尽管丢失了关于位置的全局信息(在句子中的大致位置),但是滤波器捕捉到的局部信息却被保留下来了,比如“not&amazing”和“amazing&not”的意思就大相径庭。在图像识别领域,池化还能提供平移和旋转不变性。若对某个区域做了池化,即使图像平移/旋转几个像素,得到的输出值也基本一样,因为每次最大值运算得到的结果总是一样的。通道我们需要了解的最后一个概念是通道。通道即是输入数据的不同“视角”。比如说,做图像识别时一般会用到RGB通道(红绿蓝)。你可以对每个通道做卷积运算,赋予相同或不同的权值。你也同样可以把NLP想象成有许多个通道:把不同类的词向量表征(例如和)看做是独立的通道,或是把不同语言版本的同一句话看作是一个通道。卷积神经网络在自然语言处理的应用我们接下来看看卷积神经网络模型在自然语言处理领域的实际应用。我试图去概括一些研究成果。希望至少能够涵盖大部分主流的成果,难免也会遗漏其它一些有意思的应用(请在评论区提醒我)。最适合CNNs的莫过于分类任务,如语义分析、垃圾邮件检测和话题分类。卷积运算和池化会丢失局部区域某些单词的顺序信息,因此纯CNN的结构框架不太适用于PoS&Tagging和Entity&Extraction等顺序标签任务(也不是不可能,你可以尝试输入位置相关的特征)。文献[1&在不同的分类数据集上评估CNN模型,主要是基于语义分析和话题分类任务。CNN模型在各个数据集上的表现非常出色,甚至有个别刷新了目前最好的结果。令人惊讶的是,这篇文章采用的网络结构非常简单,但效果相当棒。输入层是一个表示句子的矩阵,每一行是word2vec词向量。接着是由若干个滤波器组成的卷积层,然后是最大池化层,最后是softmax分类器。该论文也尝试了两种不同形式的通道,分别是静态和动态词向量,其中一个通道在训练时动态调整而另一个不变。文献[2]中提到了一个类似的结构,但更复杂一些。文献[6]在网络中又额外添加了一个层,用于语义聚类。Kim,&Y.&(2014).&卷积神经网络用来语句分类文献[4]从原始数据训练CNN模型,不需要预训练得到word2vec或GloVe等词向量表征。它直接对one-hot向量进行卷积运算。作者对输入数据采用了节省空间的类似词袋表征方式,以减少网络需要学习的参数个数。在文献[5]中作者用了CNN学习得到的非监督式“region&embedding”来扩展模型,预测文字区域的上下文内容。这些论文中提到的方法对处理长文本(比如影评)非常有效,但对短文本(比如推特)的效果还不清楚。凭我的直觉,对短文本使用预训练的词向量应该能比长文本取得更好的效果。搭建一个CNN模型结构需要选择许多个超参数,我在上文中已经提到了一些:输入表征(word2vec,&GloVe,&one-hot),卷积滤波器的数量和尺寸,池化策略(最大值、平均值),以及激活函数(ReLU,&tanh)。文献[7]通过多次重复实验,比较了不同超参数对CNN模型结构在性能和稳定性方面的影响。如果你想自己实现一个CNN用于文本分类,可以借鉴该论文的结果。其主要的结论有最大池化效果总是好于平均池化;选择理想的滤波器尺寸很重要,但也根据任务而定需;正则化在NLP任务中的作用并不明显。需要注意的一点是该研究所用文本集里的文本长度都相近,因此若是要处理不同长度的文本,上述结论可能不具有指导意义。文献[8]探索了CNNs在关系挖掘和关系分类任务中的应用。除了词向量表征之外,作者还把词与词的相对位置作为卷积层的输入值。这个模型假设了所有文本元素的位置已知,每个输入样本只包含一种关系。文献[9]和文献[10]使用的模型类似。来自微软研究院的文献[11]和&[12]介绍了CNNs在NLP的另一种有趣的应用方式。这两篇论文介绍了如何学习将句子表示成包含语义的结构,它能被用来做信息检索。论文中给出的例子是基于用户当前的阅读内容,为其推荐其它感兴趣的文档。句子的表征是基于搜索引擎的日志数据训练得到的。大多数CNN模型以这样或是那样的训练方式来学习单词和句子的词向量表征,它是训练过程的一部分。并不是所有论文都关注这一步训练过程,也并不在乎学到的表征意义有多大。文献[13]介绍了用CNN模型对Facebook的日志打标签。这些学到的词向量随后又被成功应用于另一个任务&——&基于点击日志给用户推荐感兴趣的文章。字符层面的CNNs模型至此,所有的模型表征都是在单词的层面上。另外有一些团队则研究如何将CNNs模型直接用于字符。文献[14]学到了字符层面的向量表征,将它们与预训练的词向量结合,用来给语音打标签。文献[15]和[16]研究了直接用CNNs模型直接从字符学习,而不必预训练词向量了。值得注意的是,作者使用了一个相对较深的网络结构,共有9层,用来完成语义分析和文本分类任务。结果显示,用字符级输入直接在大规模数据集(百万级)上学习的效果非常好,但用简单模型在小数据集(十万级)上的学习效果一般。文献[17]是关于字符级卷积运算在语言建模方面的应用,将字符级CNN模型的输出作为LSTM模型每一步的输入。同一个模型用于不同的语言。令人惊讶的是,上面所有论文几乎都是发表于近两年。显然CNNs模型在NLP领域已经有了出色的表现,新成果和顶级系统还在层出不穷地出现。若有疑问或是反馈,请在评论区留言。谢谢阅读!&参考文献&[1]&&[2]&&[3]&&[4]&&[5]&&[6]&&[7]&&[8]&[9]&&[10]&&[11]&&[12][13][14]&[15]&[16]&[17]&原文链接:(译者/赵屹华&审核/刘翔宇、朱正贵 责编/周建丁 原创/翻译投稿请联系:,微信号:jianding_zhou)译者简介:,计算广告工程师@搜狗,前生物医学工程师,关注推荐算法、机器学习领域。将于-12日在北京隆重举办。在主会之外,会议还设立了16大分论坛,包含数据库、深度学习、推荐系统、安全等6大技术论坛,金融、制造业、交通旅游、互联网、医疗健康、教育等7大应用论坛和3大热点议题论坛,。&
推荐阅读相关主题:
CSDN官方微信
扫描二维码,向CSDN吐槽
微信号:CSDNnews
相关热门文章卷积神经网络全面解析
最近仔细学习了一下卷积神经网络(CNN,Convolutional Neural Network),发现各处资料都不是很全面,经过艰苦努力终于弄清楚了。为了以后备查,以及传播知识,决定记录下来。本文将极力避免废话,重点聚焦在推导过程上,为打算从零开始的孩纸说清楚“为什么”。
另外,因本人才疏学浅(是真的才疏学浅,不是谦虚),肯定会有很多谬误,欢迎大家指出!
卷积神经网络(CNN)概述
由来:神经元网络的直接升级版
相关:Yann LeCun和他的LeNet
影响:在图像、语音领域不断突破,复兴了神经元网络并进入“深度学习”时代
卷积神经网络沿用了普通的神经元网络即多层感知器的结构,是一个前馈网络。以应用于图像领域的CNN为例,大体结构如图1。
很明显,这个典型的结构分为四个大层次
输入图像I。为了减小复杂度,一般使用灰度图像。当然,也可以使用RGB彩色图像,此时输入图像有三张,分别为RGB分量。输入图像一般需要归一化,如果使用sigmoid激活函数,则归一化到[0, 1],如果使用tanh激活函数,则归一化到[-1, 1]。
多个卷积(C)-下采样(S)层。将上一层的输出与本层权重W做卷积得到各个C层,然后下采样得到各个S层。怎么做以及为什么,下面会具体分析。这些层的输出称为Feature Map。
光栅化(X)。是为了与传统的多层感知器全连接。即将上一层的所有Feature Map的每个像素依次展开,排成一列。
传统的多层感知器(N&O)。最后的分类器一般使用Softmax,如果是二分类,当然也可以使用LR。
接下来,就开始深入探索这个结构吧!
从多层感知器(MLP)说起
卷积神经网络来源于普通的神经元网络。要了解个中渊源,就要先了解神经元网络的机制以及缺点。典型的神经元网络就是多层感知器。
摘要:本节主要内容为多层感知器(MLP,Multi-Layer Perceptron)的原理、权重更新公式的推导。熟悉这一部分的童鞋可以直接跳过了~但是,一定一定要注意,本节难度比较大,所以不熟悉的童鞋一定一定要认真看看!如果对推导过程没兴趣,可直接在本节最后看结论。
感知器(Perceptron)是建立模型
$$f(x) = act(\theta^Tx + b)$$
其中激活函数 act 可以使用{sign, sigmoid, tanh}之一。
激活函数使用符号函数 sign ,可求解损失函数最小化问题,通过梯度下降确定参数
激活函数使用 sigmoid (或者 tanh ),则分类器事实上成为Logistic Regression(个人理解,请指正),可通过梯度上升极大化似然函数,或者梯度下降极小化损失函数,来确定参数
如果需要多分类,则事实上成为Softmax Regression
如要需要分离超平面恰好位于正例和负例的正中央,则成为支持向量机(SVM)。
感知器比较简单,资料也比较多,就不再详述。
多层感知器
感知器存在的问题是,对线性可分数据工作良好,如果设定迭代次数上限,则也能一定程度上处理近似线性可分数据。但是对于非线性可分的数据,比如最简单的异或问题,感知器就无能为力了。这时候就需要引入多层感知器这个大杀器。
多层感知器的思路是,尽管原始数据是非线性可分的,但是可以通过某种方法将其映射到一个线性可分的高维空间中,从而使用线性分类器完成分类。图1中,从X到O这几层,正展示了多层感知器的一个典型结构,即输入层-隐层-输出层。
输入层-隐层
是一个全连接的网络,即每个输入节点都连接到所有的隐层节点上。更详细地说,可以把输入层视为一个向量 \(x\) ,而隐层节点 \(j\) 有一个权值向量 \(\theta_j\) 以及偏置 \(b_j\) ,激活函数使用 sigmoid 或 tanh ,那么这个隐层节点的输出应该是
$$f_j(x) = act(\theta_j^Tx + b_j)$$
也就是每个隐层节点都相当于一个感知器。每个隐层节点产生一个输出,那么隐层所有节点的输出就成为一个向量,即
act({\Theta}x + b)$$
若输入层有 \(m\) 个节点,隐层有 \(n\) 个节点,那么 \(\Theta = [\theta^T]\) 为 \(n×m\) 的矩阵,\(x\) 为长为 \(m\) 的向量,\(b\) 为长为 \(n\) 的向量,激活函数作用在向量的每个分量上, \(f(x)\) 返回一个向量。
隐层-输出层
可以视为级联在隐层上的一个感知器。若为二分类,则常用Logistic Regression;若为多分类,则常用Softmax Regression。
Back Propagation
搞清楚了模型的结构,接下来就需要通过某种方法来估计参数了。对于一般的问题,可以通过求解损失函数极小化问题来进行参数估计。但是对于多层感知器中的隐层,因为无法直接得到其输出值,当然不能够直接使用到其损失了。这时,就需要将损失从顶层反向传播(Back Propagate)到隐层,来完成参数估计的目标。
首先,约定标量为普通小写字母,向量为加粗小写字母,矩阵为加粗大写字母;再约定以下记号:
输入样本为 \(\mathbf x\),其标签为 \(\mathbf t\)
对某个层 \(Q\) ,其输出为 \(\mathbf o_Q\) ,其第 \(j\) 个节点的输出为 \(o_Q^{(j)}\) ,其每个节点的输入均为上一层 \(P\) 的输出 \(\mathbf o_P\) ;层 \(Q\) 的权重为矩阵 \(\mathbf \Theta_Q\) ,连接层 \(P\) 的第 \(i\) 个节点与层 \(Q\) 的第 \(j\) 个节点的权重为 \(\theta_Q^{(ji)}\)
对输出层 \(Y\) ,设其输出为 \(\mathbf o_Y\), 其第 \(y\) 个节点的输出为 \(o_Y^{(y)}\)
现在可以定义损失函数
$$\left \lbrace \begin {aligned}E & = \frac {1} {2} \sum_{y \in Y}(t^{(y)} - o_Y^{(y)})^2\\o_Q^{(j)} & = \phi(n_Q^{(j)})\\n_Q^{(j)} & = \sum_{i \in P} \theta_Q^{(ji)} o_P^{(i)} + b_Q^{(j)}\end {aligned} \right.$$
其中, \(\phi\) 为激活函数。我们依旧通过极小化损失函数的方法,尝试进行推导。则
$$\left \lbrace \begin {aligned}\frac {\partial E} {\partial \theta_Q^{(ji)}} & =\frac {\partial E} {\partial o_Q^{(j)}} \frac {\partial o_Q^{(j)}} {\partial n_Q^{(j)}} \frac {\partial n_Q^{(j)}} {\partial \theta_Q^{(ji)}}\\\frac {\partial E} {\partial b_Q^{(j)}} & = \frac {\partial E} {\partial o_Q^{(j)}} \frac {\partial o_Q^{(j)}} {\partial n_Q^{(j)}} \frac {\partial n_Q^{(j)}} {\partial b_Q^{(j)}}\end{aligned}\right.$$
上边两个式子的等号右边部有三个导数比较容易确定
$$\left \lbrace \begin {aligned}\frac {\partial o_Q^{(j)}} {\partial n_Q^{(j)}} & = \phi'(n_Q^{(j)})\\\frac {\partial n_Q^{(j)}} {\partial \theta_Q^{(ji)}} & = o_P^{(i)}\\\frac {\partial n_Q^{(j)}} {\partial b_Q^{(j)}} & = 1\end {aligned} \right.$$
然后再看剩下的比较复杂的一个偏导数。考虑层 \(Q\) 的下一层 \(R\) ,其节点 \(k\) 的输入为层 \(Q\) 中每个节点的输出,也就是为 \(o_Q^{(j)}\) 的函数,考虑逆函数,可视 \(o_Q^{(j)}\) 为 \(o_R^{(k)}\) 的函数,也为 \(n_R^{(k)}\) 的函数。则对每个隐层
$$\begin {aligned}\frac {\partial E} {\partial o_Q^{(j)}} & = \frac {\partial E(n_R^{(1)}, n_R^{(2)}, ..., n_R^{(k)}, ..., n_R^{(K)})} {\partial o_Q^{(j)}}\\& = \sum_{k \in R} \frac {\partial E} {\partial n_R^{(k)}} \frac {\partial n_R^{(k)}} {\partial o_Q^{(j)}}\\& = \sum_{k \in R} \frac {\partial E} {\partial o_R^{(k)}} \frac {\partial o_R^{(k)}} {\partial n_R^{(k)}} \frac {\partial n_R^{(k)}} {\partial o_Q^{(j)}}\\& = \sum_{k \in R} \frac {\partial E} {\partial o_R^{(k)}} \frac {\partial o_R^{(k)}} {\partial n_R^{(k)}} \theta_R^{(kj)}\end {aligned}$$
令 \(\delta_Q^{(j)} = \frac {\partial E} {\partial o_Q^{(j)}} \frac {\partial o_Q^{(j)}} {\partial n_Q^{(j)}}\)
则对每个隐层
$$\frac {\partial E} {\partial o_Q^{(j)}} = \sum_{k \in R} \frac {\partial E} {\partial o_R^{(k)}} \frac {\partial o_R^{(k)}} {\partial n_R^{(k)}} \theta_R^{(kj)} = \sum_{k \in R} \delta_R^{(k)} \theta_R^{(kj)}$$
考虑到输出层,有
$$\frac {\partial E} {\partial o_Q^{(j)}} =\left \lbrace \begin {aligned}\sum_{k \in R} \delta_R^{(k)} \theta_R^{(kj)}, & \qquad k\ has\ input\ node\ j\\o_Y^{(j)} - t^{(j)}, & \qquad j\ is\ an\ output\ node,\ i.e.\ Q = Y\end {aligned} \right .$$
$$\delta_Q^{(j)} = \frac {\partial E} {\partial o_Q^{(j)}} \frac {\partial o_Q^{(j)}} {\partial n_Q^{(j)}} = \frac {\partial E} {\partial o_Q^{(j)}} \phi'(n_Q^{(j)}) =\left \lbrace \begin {aligned}(\sum_{k \in R} \delta_R^{(k)} \theta_R^{(kj)}) \phi'(n_Q^{(j)}), & \qquad k\ has\ input\ node\ j\\(o_Y^{(j)} - t^{(j)}) \phi'(n_Y^{(j)}), & \qquad j\ is\ an\ output\ node,\ i.e.\ Q = Y\end {aligned} \right.$$
综合以上各式,有梯度结果
$$\begin {aligned}\frac {\partial E} {\partial \theta_Q^{(ji)}} & = \frac {\partial E} {\partial o_Q^{(j)}} \frac {\partial o_Q^{(j)}} {\partial n_Q^{(j)}} \frac {\partial n_Q^{(j)}} {\partial \theta_Q^{(ji)}} = \delta_Q^{(j)} o_P^{(i)}\\\frac {\partial E} {\partial b_Q^{(j)}} & = \frac {\partial E} {\partial o_Q^{(j)}} \frac {\partial o_Q^{(j)}} {\partial n_Q^{(j)}} \frac {\partial n_Q^{(j)}} {\partial b_Q^{(j)}} = \delta_Q^{(j)}\end {aligned}$$
本来到这里应该就结束了,不过同正向的时候一样,为了计算方便,我们依然希望能够以矩阵或者向量的方式来表达。结论在这里:
假设有层 \(P, Q, R\) ,分别有 \(l, m, n\) 个节点,依序前者输出全连接到后者作为输入。层 \(Q\) 有权重矩阵 \([\mathbf \Theta_Q]_{m×l}\) ,偏置向量 \([\mathbf b_Q]_{m×1}\) ,层 \(R\) 有权重矩阵 \([\mathbf \Theta_R]_{n×m}\) ,偏置向量 \([\mathbf b_R]_{n×1}\) 。那么
$$\begin {aligned}\frac {\partial E} {\partial \mathbf \Theta_Q} & = \mathbf δ_Q \mathbf o_P^T\\\frac {\partial E} {\partial \mathbf b_Q} & = \mathbf δ_Q\\\mathbf δ_Q & =\left \lbrace \begin {aligned}(\mathbf \Theta_R^T \mathbf δ_R) \circ \phi'(\mathbf n_Q), & \qquad Q\ is\ a\ hidden\ layer\\(\mathbf o_Y - \mathbf t) \circ \phi'(\mathbf n_Y), & \qquad Q = Y\ is\ the\ output\ layer\end {aligned} \right.\end {aligned}$$
其中,运算 \(w = u \circ v\) 表示 \(w_i = u_i v_i\) 。函数作用在向量或者矩阵上,表示作用在其每个分量上。
最后,补充几个常用的激活函数的导数结果,推导很简单,从略。
$$\begin {aligned}\phi'(x) & = sigmoid'(x) = sigmoid(x)(1 - sigmoid(x)) = \mathbf o_Q(1 - \mathbf o_Q)\\\phi'(x) & = tanh'(x) = 1 - tanh^2(x) = 1 - \mathbf o_Q^2\\\phi'(x) & = softmax'(x) = softmax(x) - softmax^2(x) = \mathbf o_Q - \mathbf o_Q^2\end{aligned}$$
存在的问题
多层感知器存在的最大的问题就是,它是一个全连接的网络,因此在输入比较大的时候,权值会特别多。比如一个有1000个节点的隐层,连接到一个的图像上,那么就需要 10^9 个权值参数(外加1000个偏置参数)!这个问题,一方面限制了每层能够容纳的最大神经元数目,另一方面也限制了多层感知器的层数即深度。
多层感知器的另一个问题是梯度发散。 (这个问题的具体原因还没有完全弄清楚,求指教!) 一般情况下,我们需要把输入归一化,而每个神经元的输出在激活函数的作用下也是归一化的;另外,有效的参数其绝对值也一般是小于1的;这样,在BP过程中,多个小于1的数连乘,得到的会是更小的值。也就是说,在深度增加的情况下,从后传播到前边的残差会越来越小,甚至对更新权值起不到帮助,从而失去训练效果,使得前边层的参数趋于随机化(补充一下,其实随机参数也是能一定程度上捕捉到图像边缘的)。
感谢提供的帮助~
因为这些问题,神经元网络在很长一段时间内都被冷落了。
从MLP到CNN
卷积神经网络的名字怪吓人,实际理解起来也挺吓人的。哈哈,其实只要看明白了多层感知器的推导过程,理解卷积神经网络就差不多可以信手拈来了。
摘要:首先解释卷积神经网络为什么会“长”成现在这般模样。然后详细推导了卷积神经网络的预测过程和参数估计方法。
CNN的前世今生
既然多层感知器存在问题,那么卷积神经网络的出现,就是为了解决它的问题。卷积神经网络的核心出发点有三个。
局部感受野。形象地说,就是模仿你的眼睛,想想看,你在看东西的时候,目光是聚焦在一个相对很小的局部的吧?严格一些说,普通的多层感知器中,隐层节点会全连接到一个图像的每个像素点上,而在卷积神经网络中,每个隐层节点只连接到图像某个足够小局部的像素点上,从而大大减少需要训练的权值参数。举个栗子,依旧是的图像,使用10×10的感受野,那么每个神经元只需要100个权值参数;不幸的是,由于需要将输入图像扫描一遍,共需要991×991个神经元!参数数目减少了一个数量级,不过还是太多。
权值共享。形象地说,就如同你的某个神经中枢中的神经细胞,它们的结构、功能是相同的,甚至是可以互相替代的。也就是,在卷积神经网中,同一个卷积核内,所有的神经元的权值是相同的,从而大大减少需要训练的参数。继续上一个栗子,虽然需要991×991个神经元,但是它们的权值是共享的呀,所以还是只需要100个权值参数,以及1个偏置参数。从MLP的 10^9 到这里的100,就是这么狠!作为补充,在CNN中的每个隐藏,一般会有多个卷积核。
池化。形象地说,你先随便看向远方,然后闭上眼睛,你仍然记得看到了些什么,但是你能完全回忆起你刚刚看到的每一个细节吗?同样,在卷积神经网络中,没有必要一定就要对原图像做处理,而是可以使用某种“压缩”方法,这就是池化,也就是每次将原图像卷积后,都通过一个下采样的过程,来减小图像的规模。以最大池化(Max Pooling)为例,的图像经过10×10的卷积核卷积后,得到的是991×991的特征图,然后使用2×2的池化规模,即每4个点组成的小方块中,取最大的一个作为输出,最终得到的是496×496大小的特征图。
现在来看,需要训练参数过多的问题已经完美解决。 而梯度发散的问题,因为还不清楚具体缘由,依然留待讨论。 关于梯度发散,因为多个神经元共享权值,因此它们也会对同一个权值进行修正,积少成多,积少成多,积少成多,从而一定程度上解决梯度发散的问题!
下面我们来揭开卷积神经网络中“卷积”一词的神秘面纱。
CNN的预测过程
回到开头的图1,卷积神经网络的预测过程主要有四种操作:卷积、下采样、光栅化、多层感知器预测。
先抛开卷积这个概念不管。为简便起见,考虑一个大小为5×5的图像,和一个3×3的卷积核。这里的卷积核共有9个参数,就记为 \(\Theta = [\theta_{ij}]_{3×3}\) 吧。这种情况下,卷积核实际上有9个神经元,他们的输出又组成一个3×3的矩阵,称为特征图。第一个神经元连接到图像的第一个3×3的局部,第二个神经元则连接到第二个局部(注意,有重叠!就跟你的目光扫视时也是连续扫视一样)。具体如图2所示。
图2的上方是第一个神经元的输出,下方是第二个神经元的输出。每个神经元的运算依旧是
$$f(x) = act(\sum_{i, j}^n \theta_{(n - i)(n - j)} x_{ij} + b)$$
需要注意的是,平时我们在运算时,习惯使用 \(\theta_{ij}x_{ij}\) 这种写法,但事实上,我们这里使用的是 \(\theta_{(n - i)(n - j)}x_{ij}\) ,原因马上揭晓。
现在我们回忆一下离散卷积运算。假设有二维离散函数 \(f(x, y), g(x, y)\) , 那么它们的卷积定义为
$$f(m, n)*g(m, n) = \sum_u^\infty \sum_v^\infty {f(u, v)g(m - u, n - v)}$$
现在发现了吧!上面例子中的9个神经元均完成输出后,实际上等价于图像和卷积核的卷积操作!这就是“卷积神经网络”名称的由来,也是为什么在神经元运算时使用 \(\theta_{(n - i)(n - j)}x_{ij}\) 。
如果你足够细心,就会发现其实上述例子中的运算并不完全符合二维卷积的定义。实际上,我们需要用到的卷积操作有两种模式:
valid模式,用 \(*_v\) 表示。即上边例子中的运算。在这种模式下,卷积只发生在被卷积的函数的定义域“内部”。一个 \(m×n\) 的矩阵被一个 \(p×q\) 的矩阵卷积( \(m \ge p, n \ge q\) ),得到的是一个 \((m - p + 1)×(n - q + 1)\) 的矩阵。
full模式,用 \(*_f\) 表示。这种模式才是上边二维卷积的定义。一个 \(m×n\) 的矩阵被一个 \(p×q\) 的矩阵卷积,得到的是一个 \((m + p - 1)×(n + q - 1)\) 的矩阵。
现在总结一下卷积过程。如果卷积层 \(c\) 中的一个“神经中枢” \(j\) 连接到特征图 \(\mathbf X_1, \mathbf X_2, ..., \mathbf X_i\) ,且这个卷积核的权重矩阵为 \(\mathbf \Theta_j\) ,那么这个神经中枢的输出为
$$\mathbf O_j = \phi (\sum_i \mathbf X_i *_v \mathbf \Theta_j + b_j)$$
下采样,即池化,目的是减小特征图,池化规模一般为2×2。常用的池化方法有:
最大池化(Max Pooling)。取4个点的最大值。这是最常用的池化方法。
均值池化(Mean Pooling)。取4个点的均值。
高斯池化。借鉴高斯模糊的方法。不常用。具体过程不是很清楚。。。
可训练池化。训练函数 \(f\) ,接受4个点为输入,出入1个点。不常用。
由于特征图的变长不一定是2的倍数,所以在边缘处理上也有两种方案:
忽略边缘。即将多出来的边缘直接省去。
保留边缘。即将特征图的变长用0填充为2的倍数,然后再池化。一般使用这种方式。
对神经中枢 \(j\) 的输出 \(O_j\) ,使用池化函数 downsample ,池化后的结果为
$$\mathbf S_j = downsample(\mathbf O_j)$$
图像经过池化-下采样后,得到的是一系列的特征图,而多层感知器接受的输入是一个向量。因此需要将这些特征图中的像素依次取出,排列成一个向量。具体说,对特征图 \(\mathbf X_1, \mathbf X_2, ..., \mathbf X_j\) ,光栅化后得到的向量
$$\mathbf o_k = [x_{111}, x_{112}, ..., x_{11n}, x_{121}, x_{122}, ..., x_{12n}, ..., x_{1mn}, ..., x_{2mn}, ..., x_{jmn}]^T$$
多层感知器预测
将光栅化后的向量连接到多层感知器即可。
CNN的参数估计
卷积神经网络的参数估计依旧使用Back Propagation的方法,不过需要针对卷积神经网络的特点进行一些修改。我们从高层到底层,逐层进行分析。
多层感知器层
使用多层感知器的参数估计方法,得到其最低的一个隐层 \(S\) 的残差向量 \(\mathbf δ_s\) 。现在需要将这个残差传播到光栅化层 \(R\) ,光栅化的时候并没有对向量的值做修改,因此其激活函数为恒等函数,其导数为单位向量。
$$\mathbf δ_R =(\mathbf \Theta_S^T \mathbf δ_S) \circ \phi'(\mathbf n_R) = \mathbf \Theta_S^T \mathbf δ_S$$
从上一层传过来的残差为
$$\mathbf δ_R = [\delta_{111}, \delta_{112}, ..., \delta_{11n}, \delta_{121}, \delta_{122}, ..., \delta_{12n}, ..., \delta_{1mn}, ..., \delta_{2mn}, ..., \delta_{jmn}]^T$$
重新整理成为一系列的矩阵即可,若上一层 \(Q\) 有 \(q\) 个池化核,则传播到池化层的残差
$$\Delta_Q = {\mathbf \Delta_1, \mathbf \Delta_2, ..., \mathbf \Delta_q}$$
对应池化过程中常用的两种池化方案,这里反传残差的时候也有两种上采样方案:
最大池化:将1个点的残差直接拷贝到4个点上。
均值池化:将1个点的残差平均到4个点上。
即传播到卷积层的残差
$$\mathbf \Delta_p = upsample(\mathbf \Delta_q)$$
卷积层有参数,所以卷积层的反传过程有两个任务,一是更新权值,另一是反传残差。先看更新权值,即梯度的推导。
如图三上方,先考虑卷积层的某个“神经中枢”中的第一个神经元。根据多层感知器的梯度公式
$$\frac {\partial E} {\partial \theta_{ji}} = \delta_j o_i$$
那么在图三上方的例子中,有
$$\frac {\partial E} {\partial \theta_{11}} = \delta_{11} o_{22} \qquad \frac {\partial E} {\partial \theta_{12}} = \delta_{11} o_{21} \qquad \frac {\partial E} {\partial \theta_{21}} = \delta_{11} o_{12} \qquad \frac {\partial E} {\partial \theta_{22}} = \delta_{11} o_{11}$$
考虑到其他的神经元,每次更新的都是这四个权值,因此实际上等价于一次更新这些偏导数的和。如果仅考虑对 \(\theta_{11}\) 的偏导数,不难发现如图3下方所示,其值应该来自于淡蓝色和灰色区域。是不是似曾相识?是的,又是卷积!但是又有两处重要的不同:
在计算对 \(\theta_{11}\) 的偏导数时,淡蓝色区域和灰色区域的对应位置做运算,但是在卷积运算中,这些位置应该是旋转过来的!
\(\theta_{11}\) 在 \(\Theta\) 矩阵的左上角,而淡蓝色区域在右下角,同样是旋转过的!
因此,对卷积层 \(P\) 中的某个“神经中枢” \(p\), 权值(以及偏置,不再具体推导)更新公式应该是
$$\begin {aligned}\frac {\partial E} {\partial \mathbf \Theta_p} & = rot180((\sum_{q'} \mathbf O_{q'}) *_v rot180(\mathbf \Delta_p))\\\frac {\partial E} {\partial b_p} & = \sum_{u, v} (\delta_p)_{uv}\end {aligned}$$
其中,\(rot180\) 是将一个矩阵旋转180度; \(O_{q'}\) 是连接到该“神经中枢”前的池化层的输出;对偏置的梯度即 \(\Delta_p\) 所有元素之和。
下面讨论残差反传的问题。
如图4,考虑淡蓝色像素点影响到的神经元,在这个例子中,受影响的神经元有4个,他们分别以某个权值与淡蓝色像素运算后影响到对应位置的输出。再结合多层感知器的残差传播公式,不难发现这里又是一个卷积过程!同样需要注意的是,正如图4中的数字标号,这里的卷积是旋转过的;另外,这里用的卷积模式是full。
如果前边的池化层 \(Q'\) 的某个特征图 \(q'\) 连接到这个卷积层 \(P\) 中的某“神经中枢”集合 \(C\) ,那么传播到 \(q'\) 的残差为
$$\mathbf \Delta_{q'} = (\sum_{p \in C} \mathbf \Delta_p *_f rot180(\mathbf \Theta_p)) \circ \phi'(\mathbf O_{q'})$$
最后一公里:Softmax
前边我有意忽略了对Softmax的讨论,在这里补上。因为Softmax的资料已经非常多了,所以这里不再详细讨论。具体可以参考。
需要补充说明的是,不难发现,Softmax的梯度公式与多层感知器的BP过程是兼容的;另外,实现Softmax的时候,如果需要分为 \(k\) 个类,同样也可以设置 \(k\) 个输出节点,这相当于隐含了一个类别名称为“其他”的类。
我建立了一个Github的,目前内容还是空的,近期会逐渐上传。
以层为单位,分别实现卷积层、池化层、光栅化层、MLP隐层、Softmax层这五个层的类。其中每个类都有output和backpropagate这两个方法。
另外,还需要一系列的辅助方法,包括:conv2d(二维离散卷积,valid和full模式),downsample(池化中需要的下采样,两种边界模式),upsample(池化中的上采样),以及dsigmoid和dtanh等。
还需要考虑的是可扩展性和性能优化,这些以后再谈~
Designed by
Refined by}

我要回帖

更多关于 卷积神经网络激活函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信