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 // alpha为L2正则化常数 // eta为学习率 // nnet.c为该nnet的component(应该是权重) // 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.c即w; eta为学习率 因子-1.0(-=,减等于)是为了最大化正则化项; 因子2.0来自参数平方的导数。该函数使用了"l2_regularize_scale"因子,请参阅下面的说明。 ? ? ? ? 注意:由于与自然梯度的相互作用,Kaldi的L2正则化是普通方法的近似。问题在于普通梯度乘以经过近似化、平滑化、比例缩放的Fisher矩阵的逆,但是l2梯度不是。这意味着我们正在优化的不是常规的"目标函数 + L2正则化项"这种形式,我们可以将其视为"常规目标函数 + L2正则化项 × Fisher矩阵" ,前提是 参数变化量不受到Fisher矩阵缩放的影响,所以这不会影响L2的整体强度,只会影响是方向(direction-wise)权重。实际上,在大的Fisher矩阵的变换方向上,相对于梯度,L2项的贡献将更大。这可能并不理想,但如果没有实验就很难判断。无论如何,L2的影响足够小,并且Fisher矩阵根据identity进行了充分的平滑,我怀疑这会产生很大的差别。 要为nnet3设定L2正则化,可以调用nnet3/xconfig_to_configs.py: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |