Skip to content

神经网络-过拟合-预处理-BN

📅 发表于 2017/11/27
🔄 更新于 2017/11/27
👁️ 次访问
📝 0 字
0 分钟
自然语言处理
#正则化
#范数
#Dropout
#数据预处理
#PCA
#白化
#BN

cs224n的笔记,过拟合、预处理、初始化、Batch Normalization

过拟合

过拟合

训练数据很少,或者训练次数很多,会导致过拟合。避免过拟合的方法有如下几种:

  • early stop
  • 数据集扩增
  • 正则化 (L1, L2权重衰减
  • Dropout
  • 决策树剪枝(尽管不属于神经网络)

现在一般用L2正则化+Dropout。

过拟合时拟合系数一般都很大。过拟合需要顾及到所有的数据点,意味着拟合函数波动很大

看到,在某些很小的区间内里,函数值的变化很剧烈。意味着这些小区间的导数值(绝对值)非常大。由于自变量值可大可小,所以只有系数足够大,才能保证导数值足够大。

所以:过拟合时,参数一般都很大参数较小时,意味着模型复杂度更低,对数据的拟合刚刚好, 这也是奥卡姆剃刀法则。

范数

向量范数

xRd

范数定义
1-范数|x|1=id|xi|绝对值之和
2-范数|x|2=(id|xi|2)12绝对值平方之和再开方
p-范数|x|p=(id|xi|p)1p绝对值的p次方之和的1p次幂
-范数|x|=maxi|xi| ,绝对值的最大值
--范数|x|=mini|xi| ,绝对值的最小值

矩阵范数

ARm×n

范数定义
1-范数|A|1=maxjim|aij|列和范数,矩阵列向量绝对值之和的最大值。
-范数|A|=maxijn|aij|行和范数,所有行向量绝对值之和的最大值。
2-范数|A|2=λm , 其中λmATA最大特征值
F-范数|A|F=(imjnaij2)12所有元素的平方之和,再开方。或者不开方, L2正则化就直接平方,不开方。

L2正则化权重衰减

为了避免过拟合,使用L2正则化参数。λ是正则项系数,用来权衡正则项和默认损失的比重λ 的选取很重要。

JR=J+λi=1LW(i)F

L2惩罚更倾向于更小更分散的权重向量,鼓励使用所有维度的特征,而不是只依赖其中的几个,这也避免了过拟合。

标准L2正则化

λ正则项系数n是数据数量,w是模型的参数。

C=C0+λ2nww2

C对参数wb偏导

Cw=C0w+λnwCb=C0b

更新参数 :可以看出,正则化Cw有影响,对b无影响。

w=wαCw=(1αλn)wαC0w

从上式可以看出:

  • 不使用正则化时,w的系数是1
  • 使用正则化时
    • w的系数是1αλn<1 ,效果是减小w, 所以是权重衰减 weight decay
    • 当然,w具体增大或减小,还取决于后面的导数项

mini-batch随机梯度下降

m 是这个batch的样本个数,有更新参数如下,即求batch个C对w的平均偏导值

w=(1αλn)wαmi=1mCiwb=bαmi=1mCib

所以,权重衰减后一般可以减小过拟合。 L2正则化比L1正则化更加发散,权值也会被限制的更小。 一般使用L2正则化。

还有一种方法是最大范数限制:给范数一个上界w<c , 可以在学习率太高的时候网络不会爆炸,因为更新总是有界的。

实例说明

增加网络的层的数量和尺寸时,网络的容量上升,多个神经元一起合作,可以表达各种复杂的函数。

如下图,2分类问题,有噪声数据。

一个隐藏层。神经元数量分别是3、6、20。很明显20过拟合了,拟合了所有的数据。正则化就是处理过拟合的非常好的办法。

对20个神经元的网络,使用正则化,解决过拟合问题。正则化强度λ很重要。

L1正则化

正则化loss如下:

C=C0+λnw|w|

w偏导, 其中sgn(w)符号函数

Cw=C0w+λnsgn(w)

更新参数:

w=wαλnsgn(w)αC0w

分析:w为正,减小;w为负,增大。所以L1正则化就是使参数向0靠近,是权重尽可能为0,减小网络复杂度,防止过拟合。

特别地:当w=0时,不可导,就不要正则化项了。L1正则化更加稀疏。

随机失活Dropout

Dropout是非常有用正则化的办法,它改变了网络结构。一般采用L2正则化+Dropout来防止过拟合

训练的时候,输出不变,随机以概率p保留神经元,1p删除神经元置位0)。每次迭代删除的神经元都不一样。

BP的时候,置位0的神经元的参数就不再更新只更新前向时alive的神经元

