【问题标题】:Fitting a sine wave with Keras and PYMC3 yields unexpected results用 Keras 和 PYMC3 拟合正弦波会产生意想不到的结果
【发布时间】:2017-05-01 14:24:52
【问题描述】:

我一直在尝试使用 pymc3 用 keras(theano 后端)模型拟合正弦曲线。我一直使用这个 [http://twiecki.github.io/blog/2016/07/05/bayesian-deep-learning/] 作为参考点。

单独使用优化的 Keras 实现效果很好,但是来自 pymc3 的 Hamiltonian Monte Carlo 和变分采样不适合数据。跟踪卡在启动先验的位置。当我移动前面时,后面移动到同一个位置。单元格 59 中的贝叶斯模型的后验预测几乎没有得到正弦波,而非贝叶斯拟合模型在单元格 63 中得到了接近完美的结果。我在这里创建了一个笔记本:https://gist.github.com/tomc4yt/d2fb694247984b1f8e89cfd80aff8706,其中显示了代码和结果。

这是下面模型的sn-p...

class GaussWeights(object):
    def __init__(self):
        self.count = 0

    def __call__(self, shape, name='w'):
        return pm.Normal(
            name, mu=0, sd=.1,
            testval=np.random.normal(size=shape).astype(np.float32),
            shape=shape)


def build_ann(x, y, init):
    with pm.Model() as m:

        i = Input(tensor=x, shape=x.get_value().shape[1:])
        m = i
        m = Dense(4, init=init, activation='tanh')(m)
        m = Dense(1, init=init, activation='tanh')(m)

        sigma = pm.Normal('sigma', 0, 1, transform=None)
        out = pm.Normal('out', 
                         m, 1,
                         observed=y, transform=None)

    return out



 with pm.Model() as neural_network:
    likelihood = build_ann(input_var, target_var, GaussWeights())

#     v_params = pm.variational.advi(
#         n=300, learning_rate=.4
#     )
#     trace = pm.variational.sample_vp(v_params, draws=2000)
    start = pm.find_MAP(fmin=scipy.optimize.fmin_powell)
    step = pm.HamiltonianMC(scaling=start)
    trace = pm.sample(1000, step,   progressbar=True)

【问题讨论】:

  • 您能否更具体地说明您认为哪里出了问题?乍一看,在我看来,这两种模式都有一些问题,但其他方面都很好。 (另外,你定义了sigma,但不要在任何地方使用它......)
  • @aseyboldt 我更新了这个问题。主要问题是跟踪卡在先前启动的位置,请查看跟踪图。当我移动前面时,后面移动到同一个位置。单元格 59 中的贝叶斯模型的后验预测几乎没有得到正弦波,而非贝叶斯拟合模型在单元格 63 中得到了接近完美的结果。未使用 sigma 但不应该成为问题。
  • 您的模型表明您的测量值遵循标准值 = 1 的网络输出周围的正态分布。然后,您从预测后验中对每个 x 值采样 100 个值并取它们的中值。对于每个 x 值,这些样本的方差为 1 + 后验方差。它们的中位数自然仍然围绕网络的输出变化。在我看来,模型正在做你告诉它做的事情。
  • @aseyboldt。我只是告诉它之前的......这就是它正在做的事情(正如你所指出的那样)。然而,关键部分是它没有正确地从可能性中采样。如果模型真正受到数据的影响,那么中位数将与单元格 63 中的正弦曲线匹配,并且 sigma 不应像现在那样大。还请看一下 58 单元格……迹线清楚地表明,参数的后验模拟了先验接近完美。

标签: neural-network keras theano pymc pymc3


【解决方案1】:

模型包含固定标准为 1 的正常噪声:

out = pm.Normal('out', m, 1, observed=y)

但数据集没有。预测后验与数据集不匹配是很自然的,它们是以非常不同的方式生成的。为了使其更真实,您可以向数据集添加噪声,然后估计 sigma:

mu = pm.Deterministic('mu', m)
sigma = pm.HalfCauchy('sigma', beta=1)
pm.Normal('y', mu=mu, sd=sigma, observed=y)

您现在所做的类似于从网络中获取输出并添加标准正常噪声。

几个不相关的cmets:

  • out 不是可能性,它只是数据集。
  • 如果你使用HamiltonianMC而不是NUTS,你需要自己设置步长和积分时间。默认值通常没有用。
  • 似乎 keras 在 2.0 中发生了变化,这种结合 pymc3 和 keras 的方式似乎不再起作用了。

【讨论】:

  • 虽然这不是有效的解决方案,但您确实确定标准偏差是技术上正确的问题,所以我会接受这一点。我的先验是围绕权重指定的很差,当我根据 Radford M Neal 在这方面的工作放置适当的超先验时,我看到了更好的结果。特别是,我的先验限制了搜索空间,我需要扩大权重的标准开发
猜你喜欢
  • 2019-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-19
  • 2021-10-04
  • 2012-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多