이 번역 페이지는 최신 내용을 담고 있지 않습니다. 최신 내용을 영문으로 보려면 여기를 클릭하십시오.
스칼라 목적 함수 작성하기
함수 파일
스칼라 목적 함수 파일은 하나의 입력값, x
를 받으며 하나의 실수형 스칼라 출력값, f
를 반환합니다. 입력값 x
는 스칼라, 벡터 또는 행렬일 수 있습니다. 하나의 함수 파일에서 더 많은 출력값을 반환할 수 있습니다(기울기와 헤세 행렬 포함시키기 참조).
예를 들어, 목적 함수가 다음과 같이 세 가지 변수 x, y, z로 구성된 함수라고 가정하겠습니다.
f(x) = 3*(x – y)4 + 4*(x + z)2 / (1 + x2 + y2 + z2) + cosh(x – 1) + tanh(y + z).
이 함수를 벡터
xin
= [x;y;z]를 받고 f를 반환하는 파일로 작성합니다.function f = myObjective(xin) f = 3*(xin(1)-xin(2))^4 + 4*(xin(1)+xin(3))^2/(1+norm(xin)^2) ... + cosh(xin(1)-1) + tanh(xin(2)+xin(3));
이 파일을
myObjective.m
이라는 이름으로 MATLAB® 경로에 있는 폴더에 저장합니다.다음과 같이 함수가 올바르게 실행되는지 확인합니다.
myObjective([1;2;3]) ans = 9.2666
추가 파라미터를 포함시키는 방법에 대한 자세한 내용은 추가 파라미터 전달하기 항목을 참조하십시오. 함수 파일에 대한 더 복잡한 예제는 Minimization with Gradient and Hessian Sparsity Pattern 항목 또는 Minimization with Bound Constraints and Banded Preconditioner 항목을 참조하십시오.
로컬 함수와 중첩 함수
함수는 로컬 함수 또는 중첩 함수의 형태로 다른 파일 내에 존재할 수 있습니다. 로컬 함수 또는 중첩 함수를 사용하면 저장해야 하는 개별 파일의 개수가 적어질 수 있습니다. 중첩 함수를 사용하면 중첩 함수에서 보여지는 것처럼 추가 파라미터를 이용할 수도 있습니다.
예를 들어, 비선형 제약 조건에 설명된 제약 조건 ellipseparabola.m
을 따르는 함수 파일에서 다룬 myObjective.m
목적 함수를 최소화하고자 한다고 가정하겠습니다. 두 파일 myObjective.m
과 ellipseparabola.m
을 작성하는 대신 다음과 같이 두 함수를 로컬 함수로 포함하는 파일 하나를 작성합니다.
function [x fval] = callObjConstr(x0,options) % Using a local function for just one file if nargin < 2 options = optimoptions('fmincon','Algorithm','interior-point'); end [x fval] = fmincon(@myObjective,x0,[],[],[],[],[],[], ... @ellipseparabola,options); function f = myObjective(xin) f = 3*(xin(1)-xin(2))^4 + 4*(xin(1)+xin(3))^2/(1+sum(xin.^2)) ... + cosh(xin(1)-1) + tanh(xin(2)+xin(3)); function [c,ceq] = ellipseparabola(x) c(1) = (x(1)^2)/9 + (x(2)^2)/4 - 1; c(2) = x(1)^2 - x(2) - 1; ceq = [];
다음과 같이 점 [1;1;1]
부터 시작하여 제약 조건이 있는 최소화를 풉니다.
[x fval] = callObjConstr(ones(3,1)) Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the default value of the function tolerance, and constraints are satisfied to within the default value of the constraint tolerance. x = 1.1835 0.8345 -1.6439 fval = 0.5383
익명 목적 함수
익명 함수를 사용하여 간단한 목적 함수를 작성합니다. 익명 함수에 대한 자세한 내용은 익명 함수란? 항목을 참조하십시오. 로젠브록 함수는 익명 함수로 작성할 만큼 충분히 단순합니다.
anonrosen = @(x)(100*(x(2) - x(1)^2)^2 + (1-x(1))^2);
anonrosen
이 [-1 2]
에서 올바르게 실행되는지 확인합니다.anonrosen([-1 2]) ans = 104
fminunc
를 사용하여 anonrosen
을 최소화하면 다음 결과가 생성됩니다.options = optimoptions(@fminunc,'Algorithm','quasi-newton'); [x fval] = fminunc(anonrosen,[-1;2],options) Local minimum found. Optimization completed because the size of the gradient is less than the default value of the function tolerance. x = 1.0000 1.0000 fval = 1.2266e-10
기울기와 헤세 행렬 포함시키기
솔버에 도함수 제공하기
fmincon
및 fminunc
의 경우 목적 함수에 기울기를 포함시킬 수 있습니다. 일반적으로, 기울기를 포함시키면 솔버가 더 견고해지고 약간 더 빨라질 수 있습니다. 도함수 포함 시 얻을 수 있는 이점 항목을 참조하십시오. 2계 도함수(헤세 행렬)도 포함시키려면 헤세 행렬 포함시키기 항목을 참조하십시오.
다음 표에서는 어떤 알고리즘이 기울기와 헤세 행렬을 사용할 수 있는지 보여줍니다.
솔버 | 알고리즘 | 기울기 | 헤세 행렬 |
---|---|---|---|
fmincon | active-set | 선택적 | 불가 |
interior-point | 선택적 | 선택적(fmincon의 interior-point 알고리즘에 대한 헤세 행렬 참조) | |
sqp | 선택적 | 불가 | |
trust-region-reflective | 필수 | 선택적(fminunc의 trust-region 알고리즘 또는 fmincon의 trust-region-reflective 알고리즘에 대한 헤세 행렬 참조) | |
fminunc | quasi-newton | 선택적 | 불가 |
trust-region | 필수 | 선택적(fminunc의 trust-region 알고리즘 또는 fmincon의 trust-region-reflective 알고리즘에 대한 헤세 행렬 참조) |
기울기를 포함시키는 방법
다음을 수행하는 코드를 작성합니다.
첫 번째 출력값으로 목적 함수(스칼라)를 반환
두 번째 출력값으로 기울기(벡터)를 반환
optimoptions
를 사용하여SpecifyObjectiveGradient
옵션을true
로 설정합니다. 필요한 경우,SpecifyConstraintGradient
옵션도true
로 설정합니다.선택적으로, 기울기 함수가 유한 차분 근사와 일치하는지 여부를 확인합니다. Checking Validity of Gradients or Jacobians 항목을 참조하십시오.
팁
유연성을 극대화하려면 조건화된 코드를 작성합니다. 조건화되었다는 것은 다음 예제에 보여지는 것처럼 함수 출력값의 개수가 달라질 수 있음을 의미합니다. 조건화된 코드는 SpecifyObjectiveGradient
옵션의 값에 따라 오류를 발생시키지 않습니다. 조건화되지 않은 코드를 사용하려면 옵션을 적절하게 설정해야 합니다.
예를 들어, 다음과 같은 로젠브록 함수가 있다고 가정하겠습니다.
이 함수는 최적화 라이브 편집기 작업 또는 솔버를 사용한, 제약 조건이 있는 비선형 문제에 설명 및 플로팅되어 있습니다. f(x)의 기울기는 다음과 같습니다.
rosentwo
는 다음과 같이 솔버가 필요로 하는 모든 값을 반환하는 조건화된 함수입니다.
function [f,g] = rosentwo(x) % Calculate objective f f = 100*(x(2) - x(1)^2)^2 + (1-x(1))^2; if nargout > 1 % gradient required g = [-400*(x(2)-x(1)^2)*x(1)-2*(1-x(1)); 200*(x(2)-x(1)^2)]; end
nargout
은 호출하는 함수가 지정하는 인수의 개수를 확인합니다. 함수 인수의 개수 구하기 항목을 참조하십시오.
제약 조건이 없는 최적화에 사용하도록 설계된 fminunc
솔버를 사용하면 로젠브록 함수를 최소화할 수 있습니다. 다음과 같이 options
를 설정하여 기울기와 헤세 행렬을 사용하도록 fminunc
에 지시합니다.
options = optimoptions(@fminunc,'Algorithm','trust-region',... 'SpecifyObjectiveGradient',true);
다음과 같이 [-1;2]
에서 시작하도록 fminunc
를 실행합니다.
[x fval] = fminunc(@rosentwo,[-1;2],options) Local minimum found. Optimization completed because the size of the gradient is less than the default value of the function tolerance. x = 1.0000 1.0000 fval = 1.9886e-17
Symbolic Math Toolbox™ 라이선스가 있는 경우 Calculate Gradients and Hessians Using Symbolic Math Toolbox에 설명된 대로 기울기와 헤세 행렬을 자동으로 계산할 수 있습니다.
헤세 행렬 포함시키기
fmincon
의 'trust-region-reflective'
알고리즘과 'interior-point'
알고리즘, 그리고 fminunc
의 'trust-region'
알고리즘을 사용하여 2계 도함수를 포함시킬 수 있습니다. 헤세 행렬 정보를 포함시킬 수 있는 방법에는 정보 유형과 알고리즘에 따라 여러 가지가 있습니다.
헤세 행렬을 포함시키려면 기울기도 포함시켜야 합니다(SpecifyObjectiveGradient
를 true
로 설정하고, 해당되는 경우 SpecifyConstraintGradient
를 true
로 설정).
fminunc
의 trust-region 알고리즘 또는 fmincon
의 trust-region-reflective 알고리즘에 대한 헤세 행렬. 이러한 알고리즘에는 제약 조건이 전혀 없거나 범위 제약 조건 또는 선형 등식 제약 조건만 있습니다. 따라서 헤세 행렬은 목적 함수의 2계 도함수로 구성된 행렬입니다.
헤세 행렬을 목적 함수의 세 번째 출력값으로 포함시킵니다. 예를 들어, 로젠브록 함수의 헤세 행렬 H(x)는 다음과 같습니다(기울기를 포함시키는 방법 참조).
목적 함수에 이 헤세 행렬을 포함시킵니다.
function [f, g, H] = rosenboth(x) % Calculate objective f f = 100*(x(2) - x(1)^2)^2 + (1-x(1))^2; if nargout > 1 % gradient required g = [-400*(x(2)-x(1)^2)*x(1)-2*(1-x(1)); 200*(x(2)-x(1)^2)]; if nargout > 2 % Hessian required H = [1200*x(1)^2-400*x(2)+2, -400*x(1); -400*x(1), 200]; end end
HessianFcn
을 'objective'
로 설정합니다. 예를 들면 다음을 입력합니다.
options = optimoptions('fminunc','Algorithm','trust-region',... 'SpecifyObjectiveGradient',true,'HessianFcn','objective');
fmincon
의 interior-point 알고리즘에 대한 헤세 행렬. 헤세 행렬은 라그랑주 함수의 헤세 행렬이며, 여기서 라그랑주 함수 L(x,λ)는 다음과 같습니다.
g 및 h는 각각 모든 부등식 제약 조건과 등식 제약 조건(즉, 범위 제약 조건, 선형 제약 조건, 비선형 제약 조건)을 나타내는 벡터 함수이므로 최소화 문제는 다음과 같습니다.
자세한 내용은 제약 조건이 있는 최적성 이론 항목을 참조하십시오. 라그랑주 함수의 헤세 행렬은 다음과 같습니다.
(1) |
헤세 행렬을 포함시키려면 다음 구문을 사용하여 함수를 작성하십시오.
hessian = hessianfcn(x,lambda)
hessian
은 n×n 희소 또는 조밀 행렬이며, 여기서 n은 변수의 개수입니다. hessian
이 대규모이고 상대적으로 적은 수의 0이 아닌 요소를 가지는 경우 hessian
을 희소 행렬로 나타내어 실행 시간과 메모리를 절약하십시오. lambda
는 다음과 같이 비선형 제약 조건과 연결된 라그랑주 승수 벡터를 갖는 구조체입니다.
lambda.ineqnonlin lambda.eqnonlin
fmincon
은 구조체 lambda
를 계산한 후 이를 헤세 행렬 함수에 전달합니다. hessianfcn
은 수식 1의 합계를 계산해야 합니다. 다음 옵션을 설정하여 사용자가 헤세 행렬을 제공한다는 것을 나타냅니다.
options = optimoptions('fmincon','Algorithm','interior-point',... 'SpecifyObjectiveGradient',true,'SpecifyConstraintGradient',true,... 'HessianFcn',@hessianfcn);
예를 들어, 단위 원판 로 제한된 로젠브록 함수의 헤세 행렬을 포함시키려면 제약 조건 함수 가 다음과 같은 기울기와 2계 도함수 행렬을 포함한다는 것을 상기하십시오.
다음과 같이 헤세 행렬 함수를 작성합니다.
function Hout = hessianfcn(x,lambda) % Hessian of objective H = [1200*x(1)^2-400*x(2)+2, -400*x(1); -400*x(1), 200]; % Hessian of nonlinear inequality constraint Hg = 2*eye(2); Hout = H + lambda.ineqnonlin*Hg;
hessianfcn
을 MATLAB 경로에 저장합니다. 예제를 완료하기 위해 기울기를 포함하는 제약 조건 함수를 설명하면 다음과 같습니다.
function [c,ceq,gc,gceq] = unitdisk2(x) c = x(1)^2 + x(2)^2 - 1; ceq = [ ]; if nargout > 2 gc = [2*x(1);2*x(2)]; gceq = []; end
기울기와 헤세 행렬을 포함하는 문제를 풉니다.
fun = @rosenboth; nonlcon = @unitdisk2; x0 = [-1;2]; options = optimoptions('fmincon','Algorithm','interior-point',... 'SpecifyObjectiveGradient',true,'SpecifyConstraintGradient',true,... 'HessianFcn',@hessianfcn); [x,fval,exitflag,output] = fmincon(fun,x0,[],[],[],[],[],[],@unitdisk2,options);
interior-point 헤세 행렬을 사용하는 다른 예제는 해석적 헤세 행렬을 사용하는 fmincon Interior-Point 알고리즘 항목과 Calculate Gradients and Hessians Using Symbolic Math Toolbox 항목을 참조하십시오.
헤세 행렬의 곱셈 함수. 전체 헤세 행렬 함수 대신 fmincon
의 interior-point
알고리즘과 trust-region-reflective
알고리즘을 사용하면 헤세 행렬의 곱셈 함수를 제공할 수 있습니다. 이 함수는 헤세 행렬을 직접 계산하지 않고 헤세 행렬과 벡터의 곱에 대한 결과를 구해줍니다. 따라서 메모리를 절약할 수 있습니다. 헤세 행렬의 곱셈 함수가 작동하려면 SubproblemAlgorithm
옵션이 'cg'
여야 하며, 이는 trust-region-reflective
의 디폴트 값입니다.
두 알고리즘의 구문은 서로 다릅니다.
interior-point
알고리즘의 경우 구문은 다음과 같습니다.W = HessMultFcn(x,lambda,v);
결과
W
는 곱H*v
여야 하며, 여기서H
는x
에서 계산된 라그랑주 함수의 헤세 행렬이고(수식 3 참조),lambda
는 라그랑주 승수이며(fmincon
으로 계산됨),v
는 n×1 크기의 벡터입니다. 옵션을 다음과 같이 설정합니다.options = optimoptions('fmincon','Algorithm','interior-point','SpecifyObjectiveGradient',true,... 'SpecifyConstraintGradient',true,'SubproblemAlgorithm','cg','HessianMultiplyFcn',@HessMultFcn);
n×1 벡터를 반환하는 함수
HessMultFcn
을 제공하십시오. 여기서 n은 x의 차원 수입니다.HessianMultiplyFcn
옵션을 사용하면 헤세 행렬을 계산하지 않고도 헤세 행렬과 벡터를 곱한 결과를 전달할 수 있습니다.trust-region-reflective
알고리즘은lambda
를 사용하지 않습니다.W = HessMultFcn(H,v);
결과를 나타내는 식은
W = H*v
입니다.fmincon
은 목적 함수의 세 번째 출력값에 반환되는 값으로H
를 전달합니다(fminunc의 trust-region 알고리즘 또는 fmincon의 trust-region-reflective 알고리즘에 대한 헤세 행렬 참조).fmincon
은 n개 행을 가지는 벡터 또는 행렬인v
도 전달합니다.v
에 포함된 열의 개수는 달라질 수 있으므로 임의 개수의 열을 받을 수 있도록HessMultFcn
을 작성하십시오.H
는 반드시 헤세 행렬일 필요가 없으며W = H*v
를 계산할 수 있는 어떤 것이든 가능합니다.옵션을 다음과 같이 설정합니다.
options = optimoptions('fmincon','Algorithm','trust-region-reflective',... 'SpecifyObjectiveGradient',true,'HessianMultiplyFcn',@HessMultFcn);
trust-region-reflective
알고리즘에 헤세 행렬의 곱셈 함수를 사용하는 예제를 보려면 Minimization with Dense Structured Hessian, Linear Equalities 항목을 참조하십시오.
도함수 포함 시 얻을 수 있는 이점
기울기를 제공하지 않을 경우 솔버는 유한 차분을 통해 기울기를 추정합니다. 복잡한 도함수에는 유한 차분 추정이 더 빠를 수 있지만 기울기를 제공하면 솔버가 이 유한 차분 추정을 수행할 필요가 없으므로 시간을 절약할 수 있으며 정확도가 더 높을 수 있습니다. 또한, 솔버는 실제 헤세 행렬과 많이 차이가 날 수 있는 근사 헤세 행렬을 사용합니다. 헤세 행렬을 제공하면 더 적은 반복으로 해에 수렴할 수 있습니다. 예를 들어 Calculate Gradients and Hessians Using Symbolic Math Toolbox의 마지막 부분을 참조하십시오.
제약 조건이 있는 문제에 대해 기울기를 제공하면 또 다른 이점을 얻을 수 있습니다. 솔버는 x
를 실현 가능하게 되는 점 x
에 도달할 수 있지만, 이 x
에 대해서 x
주위의 유한 차분은 항상 실현불가능점에 이르게 됩니다. 실현불가능점에서의 목적 함수가 복소수 출력값, Inf
, NaN
또는 오류를 반환한다고 가정하겠습니다. 이 경우, 솔버가 실패하거나 도중에 중단될 수 있습니다. 기울기를 제공하면 솔버가 계속 진행할 수 있습니다. 이 이점을 얻으려면 비선형 제약 조건 함수의 기울기를 포함시키고 SpecifyConstraintGradient
옵션을 true
로 설정해야 할 수도 있습니다. 비선형 제약 조건 항목을 참조하십시오.
fmincon
의 interior-point에 대한 입력값으로 헤세 행렬 근삿값 선택하기
fmincon
의 interior-point
알고리즘에는 입력값으로 헤세 행렬 근삿값을 선택할 수 있는 옵션이 많이 있습니다. 구문 세부 정보는 입력값 헤세 행렬 항목을 참조하십시오. 다음은 옵션과 각 옵션의 상대적인 특성에 대한 추정값을 보여줍니다.
헤세 행렬 | 상대적인 메모리 사용량 | 상대적인 효율성 |
---|---|---|
'bfgs' (디폴트 값) | 높음(대규모 문제의 경우) | 높음 |
'lbfgs' | 낮음~중간 | 중간 |
'fin-diff-grads' | 낮음 | 중간 |
'HessianMultiplyFcn' | 낮음(코드에 따라 다를 수 있음) | 중간 |
'HessianFcn' | ?(코드에 따라 다름) | 높음(코드에 따라 다름) |
다음 경우에 해당되지 않을 경우 디폴트 'bfgs'
헤세 행렬을 사용하십시오.
메모리가 부족한 경우 —
'bfgs'
대신'lbfgs'
를 사용해 봅니다. 기울기를 직접 제공할 수 있는 경우'fin-diff-grads'
를 사용해 보고SpecifyObjectiveGradient
옵션과SpecifyConstraintGradient
옵션을true
로 설정하십시오.더 높은 효율성을 원할 경우 — 기울기와 헤세 행렬을 직접 제공하십시오. 헤세 행렬 포함시키기, 해석적 헤세 행렬을 사용하는 fmincon Interior-Point 알고리즘, Calculate Gradients and Hessians Using Symbolic Math Toolbox 항목을 참조하십시오.
'lbfgs'
의 효율성이 중간 수준인 이유는 두 가지가 있습니다. 셔먼-모리슨(Sherman-Morrison) 업데이트가 상대적으로 비용이 많이 듭니다. 그리고 결과로 생성되는 반복 스텝은 'lbfgs'
의 제한된 메모리로 인해 다소 부정확할 수 있습니다.
'fin-diff-grads'
와 HessianMultiplyFcn
의 효율성이 중간 수준인 이유는 켤레 기울기 접근법을 사용하기 때문입니다. 이 옵션은 목적 함수의 헤세 행렬을 정확하게 추정하지만, 가장 정확한 반복 스텝을 생성하지는 않습니다. 자세한 내용은 fmincon의 Interior Point 알고리즘 항목과 수식 38 풀이를 위한 LDL 접근법 및 켤레 기울기 접근법에 대한 설명을 참조하십시오.