cs231n-lecture6 神经网络的训练Part1

Lecture6的内容比较多,稍微复杂一点,但是在实际操作中都是非常有用的知识点。

结合视频课件还有课堂笔记可以比较好的理解这章的内容,我写这篇文章是为了梳理一下自己的理解,也方便自己以后回顾。

目录

Activation Functions

Data Preprocessing

Weight Initialization

Batch Normalization

Babysitting the Learning Process

Hyperparameter Optimization

 

Activation Functions(激活函数)

Sigmoid

数学公式\sigma (x) = \frac{1}{1+e^{-x}}

图形

优点:可以将数据挤压到(0,1)的输出,具有比较好的激活性

缺点

sigmoid函数饱和使梯度消失。在输入值比较大或者比较小的情况下sigmoid的导数使趋近于0,使得w梯度消失,从而不能有效的进行梯度下降。所以我们必须小心的初始化w,防止输入的值过大或者过小。

sigmoid函数输出不是以0为中心的。会导致梯度下降时以z字形下降,效率不高。

分析一下为何函数输出不是以0为中心会导致梯度下降效率降低

假设L = f(\sigma (w_1x_1+w_2x_2+b))f表示loss函数,z=w_1x_1+w_2x_2+b,那么可以得到

dw_1 = \frac{\partial L}{\partial \sigma } \frac{\partial \sigma}{\partial z}\frac{\partial z }{\partial w_1}=\frac{\partial L}{\partial \sigma }\sigma (1-\sigma )x_1dw_2 = \frac{\partial L}{\partial \sigma } \frac{\partial \sigma}{\partial z}\frac{\partial z }{\partial w_2}=\frac{\partial L}{\partial \sigma }\sigma (1-\sigma )x_2

我们知道\sigma的值在0到1之间,所以\sigma (1-\sigma )肯定大于0,对于w_1,w_2而言\frac{\partial L}{\partial \sigma }是常数,所以如果x_1,x_2都为正数(对于sigmoid而言计算出来的下一层的输入都为正数,就是非0为中心的输出),那么w_1,w_2必定同为正数或者负数。

假设对这种情况下,我们的最优解是w_1需要增加,w_2需要减少,但是w_1,w_2是同符号的,所以必定会以一种类似z的路径下降。

exp的计算消耗稍微有点大。这个是很小的问题,因为卷积运算本身计算消耗也是非常大的。

tanh

数学公式tanh(x) = \frac{e^{x} - e^{-x}}{e^{x} + e^{-x}}

图形

优点:将数据压缩在了(-1,1)之间,输出是以0为中心

缺点:当输入很大或者很小的时候梯度会消失,exp的计算消耗。

ReLU

数学公式f(x) = max(0, x)

图形

优点:1.计算简单,消耗小。2.收敛速度快。3.梯度不会饱和

缺点:1.不是以0为中心的输出。2.在训练中小于0的数据会”死掉“。

如果输入数据小于了0,那么这部分数据会死掉也不能再被激活,如果学习率设置的太高可能会导致40%的神经元都死掉。小心的设置学习率可以改善这个问题。

Leaky ReLU

数学公式f(x) = max(\alpha x, x)\alpha是超参数,可以取值为0.1或者0.01之类。

图形

优点:相对ReLU,多了一个优点,不会有神经元死掉。

还有一个PReLU,就是\alpha作为参数来学习,而不是像Leaky ReLU一样作为超参数来预设。

ELU

数学公式

图形

优点:1.所有ReLU的优点。2.类似于0中心化。3.相对Leaky ReLU负数区域的梯度消失前增加了一个鲁棒的干扰

缺点:1.计算有指数计算

Maxout ”Neuron“

数学公式f(x) = max(w_1^Tx+b_1,w_2^Tx+b_2)

优点:1.线性计算。2.不会梯度消失。3.神经元不会死掉。

缺点:参数的数量会double

总结

1.如果使用ReLU,需要小心的设置学习率

2.可以试试Leaky ReLU/Maxout/ELU

3.如果尝试tanh不要期待太好

4.不要用sigmoid

 

数据处理

均值减法

减去数据的均值,相当于把数据云移到以原点为中心的位置。对于图片而言可以对RGB分别求出均值,然后用RGB分别减去对应的均值。如果要归一化还可以减去数据的标准差。代码实现方式可以从下面的图片中看到。

PCA和白化

常见的数据预处理的方式,但是在图像中使用的很少。下面的图片中可以看到PCA处理后的数据云(2)和白化处理后的数据云(3)。

总结

对图像处理而言一般只需要中心化即可,一般不做其他的操作。

