【2017CS231n】第六讲:训练神经网络(上)

一.激活函数

输入与权重W作用后,输入到非线性的激活函数。激活函数有以下几类:

1.1 Sigmoid

    当输入元素输入到sigmoid函数中,数据会被压缩在[0,1]的范围。当有一个非常大的输入,那么函数的输出结果将非常接近于1。当输入是一个绝对值很大的负数,那么输出接近于0。

Sigmoid函数存在以下三个问题:

1.Sigmoid饱和导致梯度流失


    当我们的输入值特别大时,这时函数的输出就会接近sigmod的正饱和区,所以输出就会变成常数。这时游梯度就是0。

    图中举的例子当x=-10时,sigmod接近负饱和区域,x=0时,会得到一个合理的梯度,进行较好的反向传播,x=10时,梯度为0。

2.Sigmoid是非零中心输出函数


    当输入全为正时,乘以权重w,然后输入到激活函数中,本地梯度df/dw=x,如果所有输入x都为正,那么局部梯度都是正或负。

    w的梯度为dL/df乘以df/dw,这意味着w的梯度,当他们全为正或负时,w总是朝着一个方向移动。在进行w的参数更新时,可以用一个数去更新所有的值,或者增加或者减小。这对于w的更新来说十分低效。

    下面举一个例子来说明:


    在这个例子中我们假设w是二维的。用全为正数或负数的值去迭代。
    蓝色的是梯度的更新方向。我们假设w的最佳值是红色的向量。我们从某一个方向开始更新,但是我们不能从w的这个方向直接优化。因为我们的梯度方向要么为正要么为负,所以w迭代的方向是曲折前进的。
    所以一般情况下我们使用的x均值为0。这样x有正有负,则w的更新就不会是一个方向,在更新时就会高效些。

3.Sigmoid函数是指数函数,计算代价较高。

1.2 tanh函数

    这个挺简单的,大家看下下面的讲义。

1.3 ReLU

ReLU的形式为:max(0,x),不会在正半轴产生饱和现象,梯度计算成本也不高,函数不以0为中心,负半轴会饱和,x=0时我们设定梯度为0。

1.4 dead ReLU

导致dead ReLU的原因:

    w的初始值设置的不好,导致部分输入x与w作用后不能激活ReLU函数。梯度传回来它不会更新也不会被激活。
大部分的ReLU网络都有这个问题,大概10%到20%的会挂掉。
    在实际中人们会用较小的偏置项来初始化ReLU,增加他们在初始化时被激活的可能。但是这个方法不常用,大部分都把偏置项设为0。

1.5 几种ReLU的变种:

1. Leaky ReLU和P ReLU


Leaky ReLU有一个系数0.01,所以不会有饱和的问题。P ReLU采用一个系数a,这个a不用硬编码去写定它,把它当做一个可以学习的参数。

2. EReLU

在负半轴没有斜率,这建立了一种负饱和机制,有利于鲁棒性的提升。但是这种观点现在还有争议。

1.6 最大输出神经元


    两组权值w1和w2分别跟x作用,取较大的值。

    缺点:会使参数翻倍2*w。

1.7 实际中使用的激活函数

    用ReLU呗,不要用sigmoid。

二.数据预处理

    对原始数据进行零均值化和归一化。

    

    在图像领域我们一般只做零均值化,不做归一化和其他复杂的预处理。




    对图像来说我们就是做零均值化的预处理。
    在数据集中计算一个均值图像,对所有要传入网络的数据都减去这个均值图像。在一些网络中我们也通过减去单通道的均值代替减去均值图像。


例子中的图像是32*32*3。图像宽度和高度是32,另外的3代表图像是3通道图像(RGB)。我们得到的单通道均值分别是R均值,G均值,B均值。均值是从所有数据中计算得到的。
    零均值化并没有解决sigmoid遇到的问题,零均值只会在第一层网络中解决sigmod的饱和问题,但是在后续的网络中会有很多非零均值问题,所以问题会在后面的网络中迅速恶化。

三.网络权值初始化

在网络中我们需要初始化w权值,再用梯度下降来更新。

3.1 w=0

    当w=0时,所有的神经元对输入的数据都做同样的事情,他们得到相同的输出和相同的梯度,w将以相同的方式更新。

而我们希望神经元学习到不同的东西。


