exponenta event banner

Минимизация функции банана

В этом примере показано, как минимизировать «функцию банана» Розенброка:

f (x) = 100 (x (2) -x (1) 2) 2 + (1-x (1)) 2.

f (x) называется банановой функцией из-за ее кривизны вокруг начала координат. Это печально известно в примерах оптимизации из-за медленной сходимости большинство методов проявляют при попытке решить эту проблему.

f (x) имеет уникальный минимум в точке x = [1,1], где f (x) = 0. В этом примере показан ряд способов минимизации f (x), начиная с точки x0 = [-1.9,2].

Оптимизация без производных

fminsearch функция находит минимум для проблемы без ограничений. Он использует алгоритм, который не оценивает какие-либо производные целевой функции. Скорее, он использует метод геометрического поиска, описанный в fminsearch Algorithm.

Минимизировать функцию банана с помощью fminsearch. Включите функцию вывода для отчета о последовательности итераций.

fun = @(x)(100*(x(2) - x(1)^2)^2 + (1 - x(1))^2);
options = optimset('OutputFcn',@bananaout,'Display','off');
x0 = [-1.9,2];
[x,fval,eflag,output] = fminsearch(fun,x0,options);
title 'Rosenbrock solution via fminsearch'

Figure contains an axes. The axes with title Rosenbrock solution via fminsearch contains 121 objects of type surface, contour, line, text. This object represents Iterative steps.

Fcount = output.funcCount;
disp(['Number of function evaluations for fminsearch was ',num2str(Fcount)])
Number of function evaluations for fminsearch was 210
disp(['Number of solver iterations for fminsearch was ',num2str(output.iterations)])
Number of solver iterations for fminsearch was 114

Оптимизация с помощью расчетных производных

fminunc функция находит минимум для проблемы без ограничений. Он использует алгоритм на основе производных. Алгоритм пытается оценить не только первую производную целевой функции, но и матрицу вторых производных. fminunc обычно эффективнее, чем fminsearch.

Минимизировать функцию банана с помощью fminunc.

options = optimoptions('fminunc','Display','off',...
    'OutputFcn',@bananaout,'Algorithm','quasi-newton');
[x,fval,eflag,output] = fminunc(fun,x0,options);
title 'Rosenbrock solution via fminunc'

Figure contains an axes. The axes with title Rosenbrock solution via fminunc contains 41 objects of type surface, contour, line, text. This object represents Iterative steps.

Fcount = output.funcCount;
disp(['Number of function evaluations for fminunc was ',num2str(Fcount)])
Number of function evaluations for fminunc was 150
disp(['Number of solver iterations for fminunc was ',num2str(output.iterations)])
Number of solver iterations for fminunc was 34

Оптимизация с самым крутым спуском

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

Можно запустить fminunc с самым крутым алгоритмом снижения путем установки скрытого HessUpdate параметр для значения 'steepdesc' для 'quasi-newton' алгоритм. Установите максимальное число оценок функций, превышающее значение по умолчанию, поскольку решатель не находит решение быстро. В этом случае решатель не находит решение даже после 600 оценок функций.

options = optimoptions(options,'HessUpdate','steepdesc',...
    'MaxFunctionEvaluations',600);
[x,fval,eflag,output] = fminunc(fun,x0,options);
title 'Rosenbrock solution via steepest descent'

Figure contains an axes. The axes with title Rosenbrock solution via steepest descent contains 51 objects of type surface, contour, line, text. This object represents Iterative steps.

Fcount = output.funcCount;
disp(['Number of function evaluations for steepest descent was ',...
    num2str(Fcount)])
Number of function evaluations for steepest descent was 600
disp(['Number of solver iterations for steepest descent was ',...
    num2str(output.iterations)])
Number of solver iterations for steepest descent was 45

Оптимизация с помощью аналитического градиента

Если вы предоставляете градиент, fminunc решает оптимизацию, используя меньшее количество оценок функций. При предоставлении градиента можно использовать 'trust-region' алгоритм, который часто быстрее и использует меньше памяти, чем 'quasi-newton' алгоритм. Сбросить HessUpdate и MaxFunctionEvaluations значения по умолчанию.

grad = @(x)[-400*(x(2) - x(1)^2)*x(1) - 2*(1 - x(1));
            200*(x(2) - x(1)^2)];
