【发布时间】:2021-11-01 01:33:58
【问题描述】:
我正在尝试创建一个函数和所述函数的函数句柄,其中该函数接收来自先前调用的输出参数和新的输入参数,并计算函数中的梯度,如下所示的玩具示例中给出。我想将函数句柄传递给hmcSampler。但是,我在创建函数句柄时遇到了问题,希望得到一些帮助。
澄清一下:我想用 theta 的新值调用 logPosterior,但也要使用上一次调用的 theta 和 logpdf 输出。我需要通过一个函数句柄来执行此操作,该函数句柄将由我无法控制的函数多次调用,因此我需要logPosterior 或其句柄来管理存储旧值。在第一次调用中,theta 和 old_theta 的值应该不同,这样函数才能运行。
%% Toy implementation of hmcsampler class in Matlab
NumPredictors = 2;
trueIntercept = 2;
trueBeta = [3;0];
NumData = 100;
rng('default') %For reproducibility
X = rand(NumData,NumPredictors);
mu = X*trueBeta + trueIntercept;
y = mu;
% define the mean and variance of normal distribution of each parameter
means = [0; 0];
standevs = [1;1];
% create multivariate normal log probability distribution
[logpdf, grad_logpdf] = @(theta)logPosterior(theta, old_theta, X, y, means, standevs, old_logpdf); % <- How to write this?
% create the startpoint from which sampling starts
startpoint = randn(2, 1);
% create an HMC sampler object
smp = hmcSampler(logpdf, startpoint);
% estimate maximum of log probability density
[xhat, fitinfo] = estimateMAP(smp);
num_chains = 4;
chains = cell(num_chains, 1);
burnin = 50000;
num_samples = 2000000;
function [logpdf, grad_logpdf] = logPosterior(theta, old_theta, X, y, means, standevs, old_logpdf)
% values
intercept = theta(1);
beta = theta(2:end);
y_computed = X*beta + intercept;
log_likelihood = log(y_computed);
del_loglikelihood = log_likelihood - old_logpdf;
del_params = theta - old_theta;
grad_params1 = del_loglikelihood/del_params;
% compute log priors and gradients of parameters
log_prior_params = 0;
grad_params2 = [];
for i = 1:3
[lp, grad] = normalDistGrad(theta(i), means(i), standevs(i));
log_prior_params = log_prior_params + lp;
grad_params2 = [grad_params2; grad];
end
% return the log posterior and its gradient
logpdf = log_likelihood + log_prior_params;
grad_logpdf = grad_params1 + grad_params2;
end
function [lpdf,glpdf] = normalDistGrad(X, Mu, Sigma)
Z = (X - Mu)./Sigma;
lpdf = sum(-log(Sigma) - .5*log(2*pi) - .5*(Z.^2));
glpdf = -Z./Sigma;
end
【问题讨论】:
-
“我在创建函数句柄时遇到问题,需要一些帮助。”你能详细说明一下这个问题吗?它没有按预期工作吗?它是否给出错误消息?在您的示例中,
old_theta是什么?我没有看到它在任何地方定义。此外,normalDistGrad仅接受 3 个参数,您可能打算调用logPosterior? -
所以我认为您想要做的是:使用新值
theta调用logPosterior,同时使用上一次调用的theta和logpdf输出。您需要通过函数句柄来执行此操作,该函数句柄将由您无法控制的函数多次调用,因此您需要函数本身或函数句柄来管理存储旧值。可以修改logPosterior吗?如果是这样,那将是最简单的解决方案。第一次调用该函数时应该发生什么? -
是的,你是绝对正确的。是的,
logPosterior是我写的,所以可以更改。我是否只是将上一次调用的参数存储在全局变量中,然后在logPosterior中使用它?在第一次调用中,theta和old_theta的值应该不同,这样函数才能运行。