无掉头采样器 (NUTS) 的 PyMC3 性能问题:简单模型每秒少于 2 次迭代

PyMC3 performance issues with No U-Turn Sampler (NUTS): less than 2 iterations per second with simple model

我试图了解以下代码的问题所在:

import pymc3 as pm
import theano as t

X = t.shared(train_new)
features = list(map(str, range(train_new.shape[1])))
with pm.Model() as logistic_model:
    glm = pm.glm.GLM(X, targets, labels=features,
                     intercept=False, family='binomial')
    trace = pm.sample(3000, tune=3000, jobs=-1)

数据集绝不大:它的形状是 (891, 13)。这是我自己得出的结论:

它从 200 it/s 左右开始,然后迅速下降到 5 it/s。采样一半后,进一步下降到2 it/s左右。这是一个严重的问题,因为该模型几乎无法收敛几千个样本。我需要执行比当前情况允许的更多的示例。

这是日志:

Auto-assigning NUTS sampler...
Initializing NUTS using jitter+adapt_diag...
 99%|█████████▊| 5923/6000 [50:00<00:39,  1.97it/s]

我试过用pm.Metropolis()作为步长,速度快了一点,但没有收敛。

MWE:一个包含显示问题的最小工作示例的文件,数据在此处: https://gist.github.com/rubik/74ddad91317b4d366d3879e031e03396

模型的非居中版本应该工作得更好:

β_raw = pm.Normal('β_raw', 0, sd=1, shape=X.get_value().shape[1])
β = pm.Deterministic('β', β_raw * σ)

通常情况下,如果有效样本量较小,您的第一个冲动不应该只是增加样本数量,而是尝试稍微调整一下参数化。

此外,您可以使用 tt.nnet.sigmoid 而不是自定义 invlogit,这可能 faster/more 稳定。