PyMC3 / Theano中卷积的错误行为

时间:2019-02-06 22:11:09

标签: python theano bayesian pymc3

我的最初工作只是试图为卷积信号和滤波器推断适当的缩放比例,但显示出太多的噪声和较低的缩放比例值。标尺参数的推断可以进行线性回归。

嗨!我是python,PyMC3和常规贝叶斯分析的新手,所以我可能错过了一些基本问题,我将非常感谢您的帮助。我有一个电子系统,我正在尝试通过一个过滤器进行表征。输入信号与滤波器卷积以获得测量的输出。我有一个单独的手工分析可以得出结果,但结果并不令人满意,我想尝试贝叶斯方法。

我想确保在进一步潜水之前我已经了解了所涉及的不同步骤,因此我制作了一个虚拟测试用例。我创建了一个随输入信号卷积的任意滤波器函数。为了引入一些推断变量,我将结果乘以缩放参数,然后我的似然函数是关于卷积信号的正态分布,具有标准偏差,可以与观测值进行比较。自创建数据以来,我知道应该获得什么答案。我可以使用线性回归执行相同的过程,它可以正确获取噪声的正确缩放比例和标准偏差。

import numpy as np
import matplotlib.pyplot as plt
import pymc3 as pm
import pandas as pd
import theano.tensor as tt
import theano
import theano.tensor.signal.conv

#theano.config.compute_test_value = 'off'

#create source function
dtbase = 0.5e-9
tbase = np.arange(0, 1e-7, dtbase)

set1 = ((tbase > 5e-9) & (tbase < 45e-9))
sig1 = np.zeros((len(tbase),1))
sig1[set1,0] = 1

set2 = ((tbase > 5e-9) & (tbase < 8e-9))
sig2 = np.zeros((len(tbase),1))
sig2[set2,0] = 1

#define the time base of the transfer function
t2 = np.arange(0, 50e-9, dtbase)
hfunc = np.zeros((len(t2),1))

mu1 = 2e-9
sd1 = 0.5e-9
g1 = np.exp(-0.5*(t2 - mu1)**2/sd1**2)

RC1 = 2e-9
A1 = 1
mu2 = 2e-9
RC2 = 20e-9
A2 = 0.02

set3 = (t2 > mu2)
hfunc[set3,0]= A1*np.exp(-1*t2[set3]/RC1) + A2*np.exp(-1*t2[set3]/RC2)
hfunc2 = np.convolve(hfunc[:,0], g1)
hfunc2 = hfunc2[0:len(t2)]/np.trapz(hfunc2)

hproto = np.zeros((len(hfunc2),1))
hproto[:,0] = hfunc2
hfunc3 = hfunc2/(max(hfunc2))

#create the observed data arrays
obs1 = np.convolve(sig1[:,0], hfunc2)
obs1 = obs1[0:len(tbase)]
noiseAmp = np.random.normal(0, 0.005*max(obs1), len(tbase))
obs1 += noiseAmp

obs2 = np.convolve(sig2[:,0], hfunc2)
obs2 = obs2[0:len(tbase)]
noiseAmp2 = np.random.normal(0, 0.005*max(obs1), len(tbase))
obs2 += noiseAmp2



#define the theano convolution function
conv2d = tt.signal.conv.conv2d

x = tt.dmatrix('x')
x.tag.test_value = np.random.rand(5,1)

y = tt.dmatrix('y')
y.tag.test_value = np.random.rand(5,1)
veclen = x.shape[0]

conv1d_expr = conv2d(x, y, \
                 image_shape=(1, veclen), \
                 border_mode='full')

conv1d = theano.function([x, y], \
                     outputs=conv1d_expr)

#append the two signals to process at the same time
xapp = np.append(sig1, sig2)
obsapp = np.append(obs1, obs2)

basic_model = pm.Model()

with basic_model:

    scale = pm.Normal('scale', mu=0, sd = 5)

    Yobs_a = conv1d(sig1, hproto)
    Yobs_b = conv1d(sig2, hproto)

    #Yobs = (Yobs_a[0:len(sig1)])*(1-scale)
    Ydelta_a = Yobs_a[0:len(sig1)]*(1-scale)
    Ydelta_b = Yobs_b[0:len(sig2)]*(1-scale)

    #Ydelta = th_append(Ydelta_a, Ydelta_b)    
    Ydelta = tt.concatenate([Ydelta_a, Ydelta_b], axis=0)

    sigma = pm.HalfCauchy('sigma', 1)

    obs = pm.Normal('obs', mu=Ydelta, sd=sigma, observed=obsapp)

    trace = pm.sample(800, tune=800, cores=1, jobs=1, chains=2)

现在,如果我使用:

ppc = pm.sample_posterior_predictive(trace, samples=100, model=basic_model)

for i in range(100):
    plt.plot((ppc['obs'][i,:]), '-b', alpha=0.05)
    plt.plot(obsapp, '-r', linewidth=1)

我的后继者很吵,因为我的求解器返回的值是:

       mean   sd  mc_error  hpd_2.5  hpd_97.5    n_eff  Rhat
scale  0.72  0.0       0.0     0.72      0.73  1549.32   1.0
sigma  0.38  0.0       0.0     0.38      0.38  1641.81   1.0

而小数位数应为0,西格玛值应为0.005!

如果我使用与“观察到的”相同的比例线性回归算法,则此方法会返回非常精确的值。

很明显,我缺少了一些东西,但我不知道该看哪里。

0 个答案:

没有答案