Включайте производные в основанный на проблеме рабочий процесс

Почему включают производные?

Пример показывает, как включать производную информацию в нелинейную основанную на проблеме оптимизацию. Включая градиенты или Гессиан в оптимизации может принести следующую пользу:

  • Больше устойчивых результатов. Конечные шаги дифференцирования иногда достигают точек, где цель или нелинейная ограничительная функция являются неопределенными, не конечными, или комплексными.

  • Аналитические градиенты могут быть более точными, чем оценки конечной разности.

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

  • Аналитические градиенты могут быть быстрее, чтобы вычислить, чем оценки конечной разности, специально для проблем с разреженной структурой. Для сложных выражений, однако, аналитические градиенты могут быть медленнее, чтобы вычислить.

Несмотря на эти преимущества, подход, основанный на проблеме в настоящее время не использует производную информацию. Чтобы использовать производные в основанной на проблеме оптимизации, преобразуйте свою проблему с помощью prob2struct, и отредактируйте получившуюся цель и ограничительные функции.

Создайте задачу оптимизации

Создайте основанную на проблеме нелинейную оптимизацию. С 2D контрольными переменными x и y, используйте целевую функцию

fun1 =100(x2x12)2+(1x1)2fun2 =exp((xiyi)2)exp(exp(y1))sech(y2)цель = fun1 + fun2 .

Включайте ограничение что сумма квадратов x и y не больше, чем 4.

fun2 не основан на поддерживаемых функциях для выражений оптимизации; смотрите Поддерживаемые Операции на Переменных и выражениях Оптимизации. Поэтому включать fun2 в задаче оптимизации необходимо преобразовать его в выражение оптимизации с помощью fcn2optimexpr.

prob = optimproblem;
x = optimvar('x',2);
y = optimvar('y',2);
fun1 = 100*(x(2) - x(1)^2)^2 + (1 - x(1))^2;
fun2 = @(x,y)-exp(-sum((x - y).^2))*exp(-exp(-y(1)))*sech(y(2));
prob.Objective = fun1 + fcn2optimexpr(fun2,x,y);
prob.Constraints.cons = sum(x.^2 + y.^2) <= 4;

Преобразуйте проблему в основанную на решателе форму

Чтобы включать производные, преобразуйте проблему в структуру с помощью prob2struct.

problem = prob2struct(prob);

Во время преобразования, prob2struct создает файлы функции, которые представляют объективные и нелинейные ограничительные функции. По умолчанию эти функции имеют имена 'generatedObjective.m' и 'generatedConstraints.m'.

Вычислите производные и отслеживайте переменные

Вычислите производные, сопоставленные с объективными и нелинейными ограничительными функциями. Если у вас есть лицензия Symbolic Math Toolbox™, можно использовать gradient или jacobian функционируйте, чтобы помочь вычислить производные. Смотрите, что Symbolic Math Toolbox™ Вычисляет Градиенты и Гессианы.

Основанный на решателе подход имеет одну контрольную переменную. Каждая переменная оптимизации (x или y, в этом примере), фрагмент контрольной переменной.

Можно найти отображение между переменными оптимизации и одной контрольной переменной в сгенерированном файле целевой функции, 'generatedObjective.m'. Начало файла содержит эти строки кода:

%% Variable indices.
idx_x = [1 2];
idx_y = [3 4];

%% Map solver-based variables to problem-based.
x = inputVariables(idx_x);
x = x(:);
y = inputVariables(idx_y);
y = y(:);

В этом коде контрольная переменная имеет имя inputVariables.

В качестве альтернативы можно найти отображение при помощи varindex.

idx = varindex(prob);
disp(idx.x)
     1     2
disp(idx.y)
     3     4

Если вы знаете отображение, можно использовать стандартное исчисление, чтобы найти следующие выражения для градиента grad из целевой функции objective = fun1 + fun2 относительно контрольной переменной [x(:);y(:)].

grad=[2x1400x1(x2x12)+σ12200x2200x12+σ2σ1dexp(y1)σ2+dtanh(y2)],

где

c=exp((x1y1)2(x2y2)2)d=cexp(exp(y1))sech(y2)σ1=2(x1y1)dσ2=2(x2y2)d.

Отредактируйте файлы цели и ограничения

Чтобы включать расчетные градиенты в файл целевой функции, отредактируйте 'generatedObjective.m' можно следующим образом.

