Scipy 优化最小化不可靠
Scipy optimize minimize not reliable
我的程序:
# -*- coding: utf-8 -*-
import numpy as np
import itertools
from scipy.optimize import minimize
global width
width = 0.3
def time_builder(f, t0=0, tf=300):
return list(np.round(np.arange(t0, tf, 1/f*1000),3))
def duo_stim_overlap(t1, t2):
"""
Function taking 2 timelines build by time_builder function in input
and returning the ids of overlapping pulses between the 2.
len(t1) < len(t2)
"""
pulse_id_t1 = [x for x in range(len(t1)) for y in range(len(t2)) if abs(t1[x] - t2[y]) < width]
pulse_id_t2 = [x for x in range(len(t2)) for y in range(len(t1)) if abs(t2[x] - t1[y]) < width]
return pulse_id_t1, pulse_id_t2
def optimal_delay(s):
frequences = [20, 60, 80, 250, 500]
t0 = 0
tf = 150
delay = 0 # delay between signals,
timelines = list()
overlap = dict()
for i in range(len(frequences)):
timelines.append(time_builder(frequences[i], t0+delay, tf))
overlap[i] = list()
delay += s
for subset in itertools.combinations(timelines, 2):
p1_stim, p2_stim = duo_stim_overlap(subset[0], subset[1])
overlap[timelines.index(subset[0])] += p1_stim
overlap[timelines.index(subset[1])] += p2_stim
optim_param = 0
for key, items in overlap.items():
optim_param += (len(list(set(items)))/len(timelines[key]))
return optim_param
res = minimize(optimal_delay, 1.5, method='Nelder-Mead', tol = 0.01, bounds = [(0, 5)], options={'disp': True})
所以我的目标是最小化函数 optimal_delay 计算的值 optim_param
。
首先,梯度方法什么都不做。他们在第一次迭代时停止。
其次,我需要为最佳延迟的 s 值设置界限(例如在 0 到 5 之间)。我知道使用 Nelder-Mead 单纯形法是不可能的,但其他方法根本不起作用。
第三,我真的不知道如何设置终止参数tol。机器人 tol = 0.01
和 tol = 0.0000001
没有给我好的结果。 (和非常接近的)。
最后,如果我从 1.8 开始,最小化函数给我的值远非最小值...
我做错了什么?
如果绘制 optimal_delay 函数,您会发现它远非凸函数。搜索只会找到靠近起点的任何局部最小值。
我的程序:
# -*- coding: utf-8 -*-
import numpy as np
import itertools
from scipy.optimize import minimize
global width
width = 0.3
def time_builder(f, t0=0, tf=300):
return list(np.round(np.arange(t0, tf, 1/f*1000),3))
def duo_stim_overlap(t1, t2):
"""
Function taking 2 timelines build by time_builder function in input
and returning the ids of overlapping pulses between the 2.
len(t1) < len(t2)
"""
pulse_id_t1 = [x for x in range(len(t1)) for y in range(len(t2)) if abs(t1[x] - t2[y]) < width]
pulse_id_t2 = [x for x in range(len(t2)) for y in range(len(t1)) if abs(t2[x] - t1[y]) < width]
return pulse_id_t1, pulse_id_t2
def optimal_delay(s):
frequences = [20, 60, 80, 250, 500]
t0 = 0
tf = 150
delay = 0 # delay between signals,
timelines = list()
overlap = dict()
for i in range(len(frequences)):
timelines.append(time_builder(frequences[i], t0+delay, tf))
overlap[i] = list()
delay += s
for subset in itertools.combinations(timelines, 2):
p1_stim, p2_stim = duo_stim_overlap(subset[0], subset[1])
overlap[timelines.index(subset[0])] += p1_stim
overlap[timelines.index(subset[1])] += p2_stim
optim_param = 0
for key, items in overlap.items():
optim_param += (len(list(set(items)))/len(timelines[key]))
return optim_param
res = minimize(optimal_delay, 1.5, method='Nelder-Mead', tol = 0.01, bounds = [(0, 5)], options={'disp': True})
所以我的目标是最小化函数 optimal_delay 计算的值 optim_param
。
首先,梯度方法什么都不做。他们在第一次迭代时停止。
其次,我需要为最佳延迟的 s 值设置界限(例如在 0 到 5 之间)。我知道使用 Nelder-Mead 单纯形法是不可能的,但其他方法根本不起作用。
第三,我真的不知道如何设置终止参数tol。机器人 tol = 0.01
和 tol = 0.0000001
没有给我好的结果。 (和非常接近的)。
最后,如果我从 1.8 开始,最小化函数给我的值远非最小值...
我做错了什么?
如果绘制 optimal_delay 函数,您会发现它远非凸函数。搜索只会找到靠近起点的任何局部最小值。