使用 scipy.optimize.minimize 提前停止损失函数

Posted

技术标签:

【中文标题】使用 scipy.optimize.minimize 提前停止损失函数【英文标题】:Early stopping of loss function using scipy.optimize.minimize 【发布时间】:2021-10-20 20:23:18 【问题描述】:

我正在使用 scipy.optimize.minimize 库来自定义编写我的损失函数。 https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html

def customised_objective_func(x):
global lag1
global lag2
global lag3
global lag4

pred = []
err = []
df_col_others_copy=df_col_others.copy(deep=True)
df_col_others_copy*=np.array(x)
pred=intercept_val+df_col_others_copy.sum(axis=1)
pred=list(pred)
col_sales=list(df_col_sales)
err = np.array(pred) - np.array(col_sales)
#err = pred - col_sales
obj_func_cust=sum(err**2)/len(err) + (lambda_mult* pen_func(x))

# CONDITION CHECK
avg_lags_val=(lag1+lag2+lag3+lag4)/float(4.0)
perc_change=(np.abs(obj_func_cust-avg_lag_val)/float(avg_lags_val))*100

if perc_change>=2.0:
    break --###?? Sntax for breaking out here??

# retaining last 4 values
curr=obj_func_cust
lag4=lag3
lag3=lag2
lag2=lag1
lag1=curr

if curr=0:
    

return obj_func_cust

myoptions='maxiter':1000
results = minimize(customised_objective_func,params,method = "BFGS",options = myoptions) 

我保留了为最后 4 次迭代计算的损失函数的值,如果满足该条件,我想检查它们是否存在一些差异我想停止函数调用(即使 1000 次迭代,也要退出进一步函数执行迭代未完成。

我怎样才能做到这一点?希望在此处对要使用的关键字/syntx 提供帮助?

【问题讨论】:

如果我的回答有帮助,请考虑accepting and/or upvoting它。 【参考方案1】:

由于您需要最后四个目标函数值,并且您无法在目标函数中终止求解器,因此您可以编写一个包含回调和目标函数的 Wrapper:

class Wrapper:
    def __init__(self, obj_fun, cond_fun, threshold):
        self.obj_fun = obj_fun
        self.cond_fun = cond_fun
        self.threshold = threshold
        self.last_vals = np.zeros(5)
        self.iters = 0

    def callback(self, xk):
        if self.iters <= 4:
            return False
        if self.cond_fun(self.last_vals) <= self.threshold:
            return True

    def objective(self, x):
        # evaluate the obj_fun, update the last four objective values
        # and return the current objective value
        np.roll(self.last_vals, 1)
        obj_val = self.obj_fun(x)
        self.last_vals[0] = obj_val
        self.iters += 1
        return obj_val

callback 方法返回 True 并在您的最后四个值评估的 cond_fun 低于给定的 threshold 时终止求解器。这里,xk 只是当前点。 objective 方法只是您的 obj_fun 的包装器,并更新最后的目标值。

然后,你可以这样使用它:

def your_cond_fun(last_obj_vals):
    curr = last_obj_vals[0]
    last4 = last_obj_vals[1:]
    avg_vals = np.sum(last4) / last4.size
    return 100*np.abs(curr - avg_vals) / avg_vals

wrapper = Wrapper(your_obj_fun, your_cond_fun, your_threshold)

minimize(wrapper.objective, params, callback = wrapper.callback, 
         method = "BFGS", options = myoptions) 

【讨论】:

所以,我正在尝试检查我的自定义函数中的某些内容。我已编辑问题以更好地解释我的担忧。 @OshinPatwa 无法在目标函数中终止求解器,因此回调是唯一的方法。您可以扩展上述回调,使其存储最后四次迭代的目标函数值。如果有兴趣,我可以编辑我的答案。 明白了,谢谢。是的,你能帮我看看我究竟如何才能做到这一点。

以上是关于使用 scipy.optimize.minimize 提前停止损失函数的主要内容,如果未能解决你的问题,请参考以下文章

第一篇 用于测试使用

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份