预测的时候,要保留所有的神经元,即不使用Dropout。

相当于训练了很多个(指数级数量)小网络(半数网络),在预测的时候综合它们的结果。随着训练的进行,大部分的半数网络都可以给出正确的分类结果。

数据预处理

用的很多的是0中心化。CNN中很少用PCA和白化。

应该:线划分训练、验证、测试集,只是从训练集中求平均值然后各个集再减去这个平均值

中心化

也称作均值减法, 把数据所有维度变成0均值,其实就是减去均值。就是将数据迁移到原点

x=xavg(x)=xx¯

标准化

也称作归一化, 数据所有维度都归一化,使其数值变化范围都近似相等

  • 除以标准差
  • 最大值和最小值按照比例缩放到(1,1) 之间

方差s2=1n1i=1n(xix¯)2标准差就是s 。数据除以标准差,接近标准高斯分布

x=xs

PCA

斯坦福PCACSDNPCA和SVD的区别和联系

协方差

协方差就是乘积的期望-期望的乘积

Cov(X,Y)=E(XY)E(X)E(Y)

协方差的性质如下:

Cov(X,Y)=Conv(Y,X)Cov(aX,bY)=abConv(Y,X)Cov(X,X)=E(X2)E2(X)=D(X),三方公式Cov(X,C)=0Cov(X,Y)=0XY

还有别的性质就看考研笔记吧。

奇异值分解

Am×n=Um×mΣm×nVn×nT

Vn×nV的列,一组对A正交输入或分析的基向量(线性无关)。这些向量是MTM 的特征向量。

Um×mU的列,一组对A正交输出的基向量 。是MMT的特征向量。

Σm×n对角矩阵。对角元素按照从小到大排列,这些对角元素称为奇异值。 是MTM,MMT 的特征值的非负平方根,并且与U和V的行向量对应。

r非0奇异值的个数,则A中仅有**r个重要特征**,其余特征都是噪声和冗余特征。

奇异值的物理意义

利用SVD进行PCA

先将数据中心化。输入是XRN×D ,则协方差矩阵 如下:

Cov(X)=XTXNRD×D

比如X有a和b两维,均值均是0。那么Cov(ab)=E(ab)0=(a0b0+a1b1++anbn)/n ,就得到了协方差值。

  • 中心化
  • 计算x协方差矩阵cov
  • 对协方差矩阵cov进行svd分解,得到u, s, v
  • 去除x的相关性,旋转xrot=xu ,此时xrot的协方差矩阵只有对角线才有值,其余均为0
  • 选出大于0的奇异值
  • 数据降维
python
def test_pca():
    x = np.random.randn(5, 10)
    # 中心化
    x -= np.mean(x, axis=0)
    print (x.shape)
    # 协方差
    conv = np.dot(x.T, x) / x.shape[0]
    print (conv.shape)
    print (conv)
    u, s, v = np.linalg.svd(conv)
    print (s)
    print (u.shape, s.shape, v.shape)
    # 大于0的奇异值
    n_sv = np.where(s > 1e-5)[0].shape[0]
    print(n_sv)
    # 对数据去除相关性
    xrot = np.dot(x, u)
    print (xrot.shape)
    # 数据降维
    xrot_reduced = np.dot(x, u[:, :n_sv])
    # 降到了4维
    print (xrot_reduced.shape)

白化

斯坦福白化

白化希望特征之间的相关性较低,所有特征具有相同的协方差。白化后,得到均值为0,协方差相等的矩阵。对xrot除以特征值。

xwhite=xrotλ+ϵ
python
x_white = xrot / np.sqrt(s + 1e-5)

缺陷是:可能会夸大数据中的早上,因为把所有维度都拉伸到了相同的数值范围。可能有一些极少差异性(方差小)但大多数是噪声的维度。可以使用平滑来解决。

权重初始化

如果数据恰当归一化以后,可以假设所有权重数值中大约一半为正数,一半为负数。所以期望参数值是0。

千万不能够全零初始化。因为每个神经元的输出相同,BP时梯度也相同,参数更新也相同。神经元之间就失去了不对称性的源头

小随机数初始化

如果神经元刚开始的时候是随机且不相等的,那么它们将计算出不同的更新,并成为网络的不同部分

参数接近于0单不等于0。使用零均值和标准差的高斯分布来生成随机数初始化参数,这样就打破了对称性

python
W = 0.01 * np.random.randn(D,H)

注意:不是参数值初始越小就一定好。参数小,意味着会减小BP中的梯度信号,在深度网络中,就会有问题。

校准方差

随着数据集的增长,随机初始化的神经元的输出数据分布的方差也会增大。可以使用1n 校准方差。n是数据的数量。这样就能保证网络中所有神经元起始时有近似同样的输出分布。这样也能够提高收敛的速度。 感觉实际上就是做了一个归一化。

