PyMC3采样如何正确初始化参数 解决initvals不生效问题
初始值不生效的核心原因
pm.sample()默认的init参数为"auto",NUTS采样器默认会先跑ADVI变分推断自动计算起始点,你手动在分布里传的initval、在sample里传的initvals都会被这个自动初始化流程覆盖,根本不会作为采样起点使用。- 你贴出的代码里
initvals字典的定义行是被注释状态,如果运行时没取消注释,传入sample的是未定义变量,本身就不会生效。
修复方案
要强制使用自定义初始值,只需要关闭自动初始化流程即可,修正后的可运行代码如下:
import numpy as np import pytensor.tensor as at import pymc as pm with pm.Model() as model2: def likelihood(theta,E11,N11): Mix_p,alpha1,alpha2,beta1,beta2 = theta const1=np.log(at.gamma(alpha1+N11)) - np.log(at.gamma(alpha1)) - np.log(at.gamma(N11+1)) const2=np.log(at.gamma(alpha2+N11)) - np.log(at.gamma(alpha2)) - np.log(at.gamma(N11+1)) LogL1=const1 - N11*np.log(1+beta1/E11) - alpha1*np.log(1+E11/beta1) LogL2=const2 - N11*np.log(1+beta2/E11) - alpha2*np.log(1+E11/beta2) return(np.log(Mix_p*np.exp(LogL1) + (1-Mix_p)*np.exp(LogL2))) alpha1 = pm.Gamma('alpha1', alpha=1, beta=1, initval=0.2) beta1 = pm.Gamma('beta1', alpha=1, beta=1, initval=0.1) alpha2 = pm.Gamma('alpha2', alpha=1, beta=1, initval=2) beta2 = pm.Gamma('beta2', alpha=1, beta=1, initval=4) Mix_p =pm.Uniform('Mix_p',0,1,initval=0.333) theta = (Mix_p,alpha1,alpha2,beta1,beta2) like = pm.Potential('likelihood',likelihood(theta,E11,N11)) initvals = {'Mix_p': 0.333, 'alpha1':0.2,'alpha2': 2, 'beta1': 0.1, 'beta2': 4} with model2: # 核心参数:init="none" 跳过所有自动初始化,直接使用传入的初始值 # 如果你用PyMC3<4.0版本,把init="none"改成init=None即可 # 若需要保留采样器质量矩阵自适应但不替换初始点,可改用init="adapt_diag", jitter=False trace = pm.sample(chains=1, initvals=initvals, init="none", random_seed=42)
验证方法
采样完成后执行trace.point(0),返回的第一组采样值和你设置的initvals完全一致,就说明初始值已经生效。
注意不要使用init="advi"、init="jitter+adapt_diag"这类默认带变分优化、随机抖动的初始化选项,这类选项都会覆盖你传入的自定义初始值。
内容的提问来源于stack exchange,提问作者viham1
相关产品推荐
相关产品推荐

