zoukankan      html  css  js  c++  java
  • 【CS231n】斯坦福大学李飞飞视觉识别课程笔记(十二):神经网络笔记1(上)

    【CS231n】斯坦福大学李飞飞视觉识别课程笔记

    由官方授权的CS231n课程笔记翻译知乎专栏——智能单元,比较详细地翻译了课程笔记,我这里就是参考和总结。

    在这里插入图片描述

    【CS231n】斯坦福大学李飞飞视觉识别课程笔记(十二):神经网络笔记1(上)

    快速简介

    在不诉诸大脑的类比的情况下,依然是可以对神经网络算法进行介绍的。在线性分类一节中,在给出图像的情况下,是使用s=Wxs=Wx来计算不同视觉类别的评分,其中WW是一个矩阵,xx是一个输入列向量,它包含了图像的全部像素数据。在使用数据库CIFAR10CIFAR-10的案例中,xx是一个 [3072x1] 的列向量,WW是一个 [10x3072] 的矩阵,所以输出的评分是一个包含10个分类评分的向量。

    神经网络算法则不同,它的计算公式是s=W2max(0,W1x)s=W_{2}max(0,W_{1}x)。其中W1W_1的含义是这样的:举个例子来说,它可以是一个 [100x3072] 的矩阵,其作用是将图像转化为一个100维的过渡向量。函数max(0,)max(0,-)是非线性的,它会作用到每个元素。这个非线性函数有多种选择,后续将会学到。但这个形式是一个最常用的选择,它就是简单地设置阈值,将所有小于0的值变成0。最终,矩阵W2W_2的尺寸是 [10x100] ,因此将得到10个数字,这10个数字可以解释为是分类的评分。注意非线性函数在计算上是至关重要的,如果略去这一步,那么两个矩阵将会合二为一,对于分类的评分计算将重新变成关于输入的线性函数。这个非线性函数就是改变的关键点。参数W1,W2W_1,W_2将通过随机梯度下降来学习到,他们的梯度在反向传播过程中,通过链式法则来求导计算得出。

    一个三层的神经网络可以类比地看做s=W3max(0,W2max(0,W1x))s=W_{3}max(0,W_{2}max(0,W_{1}x)),其中W1,W2,W3W_1,W_2,W_3是需要进行学习的参数。中间隐层的尺寸是网络的超参数,后续将学习如何设置它们。现在让我们先从神经元或者网络的角度理解上述计算。

    单个神经元建模

    神经网络算法领域最初是被对生物神经系统建模这一目标启发,但随后与其分道扬镳,成为一个工程问题,并在机器学习领域取得良好效果。然而,讨论将还是从对生物系统的一个高层次的简略描述开始,因为神经网络毕竟是从这里得到了启发。

    生物动机与连接

    大脑的基本计算单位是神经元(neuron)。人类的神经系统中大约有860亿个神经元,它们被大约1014101510^{14}-10^{15}突触(synapses)连接起来。下面图表的左边展示了一个生物学的神经元,右边展示了一个常用的数学模型。每个神经元都从它的树突获得输入信号,然后沿着它唯一的**轴突(axon)**产生输出信号。轴突在末端会逐渐分枝,通过突触和其他神经元的树突相连。

    在神经元的计算模型中,沿着轴突传播的信号(比如x0x_0)将基于突触的突触强度(比如w0w_0),与其他神经元的树突进行乘法交互(比如w0x0w_{0}x_{0})。其观点是,突触的强度(也就是权重ww),是可学习的且可以控制一个神经元对于另一个神经元的影响强度(还可以控制影响方向:使其兴奋(正权重)或使其抑制(负权重))。在基本模型中,树突将信号传递到细胞体,信号在细胞体中相加。如果最终之和高于某个阈值,那么神经元将会激活,向其轴突输出一个峰值信号。在计算模型中,我们假设峰值信号的准确时间点不重要,是激活信号的频率在交流信息。基于这个速率编码的观点,将神经元的激活率建模为激活函数(activation function)ff,它表达了轴突上激活信号的频率。由于历史原因,激活函数常常选择使用sigmoidsigmoid函数σsigma,该函数输入实数值(求和后的信号强度),然后将输入值压缩到0-1之间。在本节后面部分会看到这些激活函数的各种细节。

    —————————————————————————————————————————————————————
    在这里插入图片描述
    左边是生物神经元,右边是数学模型。

    —————————————————————————————————————————————————————

    一个神经元前向传播的实例代码如下:

    class Neuron(object):
      # ... 
      def forward(inputs):
        """ 假设输入和权重是1-D的numpy数组,偏差是一个数字 """
        cell_body_sum = np.sum(inputs * self.weights) + self.bias
        firing_rate = 1.0 / (1.0 + math.exp(-cell_body_sum)) # sigmoid激活函数
        return firing_rate
    

    换句话说,每个神经元都对它的输入和权重进行点积,然后加上偏差,最后使用非线性函数(或称为激活函数)。本例中使用的是sigmoidsigmoid函数σ(x)=1/(1+ex)sigma(x)=1/(1+e^{-x})。在本节的末尾部分将介绍不同激活函数的细节。

    粗糙模型:要注意这个对于生物神经元的建模是非常粗糙的:在实际中,有很多不同类型的神经元,每种都有不同的属性。生物神经元的树突可以进行复杂的非线性计算。突触并不就是一个简单的权重,它们是复杂的非线性动态系统。很多系统中,输出的峰值信号的精确时间点非常重要,说明速率编码的近似是不够全面的。鉴于所有这些已经介绍和更多未介绍的简化,如果你画出人类大脑和神经网络之间的类比,有神经科学背景的人对你的板书起哄也是非常自然的。如果你对此感兴趣,可以看看这份评论或者最新的另一份

    作为线性分类器的单个神经元

    神经元模型的前向计算数学公式看起来可能比较眼熟。就像在线性分类器中看到的那样,神经元有能力“喜欢”(激活函数值接近1),或者“不喜欢”(激活函数值接近0)输入空间中的某些线性区域。因此,只要在神经元的输出端有一个合适的损失函数,就能让单个神经元变成一个线性分类器。

    二分类SoftmaxSoftmax分类器。举例来说,可以把σ(Σiwixi+b)displaystylesigma(Sigma_iw_ix_i+b)看做其中一个分类的概率P(yi=1xi;w)P(y_i=1|x_i;w),其他分类的概率为P(yi=0xi;w)=1P(yi=1xi;w)P(y_i=0|x_i;w)=1-P(y_i=1|x_i;w),因为它们加起来必须为1。根据这种理解,可以得到交叉熵损失,这个在线性分类II一节中已经介绍。然后将它最优化为二分类的SoftmaxSoftmax分类器(也就是逻辑回归)。因为sigmoidsigmoid函数输出限定在0-1之间,所以分类器做出预测的基准是神经元的输出是否大于0.5。

    二分类SVM分类器。或者可以在神经元的输出外增加一个最大边界折叶损失(maxmarginhingelossmax-margin hinge loss)函数,将其训练成一个二分类的支持向量机。

    理解正则化。在SVM/SoftmaxSVM/Softmax的例子中,正则化损失从生物学角度可以看做逐渐遗忘,因为它的效果是让所有突触权重ww在参数更新过程中逐渐向着0变化。

    一个单独的神经元可以用来实现一个二分类分类器,比如二分类的SoftmaxSoftmax或者SVMSVM分类器。

    常用激活函数

    每个激活函数(或非线性函数)的输入都是一个数字,然后对其进行某种固定的数学操作。下面是在实践中可能遇到的几种激活函数:

    —————————————————————————————————————————————————————
    在这里插入图片描述
    左边是SigmoidSigmoid非线性函数,将实数压缩到 [0,1] 之间。右边是tanhtanh函数,将实数压缩到 [-1,1]。

    —————————————————————————————————————————————————————

    SigmoidSigmoidsigmoidsigmoid非线性函数的数学公式是σ(x)=1/(1+ex)displaystylesigma(x)=1/(1+e^{-x}),函数图像如上图的左边所示。在前一节中已经提到过,它输入实数值并将其“挤压”到0到1范围内。更具体地说,很大的负数变成0,很大的正数变成1。在历史上,sigmoidsigmoid函数非常常用,这是因为它对于神经元的激活频率有良好的解释:从完全不激活(0)到在求和后的最大频率处的完全饱和(saturatedsaturated)的激活(1)。然而现在sigmoidsigmoid函数已经不太受欢迎,实际很少使用了,这是因为它有两个主要缺点:

    • SigmoidSigmoid函数饱和使梯度消失。sigmoidsigmoid神经元有一个不好的特性,就是当神经元的激活在接近0或1处时会饱和:在这些区域,梯度几乎为0。回忆一下,在反向传播的时候,这个(局部)梯度将会与整个损失函数关于该门单元输出的梯度相乘。因此,如果局部梯度非常小,那么相乘的结果也会接近零,这会有效地“杀死”梯度,几乎就有没有信号通过神经元传到权重再到数据了。还有,为了防止饱和,必须对于权重矩阵初始化特别留意。比如,如果初始化权重过大,那么大多数神经元将会饱和,导致网络就几乎不学习了。

    • SigmoidSigmoid函数的输出不是零中心的。这个性质并不是我们想要的,因为在神经网络后面层中的神经元得到的数据将不是零中心的。这一情况将影响梯度下降的运作,因为如果输入神经元的数据总是正数(比如在f=wTx+bf=w^Tx+b中每个元素都x>0x>0),那么关于ww的梯度在反向传播的过程中,将会要么全部是正数,要么全部是负数(具体依整个表达式f而定)。这将会导致梯度下降权重更新时出现zz字型的下降。然而,可以看到整个批量的数据的梯度被加起来后,对于权重的最终更新将会有不同的正负,这样就从一定程度上减轻了这个问题。因此,该问题相对于上面的神经元饱和问题来说只是个小麻烦,没有那么严重。

    TanhTanhtanhtanh非线性函数图像如上图右边所示。它将实数值压缩到 [-1,1] 之间。和sigmoidsigmoid神经元一样,它也存在饱和问题,但是和sigmoidsigmoid神经元不同的是,它的输出是零中心的。因此,在实际操作中,tanhtanh非线性函数比sigmoidsigmoid非线性函数更受欢迎。注意tanhtanh神经元是一个简单放大的sigmoidsigmoid神经元,具体说来就是:tanh(x)=2σ(2x)1tanh(x)=2sigma(2x)-1

    —————————————————————————————————————————————————————
    在这里插入图片描述
    左边是ReLUReLU(校正线性单元:RectifiedLinearUnitRectified Linear Unit)激活函数,当x=0x=0时函数值为0。当x>0x>0函数的斜率为1。右边是从Krizhevsky等的论文中截取的图表,指明使用ReLUReLU比使用tanhtanh的收敛快6倍。

    ReLUReLU。在近些年ReLUReLU变得非常流行。它的函数公式是f(x)=max(0,x)f(x)=max(0,x)。换句话说,这个激活函数就是一个关于0的阈值(如上图左侧)。使用ReLUReLU有以下一些优缺点:

    • 优点:相较于sigmoidsigmoidtanhtanh函数,ReLUReLU对于随机梯度下降的收敛有巨大的加速作用( Krizhevsky 等的论文指出有6倍之多)。据称这是由它的线性,非饱和的公式导致的。

    • 优点:sigmoidsigmoidtanhtanh神经元含有指数运算等耗费计算资源的操作,而ReLUReLU可以简单地通过对一个矩阵进行阈值计算得到。

    • 缺点:在训练的时候,ReLUReLU单元比较脆弱并且可能“死掉”。举例来说,当一个很大的梯度流过ReLUReLU的神经元的时候,可能会导致梯度更新到一种特别的状态,在这种状态下神经元将无法被其他任何数据点再次激活。如果这种情况发生,那么从此所有流过这个神经元的梯度将都变成0。也就是说,这个ReLUReLU单元在训练中将不可逆转的死亡,因为这导致了数据多样化的丢失。例如,如果学习率设置得太高,可能会发现网络中40%的神经元都会死掉(在整个训练集中这些神经元都不会被激活)。通过合理设置学习率,这种情况的发生概率会降低。

    LeakyReLULeaky ReLULeakyReLULeaky ReLU是为解决“ReLUReLU死亡”问题的尝试。ReLUReLU中当x<0x<0时,函数值为0。而LeakyReLULeaky ReLU则是给出一个很小的负数梯度值,比如0.01。所以其函数公式为f(x)=1(x<0)(αx)+1(x>=0)(x)f(x)=1(x<0)(alpha x)+1(x>=0)(x)其中αalpha是一个小的常量。有些研究者的论文指出这个激活函数表现很不错,但是其效果并不是很稳定。Kaiming He 等人在2015年发布的论文Delving Deep into Rectifiers中介绍了一种新方法PReLUPReLU,把负区间上的斜率当做每个神经元中的一个参数。然而该激活函数在在不同任务中均有益处的一致性并没有特别清晰。

    MaxoutMaxout。一些其他类型的单元被提了出来,它们对于权重和数据的内积结果不再使用f(wTx+b)f(w^Tx+b)函数形式。一个相关的流行选择是MaxoutMaxout(最近由 Goodfellow 等发布)神经元。MaxoutMaxout是对ReLUReLUleakyReLUleaky ReLU的一般化归纳,它的函数是:max(w1Tx+b1,w2Tx+b2)max(w^T_1x+b_1,w^T_2x+b_2)ReLUReLULeakyReLULeaky ReLU都是这个公式的特殊情况(比如ReLUReLU就是当w1,b1=0w_1,b_1=0的时候)。这样MaxoutMaxout神经元就拥有ReLUReLU单元的所有优点(线性操作和不饱和),而没有它的缺点(死亡的ReLUReLU单元)。然而和ReLUReLU对比,它每个神经元的参数数量增加了一倍,这就导致整体参数的数量激增。

    以上就是一些常用的神经元及其激活函数。最后需要注意一点:在同一个网络中混合使用不同类型的神经元是非常少见的,虽然没有什么根本性问题来禁止这样做。

    一句话:“那么该用那种呢?”用ReLUReLU非线性函数。注意设置好学习率,或许可以监控你的网络中死亡的神经元占的比例。如果单元死亡问题困扰你,就试试LeakyReLULeaky ReLU或者MaxoutMaxout,不要再用sigmoidsigmoid了。也可以试试tanhtanh,但是其效果应该不如ReLUReLU或者MaxoutMaxout

    神经网络笔记1(上)完。

  • 相关阅读:
    Python中所有的关键字
    关于selenium的8种元素定位
    对提示框的操作
    selenium+webservice进行百度登录
    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled...报错解决
    Vue中使用echarts
    npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142解决方法
    插入排序
    冒泡排序优化
    roject 'org.springframework.boot:spring-boot-starter-parent:XXX' not found 解决
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13302803.html
Copyright © 2011-2022 走看看