#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. Почему плохо подключать координаты к целевой функции? Это дешево по сравнению с тем, что делает оптимизатор в любом случае.