我試圖創建一個函式和一個所述函式的函式句柄,該函式接收前一次呼叫的輸出引數和新的輸入引數,并在該函式中計算梯度,如下圖所示的玩具例子。我想把這個函式句柄傳遞給hmcSampler。然而,我在創建函式句柄時遇到了問題,希望得到一些幫助。
澄清一下:我想用一個新的theta值來呼叫logPosterior,但也要用之前呼叫的theta和logpdf輸出。而且我需要通過一個函式句柄來做這件事,該句柄將被一個我不控制的函式多次呼叫,所以我需要logPosterior或其句柄來管理存盤舊值。在第一次呼叫時,應該有不同的theta和old_theta的值,這樣函式才能開始運行。
%% 在Matlab中實作hmcsampler類的玩具
NumPredictors = 2;
trueIntercept = 2;
trueBeta = [3; 0]。
NumData = 100;
rng('default') %For reproducibility
X = rand(NumData,NumPredictors)。
mu = X*trueBeta trueIntercept;
y = mu;
%定義每個引數的正態分布的平均值和方差。
means = [0; 0] 。
standevs = [1;1] 。
%創建多變數正態對數概率分布。
[logpdf, grad_logpdf] = @(theta)logPosterior(theta, old_theta, X, y, means, standevs, old_logpdf); % <- 如何寫這個?
% 創建開始采樣的起始點。
startpoint = randn(2, 1) 。
%創建一個HMC采樣器物件。
smp = hmcSampler(logpdf, startpoint);
% 估計對數概率密度的最大值 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;
% 計算引數的對數priors和梯度。
log_prior_params = 0;
grad_params2 = [];
for i = 1:3 i), means(i), standevs(i) 。)
log_prior_params = log_prior_params lp;
grad_params2 = [grad_params2; grad];
結束。
%回傳對數后驗及其梯度。
logpdf = log_likelihood log_prior_params;
grad_logpdf = grad_params1 grad_params2。
結束。
function [lpd,glpdf] = normalDistGrad(X, Mu, Sigma)
Z = (X - Mu)./Sigma;
lpdf = sum(-log(Sigma) - . 5*log(2*pi) - .5*(Z.^2))。
glpdf = -Z./Sigma;
結束。
uj5u.com熱心網友回復:
首先在一個單獨的m檔案中定義你的函式,該檔案在你的當前路徑中:
function [o1, o2]=myfunc(in1,in2,in3)
o1=in1 in2 in3。
o2=in3-in2。
end
然后創建函式的句柄 :
f=@myfunc;
f(1,2, 3)
ans=6
只使用其中一個輸入:
f=@(x)myfunc(x,3,5) 。
f(1)
ans=9。
獲得這兩種輸出:
[a,b]=f(1) 。
或者在你的函式中定義一個輸出,并在呼叫它們后參考它們的索引 :
function o=myfunc(in1。 in2,in3)
o1=in1 in2 in3。
o2=in3-in2。
o=[o1,o2]。
end
...
uj5u.com熱心網友回復:
我將按以下方式實作logPosterior,以便它能跟蹤最后一次函式呼叫中的值。persistent變數是函式的本地變數,但在呼叫之間持續存在,使其成為賦予函式記憶的理想工具。
function [logpdf, grad_logpdf] = logPosterior(theta, X, y, means, standevs)
persistent old_theta old_logpdf
if isempty(old_theta)
%函式之前沒有被呼叫,初始化舊值:。
old_theta = zeros(size(theta))。
old_logpdf = 0; % 調整為有意義的初始值。
end; %調整為有意義的初始值。
% ... (你的原始函式代碼在這里)
% 將新值保存為舊值,以便下次呼叫。
old_theta = theta;
old_logpdf = logpdf;
結束。
你現在會采取一個函式句柄,如下所示:
func = @(theta)logPosterior(theta, X, y, means, standevs)。
func是你要傳遞到任何將呼叫它的函式的句柄。你可以通過運行一次你的函式來初始化前面的變數(我不確定什么是合適的初始化!):
func(startpoint)。
smp = hmcSampler(func, startpoint)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/309723.html
標籤:
上一篇:有沒有一種方法可以讓matlab函式訪問腳本中的所有變數?
下一篇:如何從一個隱藏的元素中搜刮文本?
