zoukankan      html  css  js  c++  java
  • 深度学习——深度学习的实用层面[5]

    目录

    • 数据集划分
    • 偏差和方差
    • 判断方差和偏差并调整的基本思想
    • 解决高方差问题
    • 归一化输入的特征值(X)
    • 梯度爆炸/消失
    • 用双边导数来进行梯度检验

    一、数据集可以划分成三个部分:训练(train)/检验(dev)/测试(test)

    在train set上进行训练,在dev上进行验证找出了最好的模型,最后在test进行评估最终模型的性能如何

    数据集的划分:一般地,数据量小的时候可以用3:1:1划分,数据量较大时,dev和test的数据占比可以小一些

    如果train和dev/test来自不同的源,那么至少要保证dev和test来自相同的分布

    二、偏差和方差

    training set error dev set error    
    1% 11%

    high variance

    方差较高:过拟合

    (在训练集上表现良好,

    但是在测试集上表现较差)

    出现的原因:

    数据有噪声(采集)、训练集不足、

    模型训练过度

     15%  16%  

    high bias

    偏差过高:欠拟合

     
    15%   30%  

    high bias &

    high variance

     
     0.5%  1%  just right  

    三、判断方差和偏差并调整的基本思想

    最优误差:贝叶斯误差  图片分类中,如果train的图像模糊,则可能导致最优误差值较大

    偏差和方差的tradeoff

    if high bias(training data problem):

      use bigger network

      train longer

      NN architecture search

    else(high variance, dev set problem):

      more data

      regulation

      NN architecture search

    四、解决高方差问题

    • L1/L2正则化:

    正则化方法:通过对loss函数添加一个正则项(loss=经验风险+结构风险,系数用来平衡两者),来对模型复杂度进行约束

    给loss函数增加一项L2范数(每一层的$w$范数求和):$J(w, b)=frac{1}{m}sum_i^m{L(widehat{y}^{(i)},y^{(i)})}+frac{lambda}{2m}sum_{l=1}^L||w^{[l]}||^2_F$

    L2范数:向量中各个元素的平方和然后再求平方根$||w||^2_2=sum_{j=1}^{n_x}w_j^2=w^Tw$

        L2正则化也称为权重衰减,因为w值一直乘以一个小于1的数

    $||w^{[l]}||_F^2=sum_{i=1}^{n^{[l-1]}}sum_{j=1}^{n^{[l]}}(w_{ij}^{[l]})^2$

    $dw^{[l]}=(from backprop) + frac{lambda}{m}w^{[l]}$

    $w^{[l]}:=w^{[l]}-alpha dw^{[l]}=(1-frac{alpha lambda}{m})w^{[l]}-alpha (from backprop)$

    L0范数:非0的个数。为了让loss小一些,则参数中非0个数也要少一些,也就是0多一些,即让向量w稀疏

    L1范数:向量w中各个元素的绝对值之和$||w||_1=sum_{j=1}^{n_x}|w_j|$。L0范数不易优化

    $lambda$正则化参数

    为什么L2正则化可以消除高方差的问题

    直观上如果入值很大,为了最小化$J$,那么$W$的值就会趋近于0,则很多隐藏单元的效果就会被消除,网络会变得很简单

    $lambda$变大,$W$变小,z的取值在如下红色区域内,则g(z)就会变成线性(每一层变成线性),也就不可能作出复杂的决策

    常见正则化方法:

    L0范数:约束参数中非0的个数,非凸

    L1范数(Lasso):约束绝对值求和,不能直接求导

    L2正则(ridge regresson):参数值2次方求和,凸函数

    P范数:P次方

    • dropout正则化(随机失活)

    工作方式:遍历每一层并设置消除节点的概率,从而把网络精简,再进行训练

    为什么:开始是希望不要过分依赖于某个参数,dropout作用与L2正则化类似,一般可以用于输入范围比较不同的情况

    keep-prob的设置:每一层的keep-prob可以设置不同。如果节点数比较少(过拟合的可能性比较小),则该值可以大一点

    缺点:代价函数不能被明确定义,因为每次会随机丢弃一些节点,不便于调试(可以先把dropout关闭,保证J是下降的)

    dropout方法在CV中的应用比较多,一般在test阶段不会使用

    常用的实施方法:反向随机失活(invented dropout)

    第$l$层:$l=3$, keep-prob=0.8

    //随机生成一个true/false矩阵,其中每个值为true的概率为0.8(keep-prob保留节点的概率)

    d3=np.random.rand(a3.shape[0], a3.shape[1])

    a3=np.multiply(a3,d3)

    //这一步是inverted dropout:通过除来保持a3的期望值不变

    //因为上一步中a3的结果可能会消除一些节点

    // 原来a3中所有值的平均为sum/n;随机dropout后sum'=0.8sum,相应的n'=0.8n,才能保证期望不变 

    a3/=keep-prob

    • 增大数据集

    由于直接收集数据的代价会大一点,那么可以通过对原有数据进行变形来增加数据量

    • early stopping

    随着迭代次数增加,train上的错误率会下降,而dev的错误会可能会先降后升,可以在dev的最低点停止

    五、归一化输入的特征值(X)

    train和test都应该用同样的$u$和$sigma$作同样操作

    零均值化:$u=frac{1}{m}sum_{i=1}^{m}x^{(i)}$,$x:=x-u$

    归一化方差:$sigma^2=frac{1}{m}sum^m_{i=1}x^2_{(i)}$,$x:=x/sigma$

    为什么归一化

    通过归一化处理,使得X的各个特征值取值在相似的范围内,有利于梯度下降的执行加快速度,每次梯度下降时可以用大一点的步长,不像未归一化时,后期的步长就要很小了

    为什么未归一化时,$J$的图会是这种狭长的?因为如果一个$x$大,一个$x$小。对于当$J$取到同一个值(等势面),则大$x$对应的$w$就要小一点,而小$x$对应的$w$就要大一点

    当特征值的取值范围差很多时,归一化是有必要的

    六、梯度爆炸/消失

    • 导数指数增加/减小
    • 当w大于单位矩阵或小于单位矩阵  vanish/explode

    令$g(z)=z$且$b=0$,则$widehat{y}=w^{[l]}a^{[l-1]}+b^{[l]}=w^{[l]}w^{[l-1]}...w^{[1]}x$

    若$w^{[l]}$是1.5倍的单位矩阵,则$widehat{y}=w^{[1]}egin{bmatrix}1.5 & 0\ 0 & 1.5end{bmatrix}^{[l-1]}x$

    会成梯度增长。反之,$frac{dwidehat{y}}{dw^{[1]}}$梯度下降

    • 避免爆炸/消失的方法:初始化w时,让它是与n层数有关,让w随n增加而变小

    如$w^{[l]}=random*sqrt{frac{2}{n^{[l-1]}}}$

    七、用双边导数来进行梯度检验grad check

    在反向求导中可以进行梯度检验的测试来保证求导是正确的

    • 双边求导

    $g( heta)=frac{f( heta + epsilon)-f( heta - epsilon)}{2epsilon}$

    • 梯度检验

    对每个参数$ heta_i$,$d heta_{approx}^{[i]}=frac{J( heta_1, heta_2..., heta_i+epsilon,...)-J( heta_1, heta_2..., heta_i-epsilon,...)}{2epsilon}\ approx d heta[i]=frac{dJ}{d heta_i}$

    检查$||d heta_{approx}-d heta||_2$和$||d heta_{approx}+d heta||_2$的差值($epsilon=10^{-7}$)

    • 梯度检验实现的注意点
      • 不要在训练时使用,只应该用于debug
      • 如果发现算法grad check失败,考虑在算法模块中识别bug
      • 记住正则化
      • 不要和dropout一起使用,因为可能有些节点会被消除
      • 在随机初始化参数并训练一段时间后进行梯度检验。因为有可能在$w$和$b$接近0时,梯度结果正确,而当和0差较大时,梯度结果不正确(这种情况不太多)
  • 相关阅读:
    周末郑州程序员朋友技术交流中的PPT
    WCF并发连接数的问题
    郑州.Net技术人员的招聘信息
    在路上
    Windows8体验(1)安装
    挖掘0day打进不同学校
    记一次绕过宝塔防火墙的BC站渗透
    一次实战中对tp5网站getshell方式的测试
    一次从弱口令到getshell
    一次HW实战
  • 原文地址:https://www.cnblogs.com/coolqiyu/p/8545164.html
Copyright © 2011-2022 走看看