%% Insert gradient calculation here.
% If you include a gradient, notify the solver by setting the
% SpecifyObjectiveGradient option to true.
if nargout > 1
    c = exp(-sum((x - y).^2));
    d = c*exp(-exp(-y(1)))*sech(y(2));
    sigma1 = 2*(x(1) - y(1))*d;
    sigma2 = 2*(x(2) - y(2))*d;
    grad = zeros(4,1);
    grad(1) = 2*x(1) - 400*x(1)*(x(2) - x(1)^2) + sigma1 - 2;
    grad(2) = 200*x(2) - 200*x(1)^2 + sigma2;
    grad(3) = -sigma1 - d*exp(-y(1));
    grad(4) = -sigma2 + d*tanh(y(2));
end

Вспомните, что нелинейным ограничением является x(1)^2 + x(2)^2 + y(1)^2 + y(2)^2 <= 4. Безусловно, градиентом этой ограничительной функции является 2*[x;y]. Чтобы включать расчетные градиенты нелинейного ограничения, отредактируйте 'generatedConstraints.m' можно следующим образом.

%% Insert gradient calculation here.
% If you include a gradient, notify the solver by setting the
% SpecifyConstraintGradient option to true.
if nargout > 2
    cineqGrad = 2*[x;y];
    ceqGrad = [];
end

Запустите проблему Используя два метода

Запустите проблему с помощью и основанных на проблеме и основанных на решателе методов, чтобы видеть различия. Чтобы запустить проблему с помощью производной информации, создайте подходящие варианты в структуре задачи.

options = optimoptions('fmincon','SpecifyObjectiveGradient',true,...
    'SpecifyConstraintGradient',true);
problem.options = options;

Нелинейные проблемы требуют непустого x0 поле в структуре задачи.

x0 = [-1;2;1;-1];
problem.x0 = x0;

Вызовите fmincon на структуре задачи.

[xsolver,fvalsolver,exitflagsolver,outputsolver] = fmincon(problem)
Local minimum found that satisfies the constraints.

Optimization completed because the objective function is non-decreasing in 
feasible directions, to within the value of the optimality tolerance,
and constraints are satisfied to within the value of the constraint tolerance.

<stopping criteria details>

xsolver =

    0.8671
    0.7505
    1.0433
    0.5140


fvalsolver =

   -0.5500


exitflagsolver =

     1


outputsolver = 

  struct with fields:

         iterations: 46
          funcCount: 77
    constrviolation: 0
           stepsize: 7.4091e-06
          algorithm: 'interior-point'
      firstorderopt: 7.5203e-07
       cgiterations: 9
            message: '↵Local minimum found that satisfies the constraints.↵↵Optimization completed because the objective function is non-decreasing in ↵feasible directions, to within the value of the optimality tolerance,↵and constraints are satisfied to within the value of the constraint tolerance.↵↵<stopping criteria details>↵↵Optimization completed: The relative first-order optimality measure, 7.520304e-07,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.↵↵'

Сравните это решение с тем, полученным из solve, который не использует производной информации.

init.x = x0(1:2);
init.y = x0(3:4);
[xproblem,fvalproblem,exitflagproblem,outputproblem] = solve(prob,init)
Local minimum found that satisfies the constraints.

Optimization completed because the objective function is non-decreasing in 
feasible directions, to within the value of the optimality tolerance,
and constraints are satisfied to within the value of the constraint tolerance.

<stopping criteria details>

xproblem = 

  struct with fields:

    x: [2×1 double]
    y: [2×1 double]


fvalproblem =

   -0.5500


exitflagproblem = 

    OptimalSolution


outputproblem = 

  struct with fields:

         iterations: 48
          funcCount: 276
    constrviolation: 0
           stepsize: 7.9340e-07
          algorithm: 'interior-point'
      firstorderopt: 6.5496e-07
       cgiterations: 9
            message: '↵Local minimum found that satisfies the constraints.↵↵Optimization completed because the objective function is non-decreasing in ↵feasible directions, to within the value of the optimality tolerance,↵and constraints are satisfied to within the value of the constraint tolerance.↵↵<stopping criteria details>↵↵Optimization completed: The relative first-order optimality measure, 6.549635e-07,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.↵↵'
             solver: 'fmincon'

Оба решения сообщают о том же значении функции точности отображения, и оба требуют примерно того же количества итераций (46 информации о градиенте использования, 48 без). Однако решение с помощью градиентов требует только 77 вычислений функции, по сравнению с 276 для решения без градиентов.

Смотрите также

| |

Похожие темы