神经网络细节

神经网络细节

一、激活函数(Activation Function)

  • Sigmoid



sigmoid函数又被称为挤压函数,取值为[0,1]之间的实数。同时,sigmoid存在3个问题:
(1)一个饱和的神经元(Saturated neurons),即神经元的输出要么非常接近1要么非常接近0。这类神经元会导致在反向传播算法中出现梯度趋0的问题,叫做梯度消失。sigmoid函数计算路线:

输入一个x,会输出一个sigmoid结果,然后进行反向传播,运用链式法则,最终得到dl/dx,链式法则就是将这两项相乘。
当x取-10或10时,梯度会非常小。在sigmoid图像上可以看到,在取值-10的地方,因为这点的斜率为0,梯度几乎为0;在取值为10的地方也几乎是0。那么问题来了,在输出是1或者0的时候,那么你的梯度将会趋于0,当局部梯度是一个很小的数,在进行反向传播的时候将会停止。当数据都落在饱和区域,输出值不是0就是1,那么梯度将无法对网络进行反向传播,因为梯度的传播将很快停止。只有当数据落在安全区域时才会变化,这一安全区域我们被称为sigmoid函数的激活区域。
(2)另一个问题是,sigmoid函数的输出不是关于远点中心对称的。假设我们有一个多层的sigmoid神经网络,如果你的输入x都是正数,然后这些不关于原点对称的输出值都集中在0和1之间,那么在反向传播中w的梯度会传播到网络的某一处,那么权值的变化是要么全正要么全负。解释下:当梯度从上层传播下来,w的梯度都是用x乘以f的梯度,因此如果神经元输出的梯度是正的,那么所有w的梯度就会是正的,反之亦然。在这个例子中,我们会得到两种权值,权值范围分别位于图中一三象限:

当输入一个值时,w的梯度要么都是正的要么都是负的,当我们想要输入一三象限区域以外的点时,我们将会得到这种并不理想的曲折路线(zig zag path),图中红色曲折路线。虽然这个理由很简单,但根据经验得出,如果我们训练的数据并不关于原点中心对称,收敛速度会非常之慢。
(3)最后一个问题就是,sigmoid函数计算exp()非常耗时的,训练很大的卷积网络,过程非常慢。
  • tanh(x)

    tanh(x)函数的输出是[-1,1]之间的实数,好比两个sigmoid函数叠在一起,由图像可以看出tanh是关于原点对称的。tanh(x)与sigmoid函数有相同的缺点,就是梯度仍然会出现的饱和的问题,导致梯度无法传播。

  • ReLU(Rectified Linear Unit修正线性单元)

    ReLU是一种非线性函数max(0,x)。使用ReLU激活函数,神经网络收敛速度非常快,首先因为ReLU不会饱和,至少在输入为正的时候,在正的区域内不会产生梯度弥散的问题,梯度不会突然为0,当神经元在很小的有边界的区域被激活时,才会出现梯度消失的问题。实际上,这些神经元只在反向传播的过程中才会被激活,不论正确与否,至少在一半的区域内(正区域内)反向传播不会是0。ReLU的缺点如下:
    (1)输出结果不是关于原点对称的;
    (2)有一个很烦恼的事,当输入的神经元x<0时梯度会消散。非激活的输入值无法进行反向传播,权值也不会更新。
    Hint:这里说的梯度是指泛化的梯度,指原函数是必须可微的。】
    在使用ReLU激活函数的时候,可能会发生这样的情形,如果这个神经元什么都不输出,那么说明没有任何的梯度,假如梯度弥散了,就不会有任何更新。
    初始化ReLU神经元时,输入数据集之后,我们可能会得到dead ReLU神经元,如果神经元在数据集的外面,那么dead ReLU将永远不会激活,参数也不会更新。

    以上问题的发生,通常发生在一下两种情况:
    (1)在初始化过程中,如果你非常不幸的将权重设置成不能使神经元激活的数值,神经元将不会训练Data集;
    (2)在训练过程中,若学习速率太高,想象一下这些神经元在一定范围内波动,将会发生数据多样性的丢失,在这种情况下,神经元不会被激活,数据多样性的丢失也不会逆转。

  • Leaky ReLU

    Leaky ReLU很好的解决了dead ReLU的问题,因为Leaky ReLU保留了第三象限的曲线,分段线性并保留了ReLU的效率。以前ReLU在第三象限的区域内的梯度会消失,而Leaky ReLU给这个区间一个很小的负或正的斜率,而不会有神经元死了的问题。

  • PReLU(参数校正器)

    PReLU对Leaky ReLU进行升级,由表达式可以看出,多了一个α参数,那么计算图中的每一个神经元都会有一个α参数,就像偏置值b一样,α参数可以由反向传播学习此参数。同时只有让αx和x不相等,计算过程才有意义。

  • ELU(Exponential Linear Units )

    ELU是由Clevert等人在2015年提出的,使用非常普遍, 有着ReLU所有的优点,并且不会出现dead ReLU,并且有着接近0的平均输出。但是因为表达式中有exp(),所以有一定的计算成本。

  • Maxout “Neuron”(Maxout神经元)
    Maxout “Neuron”是由Goodfellow等人在2013年提出的一种很有特点的神经元,它的激活函数、计算的变量、计算方式和普通的神经元完全不同,并有两组权重。先得到两个超平面,再进行最大值计算。激活函数是Generalizes ReLU和Leaky ReLU,没有ReLU函数的缺点,不会出现神经元失活(dead),仍然是分段线性和高效率。

    在使用Maxout神经元时,会有2倍的参数问题。这个方法不是很理想。

