Stan/rstan中高斯过程的优化

Stan/rstan中高斯过程的优化,r,stan,rstan,rstanarm,R,Stan,Rstan,Rstanarm,我最近遇到了高斯过程模型,并碰巧认为它们可能是我在实验室研究的问题的解决方案。我有一个关于交叉验证的开放性相关问题,但我想将建模/数学问题与编程问题分开。因此,这是第二篇相关文章。如果知道更多关于我的问题背景会有所帮助,尽管这里是我打开的链接 这是我的stan代码,对应于我的简历帖子中更新的协方差函数: functions{ //covariance function for main portion of the model matrix main_GP( in

我最近遇到了高斯过程模型,并碰巧认为它们可能是我在实验室研究的问题的解决方案。我有一个关于交叉验证的开放性相关问题,但我想将建模/数学问题与编程问题分开。因此,这是第二篇相关文章。如果知道更多关于我的问题背景会有所帮助,尽管这里是我打开的链接

这是我的stan代码,对应于我的简历帖子中更新的协方差函数:

functions{
    //covariance function for main portion of the model
    matrix main_GP(
        int Nx,
        vector x,
        int Ny,
        vector y, 
        real alpha1,
        real alpha2,
        real alpha3,
        real rho1,
        real rho2,
        real rho3,
        real rho4,
        real rho5,
        real HR_f,
        real R_f){
                    matrix[Nx, Ny] K1;
                    matrix[Nx, Ny] K2;
                    matrix[Nx, Ny] K3;
                    matrix[Nx, Ny] Sigma;

                    //specifying random Gaussian process that governs covariance matrix
                    for(i in 1:Nx){
                        for (j in 1:Ny){
                            K1[i,j] = alpha1*exp(-square(x[i]-y[j])/2/square(rho1));
                        }
                    }

                    //specifying random Gaussian process incorporates heart rate
                    for(i in 1:Nx){
                        for(j in 1:Ny){
                            K2[i, j] = alpha2*exp(-2*square(sin(pi()*fabs(x[i]-y[j])*HR_f))/square(rho2))*
                            exp(-square(x[i]-y[j])/2/square(rho3));
                        }
                    }

                    //specifying random Gaussian process incorporates heart rate as a function of respiration
                    for(i in 1:Nx){
                        for(j in 1:Ny){
                            K3[i, j] = alpha3*exp(-2*square(sin(pi()*fabs(x[i]-y[j])*HR_f))/square(rho4))*
                            exp(-2*square(sin(pi()*fabs(x[i]-y[j])*R_f))/square(rho5));
                        }
                    }

                    Sigma = K1+K2+K3;
                    return Sigma;
                }
    //function for posterior calculations
    vector post_pred_rng(
        real a1,
        real a2,
        real a3,
        real r1, 
        real r2,
        real r3,
        real r4,
        real r5,
        real HR,
        real R,
        real sn,
        int No,
        vector xo,
        int Np, 
        vector xp,
        vector yobs){
                matrix[No,No] Ko;
                matrix[Np,Np] Kp;
                matrix[No,Np] Kop;
                matrix[Np,No] Ko_inv_t;
                vector[Np] mu_p;
                matrix[Np,Np] Tau;
                matrix[Np,Np] L2;
                vector[Np] yp;

    //--------------------------------------------------------------------
    //Kernel Multiple GPs for observed data
    Ko = main_GP(No, xo, No, xo, a1, a2, a3, r1, r2, r3, r4, r5, HR, R);
    Ko = Ko + diag_matrix(rep_vector(1, No))*sn;

    //--------------------------------------------------------------------
    //kernel for predicted data
    Kp = main_GP(Np, xp, Np, xp, a1, a2, a3, r1, r2, r3, r4, r5, HR, R);
    Kp = Kp + diag_matrix(rep_vector(1, Np))*sn;

    //--------------------------------------------------------------------
    //kernel for observed and predicted cross 
    Kop = main_GP(No, xo, Np, xp, a1, a2, a3, r1, r2, r3, r4, r5, HR, R);

    //--------------------------------------------------------------------
    //Algorithm 2.1 of Rassmussen and Williams... 
    Ko_inv_t = Kop'/Ko;
    mu_p = Ko_inv_t*yobs;
    Tau=Kp-Ko_inv_t*Kop;
    L2 = cholesky_decompose(Tau);
    yp = mu_p + L2*rep_vector(normal_rng(0,1), Np);
    return yp;
    }
}

data { 
    int<lower=1> N1;
    int<lower=1> N2;
    vector[N1] X; 
    vector[N1] Y;
    vector[N2] Xp;
    real<lower=0> mu_HR;
    real<lower=0> mu_R;
}

transformed data { 
    vector[N1] mu;
    for(n in 1:N1) mu[n] = 0;
}

parameters {
    real loga1;
    real loga2;
    real loga3;
    real logr1;
    real logr2;
    real logr3;
    real logr4;
    real logr5;
    real<lower=.5, upper=3.5> HR;
    real<lower=.05, upper=.75> R;
    real logsigma_sq;
}

transformed parameters {
    real a1 = exp(loga1);
    real a2 = exp(loga2);
    real a3 = exp(loga3);
    real r1 = exp(logr1);
    real r2 = exp(logr2);
    real r3 = exp(logr3);
    real r4 = exp(logr4);
    real r5 = exp(logr5);
    real sigma_sq = exp(logsigma_sq);
}

model{ 
    matrix[N1,N1] Sigma;
    matrix[N1,N1] L_S;

    //using GP function from above 
    Sigma = main_GP(N1, X, N1, X, a1, a2, a3, r1, r2, r3, r4, r5, HR, R);
    Sigma = Sigma + diag_matrix(rep_vector(1, N1))*sigma_sq;

    L_S = cholesky_decompose(Sigma);
    Y ~ multi_normal_cholesky(mu, L_S);

    //priors for parameters
    loga1 ~ student_t(3,0,1);
    loga2 ~ student_t(3,0,1);
    loga3 ~ student_t(3,0,1);
    logr1 ~ student_t(3,0,1);
    logr2 ~ student_t(3,0,1);
    logr3 ~ student_t(3,0,1);
    logr4 ~ student_t(3,0,1);
    logr5 ~ student_t(3,0,1);
    logsigma_sq ~ student_t(3,0,1);
    HR ~ normal(mu_HR,.25);
    R ~ normal(mu_R, .03);
}

generated quantities {
    vector[N2] Ypred;
    Ypred = post_pred_rng(a1, a2, a3, r1, r2, r3, r4, r5, HR, R, sigma_sq, N1, X, N2, Xp, Y);
}
函数{
//模型主要部分的协方差函数
矩阵主单元(
int Nx,
向量x,
国际纽约,
向量y,
真字母1,
真字母2,
真字母3,
真正的rho1,
真rho2,
真正的rho3,
真rho4,
真正的rho5,
真正的人力资源,
真实R\u f){
矩阵[Nx,Ny]K1;
矩阵[Nx,Ny]K2;
矩阵[Nx,Ny]K3;
矩阵[Nx,Ny]Sigma;
//指定控制协方差矩阵的随机高斯过程
对于(1:Nx中的i){
对于(1:Ny中的j){
K1[i,j]=alpha1*exp(-square(x[i]-y[j])/2/square(rho1));
}
}
//指定随机高斯过程包含心率
对于(1:Nx中的i){
对于(1:Ny中的j){
K2[i,j]=alpha2*exp(-2*square(sin(pi()*fabs(x[i]-y[j])*HR\u f))/square(rho2))*
exp(-square(x[i]-y[j])/2/square(rho3));
}
}
//指定随机高斯过程将心率作为呼吸的函数
对于(1:Nx中的i){
对于(1:Ny中的j){
K3[i,j]=alpha3*exp(-2*square(sin(pi()*fabs(x[i]-y[j])*HR\u f))/square(rho4))*
exp(-2*square(sin(pi()*fabs(x[i]-y[j])*R_f))/square(rho5));
}
}
σ=K1+K2+K3;
返回西格玛;
}
//后验计算函数
矢量post\u pred\u rng(
真正的a1,
真正的a2,
真正的a3,
真正的r1,
真正的r2,
真正的r3,
真正的r4,
RealR5,
真正的人力资源,
真正的R,
真正的sn,
int No,
向量xo,
int-Np,
向量xp,
向量(yobs){
矩阵[No,No]Ko;
矩阵[Np,Np]Kp;
矩阵[No,Np]Kop;
矩阵[Np,No]KOU inv;
向量[Np]μp;
矩阵[Np,Np]Tau;
矩阵[Np,Np]L2;
向量[Np]yp;
//--------------------------------------------------------------------
//观测数据的核多GPs
Ko=主总成(否、xo、否、xo、a1、a2、a3、r1、r2、r3、r4、r5、HR、R);
Ko=Ko+diag_矩阵(rep_向量(1,No))*sn;
//--------------------------------------------------------------------
//预测数据核
Kp=主要总成(Np、xp、Np、xp、a1、a2、a3、r1、r2、r3、r4、r5、HR、R);
Kp=Kp+diag_矩阵(rep_向量(1,Np))*sn;
//--------------------------------------------------------------------
//观测和预测交叉的核
Kop=主总成(否、xo、Np、xp、a1、a2、a3、r1、r2、r3、r4、r5、HR、R);
//--------------------------------------------------------------------
//拉斯穆森和威廉姆斯的算法2.1。。。
Ko_inv_t=Kop'/Ko;
mu_p=Ko_inv_t*yobs;
Tau=Kp-Ko_inv_t*Kop;
L2=cholesky_分解(τ);
yp=mu_p+L2*rep_向量(正态(0,1),Np);
返回yp;
}
}
数据{
int-N1;
int N2;
向量[N1]X;
向量[N1]Y;
向量[N2]Xp;
真正的穆尔;
真正的穆尔;
}
转换数据{
载体[N1]mu;
对于(1:N1中的n)μ[n]=0;
}
参数{
真实loga1;
真实loga2;
真实loga3;
真实logr1;
真实logr2;
实数logr3;
真实logr4;
实数logr5;
真实人力资源;
实R;
实对数平方;
}
变换参数{
实a1=exp(loga1);
实a2=exp(loga2);
实际a3=exp(loga3);
实际r1=exp(logr1);
实际r2=exp(logr2);
实际r3=exp(logr3);
实际r4=exp(logr4);
实数r5=exp(logr5);
实西格玛平方=exp(对数西格玛平方);
}
模型{
矩阵[N1,N1]西格玛;
矩阵[N1,N1]ls;
//从上面使用GP函数
Sigma=主要_GP(N1,X,N1,X,a1,a2,a3,r1,r2,r3,r4,r5,HR,R);
西格玛=西格玛+诊断矩阵(代表向量(1,N1))*西格玛平方;
L_S=cholesky_分解(西格玛);
Y~多正规cholesky(mu,L_-S);
//参数先验
loga1~学生t(3,0,1);
loga2~学生t(3,0,1);
loga3~学生t(3,0,1);
logr1~学生t(3,0,1);
logr2~学生t(3,0,1);
logr3~学生t(3,0,1);
logr4~学生t(3,0,1);
logr5~学生t(3,0,1);
logsigma_sq~student_t(3,0,1);
HR~正常(μu-HR,.25);
R~正常(mu_R,.03);
}
生成量{
向量[N2]Ypred;
Ypred=事后预测(a1、a2、a3、r1、r2、r3、r4、r5、HR、R、西格玛平方、N1、X、N2、Xp、Y);
}
我已经修改了内核中包含的参数的优先级,有些参数化速度要快一点(在某些情况下快两倍,但即使在这些情况下,仍然可以生成相对较慢的链)

我试图使用污染段前后15秒的数据(以3.33 Hz的频率采样,共100个数据点)预测3.5秒数据值(以10 Hz的频率采样,共35个数据点)

R中规定的型号如下:

 fit.pred2 <- stan(file = 'Fast_GP6_all.stan',
                 data = dat, 
                 warmup = 1000,
                 iter = 1500,
                 refresh=5,
                 chains = 3,
                 pars= pars.to.monitor
                 )

fit.pred2您可以获取斯坦数学库的开发分支,该库最近更新了