fungrad = @(x)deal(fun(x),grad(x));
options = resetoptions(options,{'HessUpdate','MaxFunctionEvaluations'});
options = optimoptions(options,'SpecifyObjectiveGradient',true,...
    'Algorithm','trust-region');
[x,fval,eflag,output] = fminunc(fungrad,x0,options);
title 'Rosenbrock solution via fminunc with gradient'

Figure contains an axes. The axes with title Rosenbrock solution via fminunc with gradient contains 38 objects of type surface, contour, line, text. This object represents Iterative steps.

Fcount = output.funcCount;
disp(['Number of function evaluations for fminunc with gradient was ',...
    num2str(Fcount)])
Number of function evaluations for fminunc with gradient was 32
disp(['Number of solver iterations for fminunc with gradient was ',...
    num2str(output.iterations)])
Number of solver iterations for fminunc with gradient was 31

Оптимизация с помощью аналитического Гессена

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

hess = @(x)[1200*x(1)^2 - 400*x(2) + 2, -400*x(1);
            -400*x(1), 200];
fungradhess = @(x)deal(fun(x),grad(x),hess(x));
options.HessianFcn = 'objective';
[x,fval,eflag,output] = fminunc(fungradhess,x0,options);
title 'Rosenbrock solution via fminunc with Hessian'

Figure contains an axes. The axes with title Rosenbrock solution via fminunc with Hessian contains 38 objects of type surface, contour, line, text. This object represents Iterative steps.

Fcount = output.funcCount;
disp(['Number of function evaluations for fminunc with gradient and Hessian was ',...
    num2str(Fcount)])
Number of function evaluations for fminunc with gradient and Hessian was 32
disp(['Number of solver iterations for fminunc with gradient and Hessian was ',num2str(output.iterations)])
Number of solver iterations for fminunc with gradient and Hessian was 31

Оптимизация с помощью вычислителя наименьших квадратов

Рекомендуемый решатель для нелинейной суммы квадратов: lsqnonlin. Этот решатель еще более эффективен, чем fminunc без градиента для этого особого класса проблем. Использовать lsqnonlin, не пишите свою цель как сумму квадратов. Вместо этого запишите базовый вектор, который lsqnonlin внутренние квадраты и суммы.

options = optimoptions('lsqnonlin','Display','off','OutputFcn',@bananaout);
vfun = @(x)[10*(x(2) - x(1)^2),1 - x(1)];
[x,resnorm,residual,eflag,output] = lsqnonlin(vfun,x0,[],[],options);
title 'Rosenbrock solution via lsqnonlin'

Figure contains an axes. The axes with title Rosenbrock solution via lsqnonlin contains 35 objects of type surface, contour, line, text. This object represents Iterative steps.

Fcount = output.funcCount;
disp(['Number of function evaluations for lsqnonlin was ',...
    num2str(Fcount)])
Number of function evaluations for lsqnonlin was 87
disp(['Number of solver iterations for lsqnonlin was ',num2str(output.iterations)])
Number of solver iterations for lsqnonlin was 28

Оптимизация с помощью решателя наименьших квадратов и Jacobian

Как в минимизации с использованием градиента для fminunc, lsqnonlin может использовать производную информацию для уменьшения числа оценок функций. Укажите якобиан вектора нелинейной целевой функции и повторите оптимизацию.

jac = @(x)[-20*x(1),10;
           -1,0];
vfunjac = @(x)deal(vfun(x),jac(x));
options.SpecifyObjectiveGradient = true;
[x,resnorm,residual,eflag,output] = lsqnonlin(vfunjac,x0,[],[],options);
title 'Rosenbrock solution via lsqnonlin with Jacobian'

Figure contains an axes. The axes with title Rosenbrock solution via lsqnonlin with Jacobian contains 35 objects of type surface, contour, line, text. This object represents Iterative steps.

Fcount = output.funcCount;
disp(['Number of function evaluations for lsqnonlin with Jacobian was ',...
    num2str(Fcount)])
Number of function evaluations for lsqnonlin with Jacobian was 29
disp(['Number of solver iterations for lsqnonlin with Jacobian was ',...
    num2str(output.iterations)])
Number of solver iterations for lsqnonlin with Jacobian was 28

Авторское право 2006 - 2020 The MathWorks, Inc.

Связанные темы