二、Data Preprocessing(数据预处理)


如图是原始数据,数据矩阵X有三种常见的数据预处理形式,其中我们假定X的大小为[N×D](N是数据的数量,D是它们的维数)。

  • 归一化处理(normalized data)
    22.png
    如上图所示,归一化处理是指每个维度都通过标准偏差来进行缩放或者确保每个维度最大值和最小值在-1到1之间等等,红线表示数据的范围,中间长度不等,右边长度相等。在图像处理中,归一化并不常用。

  • 零中心化处理

    零中心化处理是指减去每个维度的平均值,进而使得数据是以零为中心的。数据云集中在原点的周围。在图像处理中,零中心化处理是一种常用的数据预处理的方式。

  • PCA and Whitening(PCA算法和白化处理)
    PCA和白化是数据预处理的另一种方式。在这个过程中,应用PCA算法将协方差矩阵变成对角矩阵,或者对数据进行白化处理,那意味着在PCA处理后对数据进行压缩,使协方差矩阵变成单位矩阵,这种预处理方式在机器学习中经常用到。

以上三种数据预处理的方法在图像处理中并不常用,在图像处理中常见的是均值中心化处理,以32*32*3的CIFAR图像为例,有两种方式实现:
减去均值图像
经过计算后得到一个32*32*3的均值图像,用每张图像减去均值图像进行中心化处理,从而获得更好的训练效果。
减去单通道均值
这种数据预处理方式常常用在VGGNet中,在红绿蓝三色通道中分别计算,分别得到3个数值。这种预处理方式非常常用,因为我们只需要关心三个数值,而不用考虑上一方法中均值图像中的那个均值图像数组。

1、Weight Initialization(权重初始化)

w(权重)的初始化问题,如果不进行初始化,那么在w=0的情况下所有的神经元都是一样的,在反向传播时的梯度都是一样的,这个网络不能工作。因此,人们用很小的随机数值代替,随机数值是从标准差为0.01的高斯公式中随机抽取,这是w初始化的一种方式。

这种方式应用层数少的神经网络还可以,但是随着层数的增加,这种简单的初始化方法是无效的。

2、Batch Normalization

“Internal Covariate Shift”问题是指:在训练过程中,因为各层参数老在变,所以每个隐层都会面临covariate shift的问题,也就是在训练过程中,隐层的输入分布老是变来变去,这就是所谓的“Internal Covariate Shift”,Internal指的是深层网络的隐层,是发生在网络内部的事情,而不是covariate shift问题只发生在输入层。

