Kaldi中的L2正则化

Posted jarvanwang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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:

技术分享图片

以上是关于Kaldi中的L2正则化的主要内容,如果未能解决你的问题,请参考以下文章

正则化项L1和L2的直观理解及L1不可导处理

深度学习中的正则化——L1L2 和 Dropout

L1、L2正则化

L1正则化和L2正则化

神经网络与深度学习笔记L2正则化

浅析L2参数正则化的数学含义