我正在尝试使用 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 中实现这个

最佳答案

这是可能的,并在 documentation 中进行了描述:

如果也可以计算 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);

具有 logx 梯度的 fminunc

对于您的 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'))

具有 logx 梯度的 fminunc 示例
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]

关于matlab - 使用 fminunc 函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10582538/

10-12 18:11