我已经实现了 3D 高斯拟合scipy.optimize.leastsq
,现在我想调整参数ftol
并xtol
优化性能。但是,我不了解这两个参数的“单位”以便做出正确的选择。是否可以从结果中计算出这两个参数?这将使我了解如何选择它们。我的数据是 numpy 数组np.uint8
。我试图阅读 MINIPACK 的 FORTRAN 源代码,但我的 FORTRAN 知识为零。我还阅读了检查 Levenberg-Marquardt 算法,但我无法真正得到一个低于ftol
示例的数字。
这是我所做的一个最小示例:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import leastsq
class gaussian_model:
def __init__(self):
self.prev_iter_model = None
self.f_vals = []
def gaussian_1D(self, coeffs, xx):
A, sigma, mu = coeffs
# Center rotation around peak center
x0 = xx - mu
model = A*np.exp(-(x0**2)/(2*(sigma**2)))
return model
def residuals(self, coeffs, I_obs, xx, model_func):
model = model_func(coeffs, xx)
residuals = I_obs - model
if self.prev_iter_model is not None:
self.f = np.sum(((model-self.prev_iter_model)/model)**2)
self.f_vals.append(self.f)
self.prev_iter_model = model
return residuals
# x data
x_start = 1
x_stop = 10
num = 100
xx, dx = np.linspace(x_start, x_stop, num, retstep=True)
# Simulated data with some noise
A, s_x, mu = 10, 0.5, 3
coeffs = [A, s_x, mu]
model = gaussian_model()
yy = model.gaussian_1D(coeffs, xx)
noise_ampl = 0.5
noise = np.random.normal(0, noise_ampl, size=num)
yy += noise
# LM Least squares
initial_guess = [1, 1, 1]
pred_coeffs, cov_x, info, mesg, ier = leastsq(model.residuals, initial_guess,
args=(yy, xx, model.gaussian_1D),
ftol=1E-6, full_output=True)
yy_fit = model.gaussian_1D(pred_coeffs, xx)
rel_SSD = np.sum(((yy-yy_fit)/yy)**2)
RMS_SSD = np.sqrt(rel_SSD/num)
print(RMS_SSD)
print(model.f)
print(model.f_vals)
fig, ax = plt.subplots(1,2)
# Plot results
ax[0].scatter(xx, yy)
ax[0].plot(xx, yy_fit, c='r')
ax[1].scatter(range(len(model.f_vals)), model.f_vals, c='r')
# ax[1].set_ylim(0, 1E-6)
plt.show()
rel_SSD
大约是 1,绝对不是低于 1 的东西ftol = 1E-6
。
编辑:基于下面的@user12750353 答案,我更新了我的最小示例,以尝试重新创建lmdif如何确定终止与ftol
. 问题是 myf_vals
太小,所以它们不是正确的值。我想重新创建它的原因是我想看看我在我的主代码上得到什么样的数字来决定ftol
更早终止拟合过程的数字。