如何获取scipy.optimize.curve_fit拟合后的迭代次数?涉及maxfev参数
获取scipy.optimize.curve_fit的实际迭代/函数调用次数
scipy.optimize.curve_fit默认不会直接返回迭代次数,但可以通过两种方式获取拟合过程中实际执行的函数评估次数(和maxfev直接相关的核心指标):
方法一:使用full_output参数获取nfev
当设置full_output=True时,curve_fit会返回包含详细拟合信息的元组,其中infodict字典里的nfev字段记录了实际完成的函数调用次数(maxfev是你设置的允许上限,nfev是实际使用的次数)。
示例代码:
import numpy as np from scipy.optimize import curve_fit # 定义拟合函数 def exp_func(x, a, b): return a * np.exp(-b * x) # 生成带噪声的模拟数据 x = np.linspace(0, 4, 50) y = exp_func(x, 2.5, 1.3) + 0.2 * np.random.normal(size=x.size) # 执行拟合并开启完整输出 popt, pcov, infodict, mesg, ier = curve_fit(exp_func, x, y, full_output=True) # 提取实际函数调用次数 actual_nfev = infodict['nfev'] print(f"实际函数调用次数:{actual_nfev}")
关键说明:
- 如果拟合在达到
maxfev前收敛,nfev会小于maxfev; - 如果拟合未收敛且触发了
maxfev上限,nfev会等于maxfev,同时返回的ier状态码会提示迭代次数超出(比如返回4); nfev是函数评估次数,和迭代次数不完全等价(部分迭代步骤可能多次调用函数),但可以作为拟合计算量的核心参考。
方法二:自定义回调函数追踪迭代过程
如果需要实时追踪每一步迭代,可以直接调用curve_fit底层的_leastsq函数,传入自定义回调函数来计数。
示例代码:
import numpy as np from scipy.optimize._minpack import _leastsq # 初始化迭代计数器 iter_counter = 0 def iteration_callback(xk): global iter_counter iter_counter += 1 print(f"当前迭代步数:{iter_counter}") # 定义拟合函数和残差函数 def exp_func(x, a, b): return a * np.exp(-b * x) def residuals(params, x, y): return y - exp_func(x, *params) # 生成模拟数据 x = np.linspace(0, 4, 50) y = exp_func(x, 2.5, 1.3) + 0.2 * np.random.normal(size=x.size) # 调用底层leastsq并传入回调 initial_guess = [1, 1] _leastsq(residuals, initial_guess, args=(x, y), maxfev=1000, callback=iteration_callback) print(f"总迭代步数:{iter_counter}")
关键说明:
curve_fit本身的接口没有暴露callback参数,因此需要直接调用底层的_leastsq;- 回调函数会在每次迭代时触发,计数器累加后得到总迭代步数。
内容的提问来源于stack exchange,提问作者AleNekro97
相关产品推荐
相关产品推荐

