代码之家  ›  专栏  ›  技术社区  ›  Viktoriya Malyasova

为什么我的自定义lightgbm损耗没有减少?

  •  0
  • Viktoriya Malyasova  · 技术社区  · 5 年前

    我在lightgbm中实现了一个自定义平均误差(MAE)损失。梯度不是零,但损耗保持不变。怎么可能?

    我的实施:

    def abs_obj(preds, dtrain):
        y_true = dtrain.get_label()
        a = preds - y_true
        grad = np.sign(a)
        hess = np.zeros(len(a))
        return grad, hess
    
    def abs_eval(preds, dtrain):
        y_true = dtrain.get_label()
        loss = np.abs(preds - y_true).sum()
        return "error", loss, False
    

    一个最小的可重复性示例:损失保持不变。

    dtrain = pd.DataFrame({'x':np.random.rand(100),
                          'y':np.random.rand(100)})
    ytrain = dtrain.x + 2 * dtrain.y
    dval = dtrain
    yval = ytrain
    lgb_train = lgb.Dataset(dtrain, ytrain)
    lgb_valid = lgb.Dataset(dval, yval)
    params = {'objective':None,
             'learning_rate':30,
             'num_leaves':33}
    clf = lgb.train(params,
                   lgb_train,
                   valid_sets=[lgb_valid],
                   num_boost_round=10,
                   verbose_eval=1,
                   fobj=abs_obj,
                   feval=abs_eval)
    
    1 回复  |  直到 4 年前
        1
  •  5
  •   Viktoriya Malyasova    4 年前

    对于lightgbm中的自定义损失,需要一个具有正二阶导数的二次可微函数。

    为了加速算法,lightgbm使用 Newton's approximation 要找到最佳叶值:

    y=-L'/L''

    (见 this blogpost 详细信息)。

    当二阶导数为零或函数不可二次微分时,这种近似是非常错误的。Lightgbm具有不符合此标准的内置目标函数,例如MAE。对于这些功能,它们有不同的特殊实现。