数学详细推导见cs231ns=inwixi ,假设w和x都服从同样的分布。想要输出s和输入x有同样的方差。

D(s)=nD(w)D(x),D(s)=D(x)D(w)=1nD(wold)=1,D(aX)=a2D(X)D(w)=1nD(wold)=D(1nwold)w=1nwold

所以要使用1n来标准化参数:

python
W = 0.01 * np.random.randn(D,H)/ sqrt(n)

经验公式

对于某一层的方差,应该取决于两层的输入和输出神经元的数量,如下:

D(w)=2nin+nout

ReLU来说,方差应该是2n

python
W = 0.01 * np.random.randn(D,H) * sqrt(2.0 / n)

稀疏和偏置初始化

一般稀疏初始化用的比较少。一般偏置都初始化为0。

Batch Normalization

莫凡python BN讲解CSDN-BN论文介绍 。Batch Normalization和普通数据标准化类似,是将分散的数据标准化。

Batch Normalization在神经网络非常流行,已经成为一个标准了

训练速度分析

网络训练的时候,每一层网络参数更新,会导致下一层输入数据分布的变化。这个称为Internal Convariate Shift

需要对数据归一化的原因

  • 神经网络的本质是学习数据分布。如果训练数据与测试数据的分布不同,那么泛化能力也大大降低
  • 如果每个batch数据分布不同(batch 梯度下降),每次迭代都要去学习适应不同的分布,会大大降低训练速度

深度网络,前几层数据微小变化,后面几层数据差距会积累放大

一旦某一层网络输入数据发生改变,这层网络就需要去适应学习这个新的数据分布。如果训练数据的分布一直变化,那么就会影响网络的训练速度

敏感度问题

神经网络中,如果使用tanh激活函数,初始权值是0.1。

输入x=1, 正常更新:

z=wx=0.1,a(z1)=0.1a(z)=0.99

但是如果一开始输入 x=20 ,会导致梯度消失,不更新参数。

z=wx=2,a(z)1a(z)=0

同样地,如果再输入x=100 ,神经元的输出依然是接近于1,不更新参数。

z=wx=10,a(z)1a(z)=0

对于一个变化范围比较大特征维度,神经网络在初始阶段对它已经不敏感没有区分度了!

这样的问题,在神经网络的输入层和中间层都存在。

BN算法

BN算法在每一次迭代中,对每一层的输入都进行归一化。把数据转换为均值为0、方差为1的高斯分布

x^=xE(x)D(x)+ϵ

非常大的缺陷强行归一化会破坏掉刚刚学习到的特征。 把每层的数据分布都固定了,但不一定是前面一层学习到的数据分布。

牛逼的地方 :设置两个可以学习的变量扩展参数γ ,和平移参数 β用这两个变量去还原上一层应该学习到的数据分布。(但是芳芳说,这一步其实可能没那么重要,要不要都行,CNN的本身会处理得更好)。

y=γx^+β

这样理解:用这两个参数,让神经网络自己去学习琢磨是前面的标准化是否有优化作用,如果没有优化效果,就用γ,β来抵消标准化的操作。

这样,BN就把原来不固定的数据分布,全部转换为固定的数据分布,而这种数据分布恰恰就是要学习到的分布。从而加速了网络的训练

对一个mini-batch进行更新, 输入一个batchsize=m的数据,学习两个参数,输出y

μ=1mi=1mxi求均值σ2=1mi=1m(xiμ)2求方差x^=xE(x)σ2+ϵ标准化y=γx^+βscale and shfit

其实就是对输入数据做个归一化:

z=wx+bz=BN(wx+b)a=f(z)

一般在全连接层和激活函数之间添加BN层。

在测试的时候,由于是没有batch,所以使用固定的均值和标准差,也就是对训练的各个batch的均值和标准差做批处理。

E(x)=E(μ),D(x)=bb1E(σ2)

BN的优点

1 训练速度快

2 选择大的初始学习率

初始大学习率,学习率的衰减也很快。快速训练收敛。小的学习率也可以。

3 不再需要Dropout

BN本身就可以提高网络泛化能力,可以不需要Dropout和L2正则化。源神说,现在主流的网络都没有dropout了。但是会使用L2正则化,比较小的正则化。

4 不再需要局部相应归一化

5 可以把训练数据彻底打乱

效果图片展示

对所有数据标准化到一个范围,这样大部分的激活值都不会饱和,都不是-1或者1。

大部分的激活值在各个分布区间都有值。再传递到后面,数据更有价值。

总访客数:   ·   总访问量:
PLM's Blog @ 2016 - 2025