继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

神经网络简介--激活函数、网络架构、生物模型解释

至尊宝的传说
关注TA
已关注
手记 129
粉丝 82
获赞 463

概述

无需类比大脑的机制我们也能介绍神经网络。本节我们通过线性分类器,通过公式s=Wxs=Wx(其中WW是一个矩阵,xx是输入的列向量,包含图片的所有像素。对于CIFAR-10数据来说,xx是一个[3072 * 1]的列向量,WW是[10 * 3072]的矩阵,因此ss是一个[10 *1]的列向量,代表十个类别的分数)对给定图片可能属于的不同类别进行打分。
计算分数时,采用s=W2max(0,W1x)s=W2max(0,W1x)则是就是一个神经网络。如前例所示,W1W1若为[100 * 3072]的矩阵,则可以将图片转换100维的列向量。函数max(0,∗)max(0,)是一个非线性函数,对矩阵或向量的每个元素都进行操作。除此之外我们还可以选择其他的非线性函数(之后我们会学习到),但是这个函数是最常用的。此外,W2W2的维度可以为[10 * 100],最后得到的10个数字,我们将其解释为10个分类的分数。需要注意的是,这里的非线性函数非常重要,如果我们不使用非线性函数,两个矩阵运算就可以用一个矩阵表示,最终的预测分数就和采用用线性函数没有区别了。非线性函数能够改变这一情况。W1,W2W1,W2可以通过随机梯度下降学习,它们的梯度通过链式法则求导得到。(反向传播计算)
一个三层的神经网络类似于s=W3max(0,W2max(0,W1x))s=W3max(0,W2max(0,W1x))W1,W2,W3W1,W2,W3都是将要学习的参数,中间隐藏层的大小是神经网络的超参数,之后我们会学习如何选取。我们现在来看看如何从神经元的角度解释神经网络。

神经元模型

与生物学的联系

神经网络这个领域最初的主要灵感来源于如何为生物神经系统建模。但此后神经网络分支成为工程问题,并在机器学习任务中取得了良好的结果。 所以,在我们开始讨论前,对这个让神经网络领域产生很大启发的生物系统,进行个非常简短和宏观的描述。
大脑的基本计算单位是一个神经元。人类神经系统中可发现大约860亿个神经元,并且它们与大约1014−101510141015个突触相连。图1表示生物神经元,图2表示常见的数学模型。每个神经元接收来自其树突的输入信号并沿着其(单个)轴突产生输出信号。轴突最终分出并通过突触连接到其他神经元的树突。在神经元的计算模型中,沿轴突传播的信号(例如x0x0)基于该突触(例如w0w0)处的突触强度与另一神经元的树突相乘(例如w0x0w0x0)。这个想法是突触强度(权重w)是可以学习的,并且控制一个神经元对另一个神经元的影响力(及其方向:兴奋(权重为正)或抑制(权重为负))。在基本模型中,树突将信号传送到细胞体,在那里它们都被求和。如果最终总和超过一定的阈值,神经元可以激活,沿轴突发出尖峰。在数学计算模型中,我们假设尖峰的准确时间不重要,只有激活的频率传达信息。基于这种速率编码解释,我们用激活函数f来模拟神经元的放电速率,该函数表示沿着轴突的尖峰频率。从历史上看,sigmoid函数是激活函数的一个常见选择,因为它需要一个实值输入(求和后的信号强度),并将其压缩至0和1之间。稍后我们将看到这些激活函数的细节。

 
 图1  神经元模型

 
 图2  数学模型

单个神经元的前向传播代码如下所示:

class Neuron(object):
  # ... 
  def forward(self, inputs):
    """ assume inputs and weights are 1-D numpy arrays and bias is a number """
    cell_body_sum = np.sum(inputs * self.weights) + self.bias
    firing_rate = 1.0 / (1.0 + math.exp(-cell_body_sum)) # sigmoid activation function
    return firing_rate1234567

换句话说,每个神经元对输入和权重进行点积操作,加上偏差后并采用非线性函数(或者叫激活函数)转换数据,上面代码采用的是sigmoidσ(x)=1/(1+e−x)sigmoidσx=1/1+ex。 我们将在本节末尾详细介绍不同的激活函数。

粗糙模型 需要强调的是,这种生物神经元模型非常粗糙:例如,有许多不同类型的神经元,每种神经元都具有不同的属性。 生物神经元中的树突执行复杂的非线性计算。 突触不仅仅有一个单一的权重,他们是一个复杂的非线性动力系统。 已知许多系统中输出尖峰的确切时间非常重要,这表明速率编码近似可能不成立。 由于采用了很多简化,因此当您在神经网络和真正的大脑之间进行类比,请准备好听取来自具有神经科学背景的任何人的不屑。