但是需要注意的是,我们的操作步骤应该是选对数据集分出train/val/test,然后通过训练集计算出RGB的mean,在对train/val/test这些数据集都减去这个mean的值。

 

Weights初始化

不应该全0初始化。如果我们对w全部初始化为0,就会陷入网络对称化的问题,使得每一层的输入都相同,并且反向传播的导数都相同,这样更新也相同,如果有n个神经元就相当于缩减成了1个神经元。

下面举个例子来说明。

有一个两层的神经网络,w11,w12,w13是与x1,x2,x3分别相乘输出是a1,w21,w22,w23是与x1,x2,x3分别相乘输出a2。h11,h12是与a1,a2分别相乘输出y。

现在假设x是x1,x2,x3列出来的列向量。w1是将w11,w12,w13列出来的列向量,w2是将w21,w22,w23列出来的列向量。a是a1,a2的列向量,h是h11,h12的列向量。

如果w1=w2,h11=h12会发生什么情况?

a_1=x^{T}w_1+b,a2 = x^{T}w_2+b,因为w_1=w_2,所以a_1=a_2

dw_1=\frac{\partial L}{\partial a_1}\frac{\partial a_1}{\partial w_1}=\frac{\partial L}{\partial a_1}x

dw_2=\frac{\partial L}{\partial a_2}\frac{\partial a_2}{\partial w_2}=\frac{\partial L}{\partial a_2}x

如果L= a1*h_{11}+a2*h_{12}+b,那么\frac{\partial L}{\partial a_1}=h_{11},\frac{\partial L}{\partial a_2}=h_{12}

所以可以推导出dw_1=dw_2,后面的梯度更新也会得到一样的值,最后的效果是相当于我们只有a1或者a2这一个神经元。

可以用小的随机数初始化。代码是:W=np.random.randn(D, H) * 0.01,randn表示随机生成的数据是符合高斯分布的(均值为0,标准差为1的分布),然后与0.01相乘后将数据缩小100倍,就生成了比较小的随机数。为什么最好用比较小的随机数呢?如果W的指都比较大,会使计算出来的结果可能接近一些激活函数的梯度饱和区域,导致梯度下降失去活性。

并不是小数值一定会有好的结果。如果神经网络中权重值很小,那么计算出来的梯度也会很小,这样在很深的网络中也会失去梯度下降的活性。

如果输入的数据量很大,可能与W计算后输出值的分布的方差会增大,因此可以初始化W的时候稍作变化,W=np.random.randn(fan_in, fan_out)/sqrt(fan_in),实验证明这种初始化方式可以提高收敛速度,推导过程参考课程笔记。另外对于ReLU激活函数有一个特殊初始化方式,W=np.random.randn(fan_in, fan_out)/sqrt(2.0/n),如果使用ReLU激活,推荐这种方式进行初始化。这种方式的初始化都叫做Xavier初始化。

偏置bias一般初始化为0.

 

Batch Normalization

归一化相当于对每一层的数据都进行归一预处理,使数据均值接近0,标准差接近1,为什么说是接近,因为我们会给每一层自我学习的能力带来一点灵活性。

第一个公式将数据归一为均值为0,方差为1,然后给每一层一点自我学习的能力增加了\gamma ^{k}\beta ^{k}这两个可以学习的参数,如果\gamma ^{k}为输入数据的标准差,\beta ^{k}为输入数据的均值,那么就相当于归一化为了高斯分布,但是增加了这两个参数不为标准差和均值时,数据就会稍微不同于高斯分布,这样每一层数据可以稍微调整,拥有自己的特色。

BN一般放在全连接或者卷积运算之后,而在激活函数之前

好处

  • 促进梯度在网络中的传播
  • 允许更高的学习率
  • 减少对参数初始化的强依赖
  • 有轻微的正则化效果

注意:测试阶段均值和标准差不是由测试的batch计算出来的,而是使用训练时平均均值和标准差。所以代码中我们需要对BN接口指定是training还是test阶段。否则很可能预测的结果非常不准确(在这个细节上吃过亏)

 

训练步骤

1.预处理数据:X -= np.mean(X, axis=0), X /= np.std(X, axis=0)

2.选择模型:定义神经网络的层数,每一层宽度,激活函数,loss等

3.开始训练:先迭代比较少的次数,对一些超参数做一些调整,比如learning rate等。

 

超参数的优化

用比较小的epoch来研究超参数对loss下降的影响,然后一点点调整。

所有参数以外的配置都是超参数,需要自己进行调整,比如:网络结构,学习率,正则化方式等。

就像调音师,需要一点一点的调整来达到最好的效果。

总结:

  1. 激活函数用ReLU
  2. 输入预处理用减去均值的方式
  3. 参数初始化使用Xavier
  4. BN要使用
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值