Main Content

勾配またはヤコビアンの有効性を確認

目的関数の勾配またはヤコビアンのチェック

多数のソルバーにより、目的関数または制約関数の 1 次導関数 (勾配またはヤコビアン) を計算する関数を与えることができます。関数によって計算された導関数が有限差分近似と一致するかどうかを確認することができます。この確認は、導関数が正しいかどうかを診断するのに役立ちます。

  • 勾配関数の成分が 1 より小さい場合、「一致」とは、その成分の勾配関数の絶対差分と有限差分近似が 1e-6 より小さいことを意味します。

  • それ以外の場合は、「一致」とは、相対差分が 1e-6 未満であることを意味します。

CheckGradients オプションにより、ソルバーは指定された導関数を 1 点でのみ有限差分近似に対して確認します。指定された導関数が有限差分と一致しない場合は、ソルバーは不一致を報告します。導関数が 1e-6 内で一致する場合は、ソルバーは計算された差分を報告し、導関数の確認をこれ以上行わずに反復を続行します。ソルバーでは初期点 x0 における無作為な摂動の 1 点で一致が確認され、範囲内に収まるように変更されます。ソルバーでの CheckGradients の計算は関数計算回数に含まれません。反復と関数計算回数を参照してください。

導関数を確認する方法

MATLAB® コマンド ラインの場合:

  1. optimoptions を使用して、SpecifyObjectiveGradient オプションまたは SpecifyConstraintGradient オプションを true に設定します。目的関数または制約関数は、必ず適切な導関数を与えるものを指定してください。

  2. CheckGradients オプションを true に設定します。

中心有限差分法は、既定の前進有限差分法より正確です。MATLAB コマンド ラインで中心有限差分法を使用する場合は、optimoptions を使用して FiniteDifferenceType オプションを 'central' に設定します。

例: 目的関数と制約関数の導関数を確認

目的関数と制約関数

制約付き非線形問題の解法、ソルバーベースで説明するように、単位円板内で Rosenbrock 関数を最小化する問題を考えてみましょう。rosenboth は目的関数とその勾配を計算します。

function [f g H] = rosenboth(x)

f = 100*(x(2) - x(1)^2)^2 + (1-x(1))^2;

if nargout > 1
    g = [-400*(x(2)-x(1)^2)*x(1)-2*(1-x(1));
        200*(x(2)-x(1)^2)];
    
    if nargout > 2
        H = [1200*x(1)^2-400*x(2)+2, -400*x(1);
            -400*x(1), 200];  
    end
end

また、rosenboth は、ヘッシアンも計算しますが、この例ではヘッシアンを使用しません。

関数 unitdisk2 は制約関数とその勾配を正しく計算します。

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

関数 unitdiskb は制約関数の勾配を正しく計算しません。

function [c ceq gc gceq] = unitdiskb(x)
c = x(1)^2 + x(2)^2 - 1;
ceq = [ ];

if nargout > 2
    gc = [x(1);x(2)]; % Gradient incorrect: off by a factor of 2
    gceq = [];
end

コマンド ラインにおける導関数を確認

  1. オプションが内点法 (interior-point) アルゴリズム、目的関数と制約関数の勾配、CheckGradients オプションを使用するように設定します。

    % For reproducibility--CheckGradients randomly perturbs the initial point
    rng(0,'twister'); 
    options = optimoptions(@fmincon,'Algorithm','interior-point',...
        'CheckGradients',true,'SpecifyObjectiveGradient',true,'SpecifyConstraintGradient',true);
  2. 誤った unitdiskb 制約関数を使用して、最小化を fmincon で解きます。

    [x fval exitflag output] = fmincon(@rosenboth,...
       [-1;2],[],[],[],[],[],[],@unitdiskb,options);
    ____________________________________________________________
       Derivative Check Information  
    
    Objective function derivatives:
    Maximum relative difference between user-supplied 
    and finite-difference derivatives = 1.84768e-008.
    
    Nonlinear inequality constraint derivatives:
    Maximum relative difference between user-supplied 
    and finite-difference derivatives = 1.
     User-supplied constraint derivative element (2,1):     1.99838
     Finite-difference constraint derivative element (2,1): 3.99675
    ____________________________________________________________
    
    Error using validateFirstDerivatives
    Derivative Check failed:
    User-supplied and forward finite-difference derivatives
    do not match within 1e-006 relative tolerance.
    
    Error in fmincon at 805
        validateFirstDerivatives(funfcn,confcn,X, ...

    制約関数が計算された勾配と一致しないため、エラーのせいで関数を確認せざるをえません。

  3. 制約関数 unitdiskbunitdisk2 と置き換えて、再び最小化を行います。

    [x fval exitflag output] = fmincon(@rosenboth,...
       [-1;2],[],[],[],[],[],[],@unitdisk2,options);
    
    ____________________________________________________________
       Derivative Check Information  
    
    Objective function derivatives:
    Maximum relative difference between user-supplied 
    and finite-difference derivatives = 1.28553e-008.
    
    Nonlinear inequality constraint derivatives:
    Maximum relative difference between user-supplied 
    and finite-difference derivatives = 1.46443e-008.
    
    Derivative Check successfully passed.
    ____________________________________________________________
    
    
    Local minimum found that satisfies the constraints...