单神经元作为线性分类器

神经元前向计算的数学形式看起来很熟悉。 正如我们用线性分类器所看到的那样,神经元可以在输入空间的某些线性区域“喜欢”(激活值接近1)或“不喜欢”(激活值接近0)。因此,通过对神经元的输出采用适当的损失函数,我们可以将单个神经元变成线性分类器:
二元Softmax分类器。 例如,我们可以将σ(Σiwixi+b)σΣiwixi+b解释为将输入分类成某个类的概率P(yi=1|xi;w)Pyi=1|xi;w。 对于二分类问题,另一个类的概率是P(yi = 0xi; w)= 1-P(yi = 1xi; w),因为它们必须和为1。 通过这种解释,我们可以定义其交叉熵损失(cross-entropy)。并且优化它将其作为一个二元Softmax分类器(也称为逻辑回归)。 由于S形函数被限制在0-1之间,因此该分类器通过判断神经元的输出是否大于0.5来预测结果。
二元SVM分类器。 我们可以在神经元的输出上附加一个max-margin hinge loss,并将其训练成二元支持向量机。
正则化。 从在这个生物学的角度看,SVM/SoftmaxSVM/Softmax下的正则化损失可以解释为逐渐遗忘,因为突触权重ww会在每次更新参数后趋向于清零ww

常用的激活函数

每个激活函数(或非线性函数)都输入一个数字并对其执行某种固定的数学运算。 在实际中可能会遇到几种激活函数:




 图3  sigmoid函数,将输入压缩到(0,1)范围内





 图4  tanh函数,将输入压缩到(-1,1)范围内


sigmoid(图3所示)。 S型函数具有数学形式σ(x)=1/(1+e−x)σ(x)=1/(1+ex)。如前所述,它取一个实数值并将其“压扁”到0到1之间的范围内。大的负数变为0,大的正数变为1。历史上经常使用Sigmoid函数,因为它很好地被解释为一个神经元的激活率:从完全不激活(取值为0)到完全饱和激活(取值为1)。实际中,S形非线性近已经不受欢迎,现在很少使用它。 主要是因为它有两个缺点:

  • Sigmoid函数饱和时会”杀死”梯度。 S形神经元非常不好的特性是,当神经元的激活在0或1的尾部饱和时,这些区域的梯度几乎为零。 回想一下,在反向传播过程中,这个(局部)梯度将乘以该神经元的输出对于整个目标的梯度。 因此,如果局部梯度非常小,它将有效地“杀死”梯度,几乎没有信号会通过神经元流向其权重并递归到其数据。因此,在初始化S形神经元的权重时,为防止饱和时,必须格外小心。例如,如果初始权重太大,那么大多数神经元会变得饱和,网络几乎不能进行学习。

  • Sigmoid输出不是以零为中心的。 这是我们不希望的特性,因为在神经网络的后续层中的神经元将接收不是以零为中心的数据。 这对梯度下降过程中的动力有影响,因为如果进入神经元的数据总是正的(例如,在f=wTx+bf=wTx+b中所有x>0x>0)),则反向传播期间权重ww的梯度将全部为正或全部负(取决于整个表达式f的梯度)。 这会在权重的梯度更新中引入不希望的锯齿形动态更新。但是,请注意,处理完一批数据后(batch data),权重最终的更新可能会有可变的符号,这略微缓解了这个问题。因此,这是一个不便之处,但与上面的饱和激活问题相比,其后果不那么严重。

tanhtanh(图4)。 它将实值数字压缩到范围[-1,1]。 像S形神经元一样,它有激活饱和的问题,但与S形神经元不同,它的输出是零中心的。 因此,在实践中tanh非线性始终优于S形非线性。 还要注意tanh神经元只是一个缩放的S形神经元,可以表示为:tanh(x)=2σ(2x)−1tanhx=2σ2x1

