使用fminunc函数

3

我正在尝试使用fminunc函数进行凸优化。然而,在我的情况下,我将梯度与logx相关联。让目标函数为F。那么梯度将是

dF/dx = (dF/dlogx) * (1/x)
= > dF/dlogx = (dF/dx) * x

所以
logx_new = logx_old + learning_rate * x * (dF/logx)
x_new = exp(logx_new)

我该如何在fminunc中实现这个?
1个回答

7

这在文档中有详细描述:

如果fun的梯度也可以被计算并且设置了GradObj选项为'on',如下所示: options = optimset('GradObj','on') 那么函数fun必须在第二个输出参数中返回梯度值g(一个向量),其值为x.

使用自定义梯度的fminunc

例如:如果 f = @(x) x.^2; 那么 df/dx = 2*x,你就可以使用:

function [f df] = f_and_df(x)
    f = x.^2;
    if nargout>1
        df = 2*x;
    end
end

你可以将该函数传递给fminunc
options = optimset('GradObj','on');
x0 = 5;
[x,fval] = fminunc(@f_and_df,x0,options);

fminunc与logx梯度

对于您的logx梯度,可以采用以下方法:

function [f df] = f_and_df(x)
    f = ...;
    if nargout>1
        df =  x * (dF/logx);
    end
end

并且fminunc保持不变。

使用匿名函数的fminunc

如果您愿意,也可以使用匿名函数:

f_and_df2 = @(x) deal(x(1).^2+x(2).^2,[2*x(1)  2*x(2)]);
[x,fval] = fminunc(f_and_df2,[5, 4],optimset('GradObj','on'))

fminunc与logx梯度的示例

f = (log(x))^2的附加示例

function [f df_dlogx] = f_and_df(x)
    f = log(x).^2;

    df_dx = 2*log(x)./x;
    df_dlogx = df_dx.* x;
end

接着:

>>x0=3;
>>[x,fval] = fminunc(@f_and_df,x0,optimset('GradObj','on'))
x =
   0.999999990550151

fval =
   8.92996430424197e-17

使用自定义梯度和多个变量的fminunc示例

对于多个变量,例如f(x,y),您需要将变量放入向量中,例如:

function [f df_dx] = f_and_df(x)
    f = x(1).2 + x(2).^2;

    df_dx(1) = 2*x(1);
    df_dx(2) = 2*x(2);
end

这个函数对应于一个抛物面。当然,您还需要使用矢量作为初始起始参数,在本例中例如:x0=[-5 3]。


我不明白。df = x * (dF/logx) 是什么意思?如果我有多个变量,比如x、y、z,那该怎么做呢? - rajan sthapit
我不知道你的实际函数或梯度是什么,这就是为什么我在你的问题中输入了你写的表达式:dF/dlogx = (dF/dx) * x。在我的答案中,df指的是实际梯度df/dx,或者对于你的情况是关于logx的梯度:dF/dx。我会在我的帖子中尝试给出另一个例子。 - Gunther Struyf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接