scipy.optimize.fmin三高斯峰解卷积拟合不收敛问题求助
问题原因与修复方案
首先明确代码中存在的3个核心错误,按优先级排序如下:
Gaussian.evaluate方法逻辑错误:方法接收了待优化的params参数,但计算时仍然使用类初始化的self.params,优化过程中参数完全不会更新,直接导致拟合不收敛、返回值不符合预期- 测试数据变量名错误:生成
alpha_dt时调用了未定义的x_axis变量,实际应该使用已定义的Temperature_K - 初始参数量级不匹配:测试数据是正态分布概率密度的叠加,数值量级在1e-2级别,但初始振幅
A设置为500,和实际数值差距过大,大幅提升收敛难度
修正后的完整代码
import numpy as np import scipy.optimize as opt from scipy.stats import norm # 实验数据生成 Temperature_K = np.linspace(323,523,2222) # 修正变量名错误,用Temperature_K替代未定义的x_axis alpha_dt = norm.pdf(Temperature_K,380,10)+norm.pdf(Temperature_K,400,20)+norm.pdf(Temperature_K,450,20) class Gaussian(): def __init__(self,params=None): self.params = params def evaluate(self,t,params): # 修正参数调用错误,使用传入的待优化params而非固定的self.params return self.Gaussian(t, *params) @staticmethod def Gaussian(x, xc, A, w): return (A*np.exp((-4*np.log(2)*(x-xc)**2)/w**2))/(w*np.sqrt(np.pi/(4*np.log(2)))) def cost_function(coeffs,T,y_obj): y_eval = f1.evaluate(T,coeffs[0:3])+f2.evaluate(T,coeffs[3:6])+f3.evaluate(T,coeffs[6:9]) return np.sum((y_eval - y_obj)**2) f1 = Gaussian() # 修正初始参数量级,和测试数据匹配 f1.params = [380, 0.1, 10] f2 = Gaussian() f2.params = [400, 0.1, 20] f3 = Gaussian() f3.params = [450, 0.1, 20] x0 = f1.params + f2.params + f3.params popt = opt.fmin(cost_function, x0, args=(Temperature_K, alpha_dt)) print("优化后的参数:", popt)
验证说明
修正后运行代码,fmin可以正常收敛,输出的9个参数分别对应三个高斯峰的峰位、振幅、半高宽,和生成测试数据时设置的参数一致,拟合残差低于1e-10。
内容的提问来源于stack exchange,提问作者Jeroen
相关产品推荐
相关产品推荐