RELU(图5所示)。RELU(The Rectified Linear Unit)在过去几年中变得非常流行。它计算函数f(x)=max(0,x)fx=max0x。使用ReLUs有以下几个优点和缺点:

  • (优点)与S形tanh函数相比,随机梯度下降的收敛速度显着加快(Krizhevsky等人文献中提到为6倍,图6显示为其对比)。有人认为,这是因为其线性非饱和形式的原因。

  • (优点)与涉及复杂操作(指数等)的tanh / sigmoid神经元相比,ReLU可以通过将激活矩阵简单地设置阈值为零来实现。

  • (缺点)不幸的是,在训练过程中,ReLU单元可能会变得脆弱,并可能“死亡”。例如,流经ReLU神经元的大梯度可能导致权重更新,使得神经元不会再在任何数据上激活。如果发生这种情况,那么从该点开始流经该单元的梯度将永远为零。也就是说,ReLU单元在训练期间可能会不可逆转地死亡。例如,如果学习率设置得太高,您可能会发现多达40%的网络可能“死亡”(即从未在整个训练数据集中激活的神经元)。通过设置合适的学习率,可以缓解这个问题。

    图5  RELU函数

    图6 ReLU收敛速度大约为tanh的6倍

leak ReLU。leak ReLUs是解决ReLU 单元”死亡”问题的一种尝试。当x <0时,leak ReLU将具有小的负斜率(大约为0.01左右)。也就是说,函数计算f(x)=?(x<0)(αx)+?(x>=0)(x)fx=?x<0αx+?x>=0x其中α是一个小常数。有些人用这种形式的激活函数取得成功,但结果并不总是一致的。负向区域的斜率也可以作为每个神经元的参数,正如2015年Kaiming He等人在Delving Deep into Rectifiers中介绍的PReLU神经元中所看到的那样。然而,针对不同任务,leak ReLU的效果并不是完全一致,具体原因也没有研究清楚。

MAXOUT。也有一些函数形式不是f(wTx+b)fwTx+b的单元。 Maxout神经元(最近由Goodfellow等人提出)是一种相对流行的选择,它概括了ReLU及其leak版本。 Maxout神经元计算函数max(wT1x+b1,wT2x+b2)maxwT1x+b1wT2x+b2。请注意,ReLU和Leak ReLU都是这种形式的特例(例如,对于ReLU,我们有w1,b1 = 0)。 因此Maxout神经元有ReLU单元的所有优点(线性操作状态,没有饱和),并且没有缺点(ReLU的死亡单元)。然而,与ReLU神经元不同,它使每个神经元的参数数量加倍,从而导致参数总数很高。

这就结束了我们对最常见类型的神经元及其激活函数的讨论。 作为最后的评论,在同一网络中混合使用不同类型的神经元是非常罕见的,尽管这样做没有根本性的问题。

如果文:“我应该使用哪种神经元类型?”那么答案是:使用ReLU非线性,小心你的学习速率,并尽可能监测网络中“死亡”单元的比例。 如果出现了问题,请尝试使用Leaky ReLU或Maxout。 切勿使用sigmoid。 试试tanh,但一般情况下它比ReLU / Maxout更糟糕。

神经网络架构

分层组织

神经网络是作神经元组成的图。 神经网络模型是一个非循环图中连接的神经元集合。 换句话说,一些神经元的输出可以成为其他神经元的输入。 环是不允许的,因为这意味着在网络的正向传递中有无限循环。 神经网络模型通常组织成不同层次的神经元,而不是无组织的连接。 对于规则的神经网络,最常见的层类型是完全连接层,其中两个相邻层之间的神经元完全成对连接,但是单个层内的神经元不共享连接。 图7和图8是两个使用完全连接层的示例神经网络拓扑:




图7   2层神经网络(4个神经元的隐藏层和2个神经元的输出层)和三个输入。





图8  具有三个输入的三层神经网络,两个四个神经元的隐藏层和一个输出层。 请注意,在这两种情况下,跨层的神经元之间都存在连接(突触),但层内没有连接。


命名约定。请注意,当我们说N层神经网络时,我们不计入输入层。因此,单层神经网络描述了一个没有隐藏层的网络(输入直接映射到输出)。从这个意义上讲,你有时会听到人们说逻辑回归或支持向量机只是单层神经网络的特例。 您也可能会听到这些网络也会被称为“人工神经网络”(ANN)或“多层感知器”(MLP)。许多人不喜欢神经网络和真实大脑之间的类比,而更喜欢将神经元作为单元。
输出层。与神经网络中的其他层不同,输出层神经元通常不具有激活函数(或者可以将它们视为有线性激活函数)。这是因为最后的输出层通常被用来表示类别分数(例如在分类中),可能是任意的实数值,或者某种类型的实值目标(例如在回归中)。

衡量神经网络的大小。人们通常用来衡量神经网络大小的两个指标是神经元的数量,或者更常见的是参数的数量。在前文中使用两个示例网络:

