Я хотел бы попробовать разные стратегии для подгонки моих данных к данной модели, с границами и предоставлением аналитического якобиана для улучшения результатов. Я могу запустить optimize.least_squares
, например:
sol = optimize.least_squares(cost_function, x0=x0, args=(data, sys_path, configfile), loss='soft_l1', f_scale=0.1, max_nfev=500, jac=grad_V , bounds = param_bounds)
, но я обнаружил несколько ошибок при попытке оптимизации.минимизировать с помощью любого из доступных методов с использованием тех же параметров и данных (см. Ниже):
sol = optimize.minimize(cost_function, x0=x0, args=(data, sys_path, configfile), method='L-BFGS-B', jac=grad_V, bounds = param_bounds)
[..] line 594, in fitting_model
sol = optimize.minimize(cost_function_vector, x0=x0, args=(data, sys_path, configfile), method='L-BFGS-B', jac=grad_V, bounds = param_bounds)
File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/optimize/_minimize.py", line 600, in minimize
callback=callback, **options)
File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/optimize/lbfgsb.py", line 267, in _minimize_lbfgsb
raise ValueError('length of x0 != length of bounds')
ValueError: length of x0 != length of bounds
- Если я сделаю, например,
np.transpose(param_bounds)
:
sol = optimize.minimize(cost_function, x0=x0, args=(data, sys_path, configfile), method='L-BFGS-B', jac=grad_V, bounds = np.transpose(param_bounds))
[...], line 594, in fitting_model
sol = optimize.minimize(cost_function_vector, x0=x0, args=(data, sys_path, configfile), method='L-BFGS-B', jac=grad_V, bounds = np.transpose(param_bounds))
File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/optimize/_minimize.py", line 600, in minimize
callback=callback, **options)
File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/optimize/lbfgsb.py", line 328, in _minimize_lbfgsb
isave, dsave, maxls)
ValueError: too many axes: 2 (effrank=2), expected rank=1
Опять же, это работает с наименьшим_ квадратами, поэтому я думаю, проблема в том, как я передаю аргументы (почему они отличаются от наименьшего_ квадрата ??), а не в коде. Однако, следуя документации и найденным примерам, я не могу понять, где находится ошибка.
Буду очень признателен за любую помощь в этом. Заранее спасибо.
Я собирался поместить код, примеры данных и так далее, но, чтобы не делать это слишком длинным, я думаю, что этого достаточно со следующей информацией. Дайте мне знать, если я ошибаюсь и что-то еще нужно.
Есть 5 параметров: S0, d, theta, phi, f
. Эти и другие необходимые параметры (например, массивы bvals
и bvecs
) считываются из configfile
, а другие необходимые функции из sys_path
(передаются в args
).
cost_function
возвращает вектор F
(data, Sj
и, следовательно, F
являются массивами формы (65,)). По сути, это что-то вроде:
def cost_function(data, sys_path, configfile):
[...]
v = get_v(theta,phi)
Sj = s0 * ((1 - f) * np.exp(-bvals * d) + f * np.exp(-bvals * d * np.transpose(np.square((np.transpose(bvecs) * v)))) ) ##vector v depends on theta and phi
F = Sj - data
return F
x0
(инициализация для 5 параметров), представленных в массиве shape (5,). Например: array([ 1.46732834e+02, 1.00000000e-03, 6.81814424e-01, -2.07406186e-01, 1.27062049e+01])
Нижняя и верхняя границы представлены как param_bounds с формой (2,5). Например,
array([[ 0.0e+00, 1.0e-06, -1.0e+04, -1.0e+04, 0.001],
[ 1.0e+05, 1.0e-02, 1.0e+04, 1.0e+04, 1]])
grad_V
- это определенная пользователем функция Якобиана, которая возвращает массив формы (65,5) и, как cost_function
, принимает args=(data, sys_path, configfile)
в качестве входных аргументов.