因此,就有了Batch Normalization的基本思想:能不能让每个隐层节点的激活输入分布固定下来呢?这样就避免了“Internal Covariate Shift”问题了。

那么,详细解释Batch Normalization的基本思想:对于每个隐层神经元,把逐渐向非线性函数映射后向取值区间极限饱和区靠拢的输入分布强制拉回到均值为0方差为1的比较标准的正态分布,使得非线性变换函数的输入值落入对输入比较敏感的区域,以此避免梯度消失问题。因为梯度一直都能保持比较大的状态,所以很明显对神经网络的参数调整效率比较高,就是变动大,就是说向损失函数最优值迈动的步子大,也就是说收敛地快。
几个正态分布
假设某个隐层神经元原先的激活输入x取值符合正态分布,正态分布均值是-2,方差是0.5,对应上图中最左端的浅蓝色曲线,通过BN后转换为均值为0,方差是1的正态分布(对应上图中的深蓝色图形),意味着什么,意味着输入x的取值正态分布整体右移2(均值的变化),图形曲线更平缓了(方差增大的变化)。这个图的意思是,BN其实就是把每个隐层神经元的激活输入分布从偏离均值为0方差为1的正态分布通过平移均值压缩或者扩大曲线尖锐程度,调整为均值为0方差为1的正态分布。

标准正态分布
这意味着在一个标准差范围内,也就是说64%的概率x其值落在[-1,1]的范围内,在两个标准差范围内,也就是说95%的概率x其值落在了[-2,2]的范围内。那么这又意味着什么?我们知道,激活值y=WX+B,X是真正的输入,y是某个神经元的激活值,假设非线性函数是sigmoid,那么看下sigmoid(x)其图形:

及sigmoid(x)的导数为:G’=f(x)*(1-f(x)),因为f(x)=sigmoid(x)在0到1之间,所以G’在0到0.25之间,其对应的图如下:
sigmoid导数图
假设没有经过BN调整前x的原先正态分布均值是-6,方差是1,那么意味着95%的值落在了[-8,-4]之间,那么对应的Sigmoid(x)函数的值明显接近于0,这是典型的梯度饱和区,在这个区域里梯度变化很慢,为什么是梯度饱和区?请看下sigmoid(x)如果取值接近0或者接近于1的时候对应导数函数取值,接近于0,意味着梯度变化很小甚至消失。而假设经过BN后,均值是0,方差是1,那么意味着95%的x值落在了[-2,2]区间内,很明显这一段是sigmoid(x)函数接近于线性变换的区域,意味着x的小变化会导致非线性函数值较大的变化,也即是梯度变化较大,对应导数函数图中明显大于0的区域,就是梯度非饱和区。

BN就是把隐层神经元激活输入y=WX+B从变化不拘一格的正态分布通过BN操作拉回到了均值为0,方差为1的正态分布,即原始正态分布中心左移或者右移到以0为均值,拉伸或者缩减形态形成以1为方差的图形。经过BN后,目前大部分Activation的值落入非线性函数的线性区内,其对应的导数远离导数饱和区,这样来加速训练收敛过程。

神经网络的结构:

注意t层某个神经元的x(k)不是指原始输入,就是说不是t-1层每个神经元的输出,而是t层这个神经元的激活y=WX+B,这里的X才是t-1层神经元的输出。
变换的意思是:某个神经元对应的原始的激活y通过减去mini-Batch内m个实例获得的m个激活y求得的均值E(x)并除以求得的方差Var(x)来进行转换。
上文说过经过这个变换后某个神经元的激活x形成了均值为0,方差为1的正态分布,目的是把值往后续要进行的非线性变换的线性区拉动,增大导数值,增强反向传播信息流动性,加快训练收敛速度。但是这样会导致网络表达能力下降,为了防止这一点,每个神经元增加两个调节参数(scale和shift),这两个参数是通过训练来学习到的,用来对变换后的激活反变换,使得网络表达能力增强,即对变换后的激活进行如下的scale和shift操作,这其实是变换的反操作:


BN具体操作流程:

参考资料:CS231n课程笔记翻译:神经网络笔记

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值