第一个网络(图7)具有4 + 2 = 6个神经元(不包括输入),[3×4] + [4×2] = 20个权重和4 + 2 = 6个偏差,总共26个可学习参数。
第二个网络(图8)具有4 + 4 + 1 = 9个神经元,[3×4] + [4×4] + [4×1] = 12 + 16 + 4 = 32个权重和4 + 4 + 1 = 9偏差,总共41个可学习参数。
为了给你一些背景知识,现代卷积网络包含大约1亿个参数,通常由大约10-20层构成(因此深度学习)。但是,由于参数共享,我们将看到有效连接的数量显着增加。更多内容我们会在卷积神经网络章节中学习。

前馈计算示例

前馈计算实际上就是重复的矩阵乘法与激活函数的计算交织在一起。神经网络为层组织的主要原因之一就是这种结构进行矩阵向量操作计算神经网络非常简单高效。在上图中使用示例三层神经网络,输入是[3x1]向量。一个层的所有连接权重都可以存储在一个矩阵中。例如,第一个隐藏层的权重W1W1的大小为[4x3],所有单位的偏差都在矢量b1b1中,大小为[4x1]。在这里,每一个神经元都有一个W1的权重,所以矩阵向量乘法np.dot(W1,x)np.dotW1x计算该层所有神经元的激活。类似地,W2W2将是一个[4x4]矩阵,用于存储第二个隐藏层的连接,W3W3为最后一个(输出)层的[1x4]矩阵。这个3层神经网络的完整正向传递就是三个矩阵乘法,与激活函数的计算交织在一起,如下代码所示:

# forward-pass of a 3-layer neural network:f = lambda x: 1.0/(1.0 + np.exp(-x)) #activation function (use sigmoid)x = np.random.randn(3, 1) # random input vector of three numbers (3x1)h1 = f(np.dot(W1, x) + b1) # calculate first hidden layer activations (4x1)h2 = f(np.dot(W2, h1) + b2) # calculate second hidden layer activations (4x1)out = np.dot(W3, h2) + b3 # output neuron (1x1)123456

在上面的代码中,W1,W2,W3,b1,b2,b3是网络的可学习参数。 还要注意,变量x可以保存所有训练数据(其中每个输入样本将是x的一列),而不是只有单个输入列向量,这样所有样本将并行地进行计算。 此外,最后的神经网络层通常不具有激活功能(例如,它表示分类问题中的(实值)类分数)。

神经网络的表示能力

全连接层的神经网络实际上是定义了一系列由网络权重参数化的函数。一个很自然的问题是:这个函数族能表示能力如何?是否有不能用神经网络建模的函数?

事实证明,有一个以上隐藏层的神经网络是通用逼近器。也就是说,它可以表示出来(参见1989年Sigmoidal函数叠加的逼近(pdf),或Michael Nielsen的这个直观的解释),给定任意连续函数f(x)fx,当ε>0ε>0时,存在一个神经网络g(x)gx带有一个以上隐藏层(选取合理的非线性函数,例如sigmoid),使得∀x,|f(x)−g(x)|x|fxgx|<ε。换句话说,神经网络可以逼近任何连续函数。

如果一个隐藏层就足以近似任何函数,那为什么要使用更多的隐藏层呢?答案是,双层神经网络是一个通用逼近器,尽管在数学上很简便,但在实践中却是相对较弱且无用的。在一个维度中,函数g(x)=Σici?(ai<x<bigx=Σici?ai<x<bi)其中a,b,c是参数向量也是一个通用逼近器,但没有人会建议我们在机器学习中使用这个函数。神经网络在实践中运行良好,因为它们简洁地表达平滑的函数,这些函数非常好地拟合了我们在实践中遇到的数据的统计特性,而且使用我们的优化算法(例如梯度下降)也很容易学习。类似地,尽管深层网络和单隐层网络的表示能力是相等的,但是根据经验观察发现,深层网络比单隐层网络效果更好。

顺便说一下,在实践中,3层神经网络通常会比2层网络性能好很多,但更深层(4,5,6层)的性能提高不明显。这与卷积网络形成鲜明对比,现在发现卷积神经网络深度是良好识别系统(例如,按照10个可学习层的顺序)是非常重要的组成部分。支撑这种现象的一个观点是:图像包含分层结构(例如,面部由眼睛组成,其由边缘等组成),因此多层处理对于该数据域而言是直观的。
当然,整个问题涉及更多知识,也是最近研究的主题。如果您对这些主题感兴趣,我们建议您进一步阅读:
Deep Learning ,尤其是第6.4节。
Do Deep Nets Really Need to be Deep?
FitNets: Hints for Thin Deep Nets

