我的最初工作只是试图为卷积信号和滤波器推断适当的缩放比例,但显示出太多的噪声和较低的缩放比例值。标尺参数的推断可以进行线性回归。
嗨!我是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!
如果我使用与“观察到的”相同的比例线性回归算法,则此方法会返回非常精确的值。
很明显,我缺少了一些东西,但我不知道该看哪里。