zoukankan      html  css  js  c++  java
  • Kaldi中的L2正则化

    steps/nnet3/train_dnn.py

    --l2-regularize-factor

    影响模型参数的l2正则化强度的因子。要进行l2正则化,主要方法是在配置文件中使用'l2-regularize'进行配置。l2正则化因子将乘以组件中的l2正则化值,并且可用于通过模型平均化以校正与并行化带来的影响。 float,默认值= 1

    src/nnet3/nnet-utils.cc:2030

    void ApplyL2Regularization(const Nnet &nnet, BaseFloat l2_regularize_scale, Nnet *delta_nnet) { /*...*/

    //nnet是更新前的神经网络

    const Component *src_component_in = nnet.GetComponent(c);

    //delta_nnet是进行更新后的神经网络

    UpdatableComponent *dest_component =

    dynamic_cast<UpdatableComponent*>(delta_nnet->

    GetComponent(c));

    //delta_nnet->c -= 2.0 * l2_regularize_scale * alpha * eta * nnet.c

    // alphaL2正则化常数

    // eta为学习率

    // nnet.c为该nnetcomponent(应该是权重)

    // l2_regularize来自于L2Regularization(),该函数返回UpdatableComponent中的L2正则化常量通常由配置文件设定)。

    // 根据steps/libs/nnet3/xconfig/basic_layers.py:471

    // 可以xconfig中指定l2-regularize(默认为0.0)

    // 一般通过ApplyL2Regularization()而非组件层的代码读取该常量。ApplyL2Regularization(),声明于nnet-utils.h(训练工作流的一部分)。

    BaseFloat scale = -2.0 * l2_regularize_scale * lrate * l2_regularize;

    // nnet3/nnet-simple-component.cc:1027

    // linear_params_.AddMat(alpha, other->linear_params_);

    // bias_params_.AddVec(alpha, other->bias_params_);

    /*...*/}

    //输出的统计数值

    CuVector<double> value_sum_;

    //非线性(神经元)的微分的统计数值(只适用于以向量元素为单位的非线性,不适用于Softmax

    CuVector<double> deriv_sum_;

    //objective derivative function sum square

    //目标函数微分的平方和,用于诊断

    CuVector<double> oderiv_sumsq_;

    //oderiv_sumsq_stats数量

    double oderiv_count_;

       

    对于神经网络中的每个可更新组件c,假设它在组件中设定了l2正则化常量alpha(请参阅UpdatableComponent::L2Regularization())和学习率eta,那么此函数为(伪代码):

    对求W偏导:

    可以发现L2正则化项对b的更新没有影响,但是对于w的更新有影响:

       

    delta_nnet-> c -= 2.0 * l2_regularize_scale * alpha * eta * nnet.c

    nnet.cw

    eta为学习率

    因子-1.0-=,减等于)是为了最大化正则化项;

    因子2.0来自参数平方的导数。该函数使用了"l2_regularize_scale"因子,请参阅下面的说明。

       

       

    注意:由于与自然梯度的相互作用,KaldiL2正则化是普通方法的近似。问题在于普通梯度乘以经过近似化、平滑化、比例缩放的Fisher矩阵的逆,但是l2梯度不是。这意味着我们正在优化的不是常规的"目标函数 + L2正则化项"这种形式,我们可以将其视为"常规目标函数 + L2正则化项 × Fisher矩阵" ,前提是 参数变化量不受到Fisher矩阵缩放的影响,所以这不会影响L2的整体强度,只会影响是方向(direction-wise)权重。实际上,在大的Fisher矩阵的变换方向上,相对于梯度,L2项的贡献将更大。这可能并不理想,但如果没有实验就很难判断。无论如何,L2的影响足够小,并且Fisher矩阵根据identity进行了充分的平滑,我怀疑这会产生很大的差别。

    要为nnet3设定L2正则化,可以调用nnet3/xconfig_to_configs.py:

  • 相关阅读:
    tp5.1 查询自定义排序(按照查询结果顺序排序)
    Laravel Auth 用户认证
    Laravel 文件上传
    Laravel 缓存操作
    Laravel 验证码
    第46章:TEB
    第45章:TLS回调函数
    第4章:逆向分析技术--32位软件逆向技术
    第43章:内核6中的DLL注入
    第42章:内核6中的会话
  • 原文地址:https://www.cnblogs.com/JarvanWang/p/9152622.html
Copyright © 2011-2022 走看看