设置图层数量及其大小

在实际问题中,我们如何选择架构?我们应该使用隐藏层吗?一个隐藏层?或两个隐藏层?每层应该有多少单元?首先,随着我们增加神经网络中的层大小和数量,网络的容量也会增大。也就是说,可表示函数的空间会增加,因为神经元可以合作表达许多不同的函数。例如,假设我们在二维中存在二元分类问题。我们可以训练三个独立的神经网络,每个神经网络都有一个大小不等的隐藏层,并获得以下分类器:




 图9  越大的神经网络可以代表越复杂的函数。圆圈代表数据点,不同颜色代表不同类别。并且由训练的神经网络决定的区域显示在下方。你可以在这个ConvNetsJS中演示这些例子。


在图9中,我们可以看到具有更多神经元的网络可以表达更复杂的函数。然而,这既有好处(因为我们可以学习分类更复杂的数据)也有坏处(因为它更容易过度训练数据)。当具有高复杂度的模型拟合数据中的噪音而不是(假定的)数据之间的潜在关系时,过拟合就会发生。例如,具有20个隐藏神经元的模型拟合了所有训练数据,但是它将空间分割成许多不相交的红色和绿色决策区域。3个隐藏神经元的模型具有的表示能力只能将数据粗笔画地分类。它将数据建模为两块,并将绿色簇内的少数红色点解释为异常值(噪声)。在实践中,这可能会使模型对测试集有更好的泛化能力。


基于我们上面的讨论,如果数据不够多,为防止过拟合似乎较小的神经网络是更优选的。然而,这是不正确的,有许多其他的方法可以防止过度拟合(例如L2正则化(regularization) ,丢失(DropOut),输入噪声(input noise))。在实践中,使用这些方法来控制过度拟合比控制神经元数量的效果要好。

这背后的一个微妙的原因是,梯度下降等局部方法在较小的网络中更难进行:很显然,它们的损失函数具有相对较少的局部最小值,但事实证明,局部最小值越多越容易收敛,而且较小网络的局部最小值是不好的(即高损失)。相反,更大的神经网络包含更多的局部最小值,但是这些最小值在实际损失方面要比较小的网络好得多。由于神经网络是非凸的,所以很难从数学上研究这些性质,但是为了理解这些目标函数研究者已经做了一些尝试,例如,在最近的论文The Loss Surfaces of Multilayer Networks。在实践中,你发现如果你训练一个小型网络,最终的损失可能会表现出很大的差异 - 在某些情况下,你很幸运收敛到一个低损失的局部最小值,但有时,你又会陷入一个高损失的局部最小值。另一方面,如果你训练一个大型网络,你会发现许多不同的解决方案,但最终实现的损失差异会小得多。换句话说,所有的解决方案都大致相同,并且不依赖于随机初始化的运气。

重申一下,正则化强度是控制神经网络过度拟合的首选方法。我们可以看看三种不同正则化的结果:



图10 正则化强度的影响:每个神经网络有20个隐藏的神经元,提高正则化参数使其最终决策区域更平滑。你可以在这个ConvNetsJS中演示这个例子


结论是你不应该因为害怕而使用较小的网络。相反,您应该根据计算预算允许的限制来设置神经网络的大小,并使用其他正则化手段来控制过拟合。

概要

综上所述:

  • 我们介绍了一个非常粗糙的生物神经元模型

  • 我们讨论了在实践中使用的几种类型的激活函数,其中ReLU是最常用的

  • 我们介绍了神经网络,神经元与完全连接的层连接时,相邻层中的神经元具有完全的成对连接,但层内的神经元没有连接

  • 我们看到,这种分层架构能够交织使用激活函数和矩阵乘法,对神经网络进行高效评估

  • 我们看到,神经网络是通用函数逼近器,但这个属性与它们被广泛使用无关。它们的使用是因为它们对实践中出现函数的形式做出了某些“正确”的假设

  • 大型网络总是比小型网络工作得更好,但是它们更大的复杂度必须通过更强的正则化(比如更大的权重衰减)来解决,否则它们可能会过拟合。在后面的章节中我们会看到更多的正则化形式(特别是Droout)。

引用

deeplearning.net tutorial with Theano
ConvNetJS直观的演示
Michael Nielsen’s tutorials

译文出处

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP