CVXPY: как эффективно решить серию похожих проблем

У меня есть большая проблема, определенная на языке моделирования CVXPY. Я хочу решить серию этих задач - все тот же формат, но с другими параметрами (константами).

Я выяснил, что после вызова problem.solve() генерация внутренней проблемы занимает 20 с, а время выполнения основной оптимизации - 0,2 с. Много времени, когда я хочу решить десятки подобных задач.

Есть ли какой-либо инструмент для CVXPY, такой как оптимизатор YALMIP или какая-либо возможность сократить время создания проблем?


person dave-cz    schedule 30.05.2017    source источник


Ответы (1)


Да, есть. И это даже объясняется в официальных документах.

Параметры

Параметры - это символические представления констант. Назначение параметров - изменить значение константы в задаче без восстановления всей проблемы.

Пример прямо из документации (изменен):

from cvxpy import *
import numpy

# Problem data.
n = 15
m = 10
numpy.random.seed(1)
A = numpy.random.randn(n, m)
b = numpy.random.randn(n, 1)
# gamma must be positive due to DCP rules.
gamma = Parameter(sign="positive")                       # !!!

# Construct the problem.
x = Variable(m)
error = sum_squares(A*x - b)
obj = Minimize(error + gamma*norm(x, 1))
prob = Problem(obj)                                      # !!!

# Construct a trade-off curve of ||Ax-b||^2 vs. ||x||_1
sq_penalty = []
l1_penalty = []
x_values = []
gamma_vals = numpy.logspace(-4, 6)
for val in gamma_vals:
    gamma.value = val                                    # !!!
    prob.solve()                                         # !!!
    # Use expr.value to get the numerical value of
    # an expression in the problem.
    sq_penalty.append(error.value)
    l1_penalty.append(norm(x, 1).value)
    x_values.append(x.value)

Так что он делает

Как вы заметили, настройка вашей задачи оптимизации может занять некоторое время, потому что она соответствует подходу DCP (который доказывает выпуклость по конструкции).

При использовании parameter эта DCP-обработка выполняется только один раз! Каждое новое решение меняет только некоторые мелкие детали в проблеме. Важно описать ваш параметр как можно точнее, чтобы DCP мог работать. Пример: Parameter(sign="positive").

Есть еще что-то, что ты можешь сделать?

Может быть. В зависимости от решателя вы также можете использовать теплый запуск, если считаете, что специальное предположение (например, вектор решения вашей последней итерации) является хорошим началом для новой проблемы.

Это заменит: prob.solve() на prob.solve(warm_start=True), что приведет к повторному использованию предыдущего решения в качестве начала (объяснено здесь). Невозможно вручную определить этот вектор (из cvxpy).

К сожалению, единственный решатель, поддерживающий это (в cvxpy), насколько я знаю, - это SCS (и другие проигнорируют его без сбоев)!

person sascha    schedule 30.05.2017
comment
Работает отлично, спасибо большое! Я не знал, как работает DCP-обработка. Я также пытаюсь сериализовать решенный prob с помощью pickle, но, к сожалению, это вызывает исключение. - person dave-cz; 01.06.2017
comment
Интересно. Думаю, я никогда не пробовал, но это читается так, как будто это должно быть возможно, хотя это довольно старый (и с тех пор произошло много внутренних изменений, например, отказ от cvxopt в качестве требования). - person sascha; 01.06.2017
comment
что привело к повторному использованию предыдущего решения в качестве начала (объяснено здесь). К сожалению ссылка мертва, у меня ошибка 404 ... - person Laryx Decidua; 19.08.2020
comment
OSQP также поддерживает теплый старт. - person steven; 22.10.2020