3.2 w=随机数


    当我们用小的随机数做初始值,例如对高斯分布做抽样。这样解决了参数对称问题。在小的网络中这种方式可以,但是在大的网络中会有问题。


    当我们采用很小的随机数,每层网络的输出会迅速变小,并接近于0,梯度也迅速变小。



当我们取很大的随机数,采用tanh激活函数,会饱和。梯度将接近于0,权值得不到更新。

3.3 Xvaier初始化

要求输入方差等于输出方差,根据这个我们能得到这个初始化的公式。

四.批量归一化

    批量归一化的目的:在我们想要的高斯范围保持激活状态。
    我们想要正确地激活单位高斯函数,我们可以取目前批量处理的均值,然后用均值和方差来进行归一化。
    我们在训练开始时才设置这个值,以便每一层都有很好的单位高斯分布。
    批量归一化做的是将输入数据转化为单位高斯数据(将原始数据平移和缩放)。
    当输入数据是符合高斯分布时,批量归一化并不会使高斯数据损失,因为只是对数据进行平移和缩放,使数据在一个便于操作的区域。

    减去均值再除以标准差就是高斯化。



    假设当前的批处理有N个训练样本,假设每批是D维的,对每个维度计算均值和方差。每个特征元素通过批量处理进行计算。


    通常在全连接层和卷积层之后插入的BN。
    我们通过每个与神经元激活函数相连的输入来进行缩放。
    我们可以用相同的方法连接卷积层,唯一的区别是我们在卷积层的情况下,我们不仅想要归一化所有的特征维度的独立训练实例,而且在我们的激活映射图,包括我们的训练实例,我们想要归一化跨特征维度和空间位置的所有特性。之所以这么做是我们想要服卷积的性质,我们希望附近的位置能以同样的方式进行归一化。

    我们并不清楚是否要在每个全连接层之后进行批量归一化操作,也不清楚是否确实想要给这些tanh非线性函数输入一单位高斯数据。这里只是要把输入数据限制在非线性函数的线性区域,我们只是想避免出现饱和。


    批量归一化就是在进行归一化之后,需要进行额外的缩放操作。我们先做了归一化,然后用常亮γ进行缩放,再用另一个因子β进行平移。网络可以学习缩放因子γ使它等于方差,学习β使它等于均值。γ和β是通过学习得到的因子。



    批量归一化思想:我们提供输入,计算小批量均值(对每个输入的小批量都做这个操作),然后计算方差,通过均值和方差进行归一化,还有额外的缩放和平移因子,从而改进了整个网络的梯度流。批量归一化会使网络更具鲁棒性。

    批量归一化也可以看做是正则化的一种方式:每层的激活值和输出,都源于输入x以及批中被采样的其他样本,因为你将通过这一批样本的经验化均值对输入数据进行归一化,所以它不再对给定的训练样本提供确定的值,而是将输入放入批中。因为不再是确定的值,就像在x中加入一些抖动,实现正则化效果。



    训练时计算和使用的均值和方差在测试时不用重新计算。

五.监督训练过程

    在训练过程中如何调整参数获得好的训练效果。


    首先进行数据预处理。


    第二步选择好的网络结构。



    再三检查一下我们的损失函数是否合理。
    例子中我们有一个归一化指数函数分类器,损失函数是负对数10分类,损失函数是1/10去负对数,大概2.3。


接下来启动正则项,发现损失上升了(不启动正则项损失就是输入数据的损失)。


    下面开始正式训练,拿出所有的训练数据,加入一个小的正则化项。确定最优的学习率。


    设置学习率1e-6,损失基本不变,因为学习率设置的太小了。此时梯度更新也很小。


    当学习率很大1e6时,出现NaN。意味着学习率很高。


    通常我们的学习率范围在[1e-3,1e-5]之间。

六.优化超参数


    对任何超参数,如学习率,我们采用交叉验证的方式。
    在训练集上训练,在验证集上验证。
    选择相当分散的数值,经过几个epochs的训练,发现哪些参数有效。有了一个参数区间,然后更精确地搜索。

    如上面的例子所示,在一些区间用10的幂次进行采样更好。


    也可以进行网格采样。



    观察损失函数的曲线。学习率是一个很重要的参数。



    观察学习率/损失曲线时发现在刚开始很平滑,但是在某一个时间节点突然陡峭下降可能是学习率初始值没有设好。



如果训练精度和验证精度之间有很大的差距,这就说明很可能过拟合了。这时可以增加正则项权重。如果训练精度和验证精度差距不大说明没有过拟合,这时可以增加模型容量,可以提高精度。




  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值