CRF++中l1范式的处理

风暴红QxRed 发表于 2008-01-03 13:45:10

图1

图2

图3

图4


/*
s[j]为lbfgs得到的lambda[j](即wa[j])的方向
g[j]为lambda[j]的导数
p为考虑l1范式后得到的lambda[j]的移动方向

a)lambda[j]!=0,且p==s[j],则p为移动方向,如果lambda[j]移动时穿过0,那么lambda[j]=0,因为到0另一边,lambda[j]不一定下降(见图4)
b)lambda[j]!=0,且p!=s[j],则lambda[j]不变
c)lambda[j]==0,且g-1/C>0(即g+1/C>g-1/C>0,见图1)则lambda[j]向左边移动,其上的导数为g-1/C
d)lambda[j]==0,且g+1/C<0(即g-1/C<g+1/C<0,见图2)则lambda[j]向右边移动,其上的导数为g+1/C
e)lambda[j]!=0,且g-1/C<0<g+1/C,则lambda[j]=0(见图3)
*/
 
 
 
  for (int j = 1; j <= size; ++j) {
    double grad_neg = 0.0;//lambda[j]左导数
    double grad_pos = 0.0;//lambda[j]右导数
    double grad = 0.0;//考虑l1后的导数
    if (wa[j] == 0.0) { //wa[j]即lambda[j]
      grad_neg = g[j] - 1.0 / C;//0左边导数
      grad_pos = g[j] + 1.0 / C;//0右边导数
    } else {
      grad_pos = grad_neg = g[j] + 1.0 * sigma(wa[j]) / C;//lambda[j]!=0,左导数=右导数
    }
    if (grad_neg > 0.0) {//左右导数都<0,则向左边移动,见图1
      grad = grad_neg;
    } else if (grad_pos < 0.0) {//左右导数都>0,则向左边移动,见图2
      grad = grad_pos;
    } else {
      grad = 0.0;//左右导数异号,则不移动,见图3
    }
    const double p = pi(s[j], -grad);//如果l1后的负导数和lbfgs给的方向s[j]一致,则沿着s[j]移动,否则不移动,情况b)
    const double xi = wa[j] == 0.0 ? sigma(-grad) : sigma(wa[j]);//xi为移动前lambda[j]的符号
    x[j] = pi(wa[j] + *stp * p, xi);//如果移动前后lambda[j]变号,则lambda[j]=0

收藏: QQ书签 del.icio.us 订阅: Google 抓虾

最新评论

发表评论

* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 
 

分类小组论坛
杂谈, 娱乐、八卦, 文学、艺术, 体育, 旅游、同城, 象牙塔, 情感, 时尚、生活, 星座, 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定