对于上下文,我在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
其中omega
和v_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下获得