Сколько раз scipy.optimize.differential_evolution оценивает функцию, которую нужно свернуть? - PullRequest
2 голосов
/ 16 мая 2019

Я пытаюсь применить этот ответ к моему коду для отображения индикатора выполнения для scipy.optimize.differential_evolution метода.

Я думал, что differential_evolution будет оценивать func (функция, которая вызывается для минимизации) popsize * maxiter раз, но, очевидно, это не так.

Приведенный ниже код должен отображать индикатор выполнения, который увеличивается до 100%:

[####################] 100% 

, но в действительности это продолжается, поскольку функция DEdist() оценивается намного чаще, чем popsize * maxiter (которую я использую в качестве аргумента total функции updt()).

Как рассчитать общее количество оценок функций, выполненных differential_evolution?Можно ли это сделать вообще?


from scipy.optimize import differential_evolution as DE
import sys


popsize, maxiter = 10, 50


def updt(total, progress, extra=""):
    """
    Displays or updates a console progress bar.

    Original source: https://stackoverflow.com/a/15860757/1391441
    """
    barLength, status = 20, ""
    progress = float(progress) / float(total)
    if progress >= 1.:
        progress, status = 1, "\r\n"
    block = int(round(barLength * progress))
    text = "\r[{}] {:.0f}% {}{}".format(
        "#" * block + "-" * (barLength - block),
        round(progress * 100, 0), extra, status)
    sys.stdout.write(text)
    sys.stdout.flush()


def DEdist(model, info):
    updt(popsize * maxiter, info['Nfeval'] + 1)
    info['Nfeval'] += 1

    res = (1. - model[0])**2 + 100.0 * (model[1] - model[0]**2)**2 + \
        (1. - model[1])**2 + 100.0 * (model[2] - model[1]**2)**2

    return res


bounds = [[0., 10.], [0., 10.], [0., 10.], [0., 10.]]
result = DE(
    DEdist, bounds, popsize=popsize, maxiter=maxiter,
    args=({'Nfeval': 0},))

1 Ответ

1 голос
/ 16 мая 2019

С help(scipy.optimize.differential_evolution):

maxiter : int, optional
    The maximum number of generations over which the entire population is
    evolved. The maximum number of function evaluations (with no polishing)
    is: ``(maxiter + 1) * popsize * len(x)``

Также polish=True по умолчанию:

polish : bool, optional
    If True (default), then `scipy.optimize.minimize` with the `L-BFGS-B`
    method is used to polish the best population member at the end, which
    can improve the minimization slightly.

Так что вам нужно изменить две вещи:

1 Используйте правильноFolmula здесь:

updt(popsize * (maxiter + 1) * len(model), info['Nfeval'] + 1)

2 Pass polish=False аргумент:

result = DE(
    DEdist, bounds, popsize=popsize, maxiter=maxiter, polish=False,
    args=({'Nfeval': 0},))

После этого вы увидите, что индикатор выполнения останавливается точно тогда, когда он достигает 100%.

...