虽然Hessians做

时间:2018-02-08 15:08:18

标签: algorithm matlab numerics

对于上下文,我在MATLAB中有一个小项目,我尝试复制一个涉及牛顿算法优化的算法。虽然我的问题主要是MATLAB,但也许我缺乏深刻的背景知识,这使我无法找到解决方案,所以如果需要,请随意将我重定向到相应的StackExchange站点。

我需要计算梯度向量和Hessian矩阵进行优化的函数是:

function [zi] = Zi(lambda,j)
    zi = m(j)*exp(-(lambda*v_tilde(j,:).'));
end

function [z] = Z(lambda)
    res = arrayfun(@(x) Zi(lambda,x),1:length(omega));
    z = sum(res);

end

function [f] = F(lambda)
    f = log(Z(lambda));
end

其中omegav_tilde是n维向量的矩阵,lambda是函数的d维参数。 (现在,m(j)只是选择器(1或0),但算法允许对这些进行优化,因此不应删除它们。 我使用Derivest Suite来计算渐变和Hessian数值,并且,尽管逻辑上对于高维度来说很慢,但算法整体上都有效。 我使用sym包实现了相同的解决方案,因此我可以提前计算梯度和Hessian以获得一些修复n和d,因此可以在需要时快速评估它们。这将是符号版本:

V_TILDE = sym('v_tilde',[d,n]) 
syms n k

lambda = sym('lambda',[d,1]); 
F = log(M*exp(-(transpose(V_TILDE)*lambda)));

matlabFunction( grad_F, 'File', sprintf('Grad_%d_dim_%d_n.m',d,n_max),  'vars',{a,lambda,V_TILDE});
matlabFunction( hesse_F, 'File', sprintf('Hesse_%d_dim_%d_n.m',d,n_max), 'vars',{a,lambda,V_TILDE});

由于n已修复,因此无需迭代omega。这个梯度和Hessian可以通过sym的相应函数获得,然后存储为matlabFunctions。

然而,当我针对某些值测试两种实现时,它们并不匹配,但令人惊讶的是,粗体矩阵的值匹配而渐变的值不匹配(数值计算正确) ,牛顿算法迭代,直到值只有NaN。这些是d = 2和n = 8的一些示例值:

Omega:
12.6987   91.3376
95.7507   96.4889
15.7613   97.0593
95.7167   48.5376
70.6046    3.1833
27.6923    4.6171
9.7132   82.3458
95.0222    3.4446

v:
61.2324
52.2271

gNum =          HNum =    1.0e+03 *

  8.3624                 1.4066   -0.5653
 -1.1496                -0.5653    1.6826

gSym =          HSym =    1.0e+03 *

 -52.8700                1.4066   -0.5653
 -53.3768               -0.5653    1.6826

正如您所看到的,HNum和HSym的值匹配,但渐变不会。

我很乐意提供更多上下文信息,代码段或任何有用的信息。提前谢谢!

编辑:根据要求,这是一个最小的测试。问题基本上是gNum和gSym的值不匹配(上面的更长解释):

omega = [[12.6987,   91.3376];[95.7507, 96.4889];[15.7613, 97.0593];
[95.7167, 48.5376];[70.6046, 3.1833];[27.6923, 4.6171];[9.7132,  82.3458];
[95.0222, 3.4446]];

v = [61.2324;52.2271];

gradStr = sprintf('Grad_%d_dim_%d_n',length(omega(1,:)),length(omega));
hesseStr = sprintf('Hesse_%d_dim_%d_n',length(omega(1,:)),length(omega));
g = str2func(gradStr);
H = str2func(hesseStr);
selector = ones(1,length(omega)); %this will change, when n_max>n

vtilde = zeros(length(omega),length(omega(1,:)));
for i = 1:length(omega)
    vtilde(i,:) = omega(i,:)-v;
end

lambda = zeros(1,length(omega(1,:))); % start of the optimization

[gNum,~,~] = gradest(@F,lambda)
[HNum,~] = hessian(@F,lambda)
gSym = g(selector,lambda.',omega.')
HSym = H(selector,lambda.',omega.')

注意:DerivestSuite是一个小型库(约6个源文件),可以在https://de.mathworks.com/matlabcentral/fileexchange/13490-adaptive-robust-numerical-differentiation下获得

0 个答案:

没有答案