Как отобразить ход оптимизации?

#python #matplotlib #scipy #scipy-optimize

#python #matplotlib #scipy #scipy-оптимизировать

Вопрос:

Есть ли способ отобразить прогрессивное значение оптимизируемой функции с помощью дифференциальной эволюции scipy.optimize? В следующей части построение графика не работает:

 from scipy.optimize import rosen, differential_evolution
bounds = [(0, 5), (0, 5), (0, 5), (0, 5), (0, 5)]
result = differential_evolution(rosen, bounds, disp=False)
print(result.x, result.fun)
import matplotlib.pyplot as plt
x, f = zip(*result)
plt.plot(x, f)
  

Ответ №1:

Примечание: изначально я ответил на этот вопрос, думая, что вы хотите указать путь, пройденный оптимизатором, а не значение во время оптимизации. Я обновил ответ, чтобы он показывал оба, но вас, вероятно, интересует только второй график.

Объект, возвращаемый differential_evolution не содержит путь к результату, ни значения на этом пути. Однако вы можете использовать callback аргумент для предоставления функции обратного вызова, которая вызывается на каждой итерации. Затем этот обратный вызов может записывать прогресс.

Например:

 progress = []
progress_err = []

def cb(x, convergence):
    progress.append(x)
    progress_val.append(rosen(x))

bounds = [(0, 5), (0, 5), (0, 5), (0, 5), (0, 5)]
result = differential_evolution(rosen, bounds, disp=False, callback=cb)

progress = np.array(progress)
progress_val = np.array(progress_val)
  

Поскольку вы, похоже, хотите оптимизировать функцию Розенброка 5D, визуализация всего пути становится немного сложной. Если я решу визуализировать только первые две координаты ( значение, о котором вы на самом деле спрашиваете), т.е.

 fig = plt.figure()
ax = fig.add_subplot(2,1,1)
ax.plot(progress[:, 0], progress[:, 1])
ax = fig.add_subplot(2,1,2)
ax.plot(progress_val)
plt.show()
  

Я получаю

Путь и значение во время оптимизации

Значение, о котором, как я только что понял, вы на самом деле спрашиваете, — это нижний график. Если вам не нужен сам путь, игнорируйте все, что связано с кодом progress .

Конечно, ваш результат может выглядеть по-другому, потому что наши случайные начальные значения и, следовательно, наши пути к оптимуму различны.

Комментарии:

1. Это очень полезно — ценится. Однако я имел в виду значение целевой функции (в данном случае Розенброка), а не координаты. Теперь x в обратном вызове находится массив координат, и я не вижу никакого способа извлечь значение func из differential_evolution . Означает ли это, что единственным решением является включение извлеченных координат в целевую функцию?

2. Извините, я по ошибке назвал значения функции «ошибкой». В случае функции Розенброка это оказывается правдой, но это просто совпадение. Я обновил ответ.

3. Почему плохо подключать координаты к целевой функции? Это дешево по сравнению с тем, что делает оптимизатор в любом случае.