三指数衰减拟合时Non-linear Least Squares fit不收敛问题咨询
问题根因
- 最小化函数
fun逻辑错误:你定义的入参x, t, y完全没有被使用,函数内部硬编码了全局变量x_data、y_data,且待优化的拟合参数没有从参数数组x中拆分取值,导致无论x怎么调整,返回的残差都不会变化,优化器无法迭代更新参数。 - 初始参数数组
x0引用了未定义的变量:A21、T21等变量没有提前赋值,应该对应你之前设置的初始猜测值b1、c1、b2、c2、b3、c3、y0。
修复后可正常运行的代码
import numpy as np import matplotlib.pyplot as plt import math from scipy.optimize import least_squares def Intensity(x_data, A21, T21, A22, T22, A23, T23, y0): I_model=A21*np.exp(-x_data/T21)+A22*np.exp(-x_data/T22)+A23*np.exp(-x_data/T23)+y0 return I_model # 生成示例数据集(可替换为读取csv数据的逻辑) def gen_data(t, b1, c1, b2, c2, b3, c3, y0, noise=0, n_outliers=0, random_state=0): y = b1 * np.exp(-t / c1) + b2 * np.exp(-t / c2) + b3 * np.exp(-t / c3)+y0 rnd = np.random.RandomState(random_state) error = noise * rnd.randn(t.size) outliers = rnd.randint(0, t.size, n_outliers) error[outliers] *= 10 return y + error # 初始猜测参数 y0 = 0.5 b1 = 0.25 c1 = .01 b2 = 0.4 c2 = .3 b3 = 0.35 c3 = 10 t_min = -3 t_max = 2 n_points = 1000 x_data = np.logspace(t_min, t_max, n_points) y_data = gen_data(x_data, b1, c1, b2, c2, b3, c3, y0, noise=0.1, n_outliers=3) # 修复后的最小化函数:拆分参数x,使用传入的t、y变量 def fun(x, t, y): A21, T21, A22, T22, A23, T23, y0 = x return Intensity(t, A21, T21, A22, T22, A23, T23, y0) - y # 修复初始参数数组:使用提前定义的初始猜测值 x0 = np.array([b1, c1, b2, c2, b3, c3, y0]) # 可选优化:增加参数边界限制,所有参数都为正数,避免拟合出现无意义的负值 bounds = ( [0, 1e-4, 0, 1e-4, 0, 1e-4, 0], [1, 1e2, 1, 1e2, 1, 1e2, 1] ) res_lsq = least_squares(fun, x0, args=(x_data, y_data), bounds=bounds) y_lsq = Intensity(x_data, *res_lsq.x) # 可打印拟合结果验证 print("拟合得到的参数:", res_lsq.x)
额外注意事项
多指数衰减拟合本身存在参数可辨识性差的问题,如果你使用自己的实验数据拟合出现结果偏离预期的情况,可以尝试:
- 调整初始猜测值,尽量和实际物理意义匹配
- 收紧参数的上下边界范围
- 如果数据噪声较大,可以换用鲁棒性更强的损失函数,比如在
least_squares中设置loss='huber'
内容的提问来源于stack exchange,提问作者Florian Nettesheim
相关产品推荐
相关产品推荐

