vip_reparametrize#

pymc_extras.model.transforms.autoreparam.vip_reparametrize(model: Model, var_names: Sequence[str]) tuple[Model, VIP][source]#

使用变分信息参数化 (VIP) 重新参数化模型。

\[\begin{split}\begin{align*} \eta_{k} &\sim \text{normal}(\lambda_{k} \cdot \mu, \sigma^{\lambda_{k}})\\ \theta_{k} &= \mu + \sigma^{1 - \lambda_{k}} ( \eta_{k} - \lambda_{k} \cdot \mu) \sim \text{normal}(\mu, \sigma). \end{align*}\end{split}\]
参数:
  • model (Model) – 具有变量中心参数化的模型。

  • var_names (Sequence[str]) – 要重新参数化的目标变量。

返回:

更新后的模型和 VIP 助手,用于重新参数化或推断模型的参数化。

返回类型:

Tuple[Model, VIP]

示例

传统的八所学校。

import pymc as pm
import numpy as np

J = 8
y = np.array([28.0, 8.0, -3.0, 7.0, -1.0, 1.0, 18.0, 12.0])
sigma = np.array([15.0, 10.0, 16.0, 11.0, 9.0, 11.0, 10.0, 18.0])

with pm.Model() as Centered_eight:
    mu = pm.Normal("mu", mu=0, sigma=5)
    tau = pm.HalfCauchy("tau", beta=5)
    theta = pm.Normal("theta", mu=mu, sigma=tau, shape=J)
    obs = pm.Normal("obs", mu=theta, sigma=sigma, observed=y)

具有中心参数化的常规模型定义足以使用 VIP。要更改模型参数化,请使用以下函数。

from pymc_extras.model.transforms.autoreparam import vip_reparametrize
Reparam_eight, vip = vip_reparametrize(Centered_eight, ["theta"])

with Reparam_eight:
    # set all parameterizations to cenered (not needed)
    vip.set_all_lambda(1)

    # set all parameterizations to non-cenered (desired)
    vip.set_all_lambda(0)

    # or per variable
    vip.set_lambda(theta=0)

    # just set non-centered parameterization
    trace = pm.sample()

但是,手动设置并不总是很好的体验,我们可以学习它。

with Reparam_eight:
    # set all parameterizations to mix of centered and non-centered
    vip.set_all_lambda(0.5)

    # fit using ADVI
    mf = vip.fit(random_seed=42)

    # display lambdas
    print(vip.get_lambda())

    # {'theta': array([0.01473405, 0.02221006, 0.03656685, 0.03798879, 0.04876761,
    #    0.0300203 , 0.02733082, 0.01817754])}

现在你可以再次使用采样

with Reparam_eight:
    trace = pm.sample()

有时启用剪裁是有意义的(默认情况下是关闭的)。 想法是将 \(\varepsilon\) 四舍五入到最接近的极值 (\(0\)\(0\))

\[\begin{split}\hat \lambda_k = \begin{cases} 0, \quad &\lambda_k \le \varepsilon\\ \lambda_k, \quad &\varepsilon \lt \lambda_k \lt 1-\varepsilon\\ 1, \quad &\lambda_k \ge 1-\varepsilon \end{cases}\end{split}\]
vip.truncate_all_lambda(0.1)

必须再次执行采样

with Reparam_eight:
    trace = pm.sample()

参考文献

  • 概率程序的自动重新参数化,

    Maria I. Gorinova, Dave Moore, Matthew D. Hoffman (2019)