Main Content

바나나 함수 최소화

이 예제에서는 로젠브록의 "바나나 함수"를 최소화하는 방법을 보여줍니다.

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

f(x)는 원점 중심의 곡률 때문에 바나나 함수라고 부릅니다. 이 함수는 문제를 풀 때 대부분의 방법이 느린 수렴을 보이는 것으로 악명 높은 최적화 문제의 예입니다.

f(x)는 점 x=[1,1]에서 고유의 최솟값을 가지며, 여기서 f(x)=0입니다. 이 예제에서는 점 x0=[-1.9,2]에서 시작하여 f(x)를 최소화하는 여러 가지 방법을 보여줍니다.

도함수를 사용하지 않는 최적화

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 object. The axes object 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 함수는 제약 조건이 없는 문제의 최솟값을 구합니다. 이 함수는 도함수 기반 알고리즘을 사용합니다. 이 알고리즘은 목적 함수의 1계 도함수뿐 아니라 2계 도함수로 구성된 행렬도 추정하려고 시도합니다. 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 object. The axes object 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

최속강하법을 사용하는 최적화

최속강하법 알고리즘을 사용하여 바나나 함수를 최소화하려고 하면 문제의 높은 곡률로 인해 풀이 과정이 매우 느려집니다.

'quasi-newton' 알고리즘의 값 'steepdesc'에 숨겨진 HessUpdate 옵션을 설정하여 최속강하법 알고리즘으로 fminunc를 실행할 수 있습니다. 솔버가 해를 빠르게 찾지 못하므로 최대 함수 실행 횟수를 디폴트 값보다 크게 설정합니다. 이 경우, 솔버는 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 object. The axes object 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' 알고리즘보다 종종 속도가 더 빠르고 메모리 사용량이 적습니다. HessUpdateMaxFunctionEvaluations 옵션을 디폴트 값으로 재설정합니다.

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 object. The axes object 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

해석적 헤세 행렬을 사용하는 최적화

헤세 행렬(2계 도함수로 구성된 행렬)을 제공하는 경우 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 object. The axes object 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 object. The axes object 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

최소제곱 솔버와 야코비 행렬을 사용하는 최적화

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 object. The axes object 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

Copyright 2006–2020 The MathWorks, Inc.

관련 항목