16
16
import sys
17
17
sys .setrecursionlimit (10000 )
18
18
19
- __all__ = ['sample' , 'iter_sample' , 'sample_ppc' , 'sample_init ' ]
19
+ __all__ = ['sample' , 'iter_sample' , 'sample_ppc' , 'init_nuts ' ]
20
20
21
21
22
22
def assign_step_methods (model , step = None , methods = (NUTS , HamiltonianMC , Metropolis ,
@@ -81,8 +81,9 @@ def assign_step_methods(model, step=None, methods=(NUTS, HamiltonianMC, Metropol
81
81
return steps
82
82
83
83
84
- def sample (draws , step = None , start = None , trace = None , chain = 0 , njobs = 1 , tune = None ,
85
- progressbar = True , model = None , random_seed = - 1 ):
84
+ def sample (draws , step = None , init = 'advi' , n_init = 500000 , start = None ,
85
+ trace = None , chain = 0 , njobs = 1 , tune = None , progressbar = True ,
86
+ model = None , random_seed = - 1 ):
86
87
"""
87
88
Draw a number of samples using the given step method.
88
89
Multiple step methods supported via compound step method
@@ -97,6 +98,15 @@ def sample(draws, step=None, start=None, trace=None, chain=0, njobs=1, tune=None
97
98
A step function or collection of functions. If no step methods are
98
99
specified, or are partially specified, they will be assigned
99
100
automatically (defaults to None).
101
+ init : str {'advi', 'advi_map', 'map', 'nuts'}
102
+ Initialization method to use.
103
+ * advi : Run ADVI to estimate posterior mean and diagonal covariance matrix.
104
+ * advi_map: Initialize ADVI with MAP and use MAP as starting point.
105
+ * map : Use the MAP as starting point.
106
+ * nuts : Run NUTS and estimate posterior mean and covariance matrix.
107
+ n_init : int
108
+ Number of iterations of initializer
109
+ If 'advi', number of iterations, if 'nuts', number of draws.
100
110
start : dict
101
111
Starting point in parameter space (or partial point)
102
112
Defaults to trace.point(-1)) if there is a trace provided and
@@ -132,7 +142,14 @@ def sample(draws, step=None, start=None, trace=None, chain=0, njobs=1, tune=None
132
142
"""
133
143
model = modelcontext (model )
134
144
135
- step = assign_step_methods (model , step )
145
+ if step is None and init is not None and pm .model .all_continuous (model .vars ):
146
+ # By default, use NUTS sampler
147
+ pm ._log .info ('Auto-assigning NUTS sampler...' )
148
+ start_ , step = init_nuts (init = init , n_init = n_init , model = model )
149
+ if start is None :
150
+ start = start_
151
+ else :
152
+ step = assign_step_methods (model , step )
136
153
137
154
if njobs is None :
138
155
import multiprocessing as mp
@@ -375,19 +392,16 @@ def sample_ppc(trace, samples=None, model=None, vars=None, size=None, random_see
375
392
return {k : np .asarray (v ) for k , v in ppc .items ()}
376
393
377
394
378
- def sample_init (draws = 2000 , init = 'advi' , n_init = 500000 , sampler = 'nuts' ,
379
- model = None , ** kwargs ):
395
+ def init_nuts (init = 'advi' , n_init = 500000 , model = None ):
380
396
"""Initialize and sample from posterior of a continuous model.
381
397
382
398
This is a convenience function. NUTS convergence and sampling speed is extremely
383
399
dependent on the choice of mass/scaling matrix. In our experience, using ADVI
384
400
to estimate a diagonal covariance matrix and using this as the scaling matrix
385
401
produces robust results over a wide class of continuous models.
386
402
387
- Parameteres
388
- -----------
389
- draws : int
390
- Number of posterior samples to draw.
403
+ Parameters
404
+ ----------
391
405
init : str {'advi', 'advi_map', 'map', 'nuts'}
392
406
Initialization method to use.
393
407
* advi : Run ADVI to estimate posterior mean and diagonal covariance matrix.
@@ -397,21 +411,21 @@ def sample_init(draws=2000, init='advi', n_init=500000, sampler='nuts',
397
411
n_init : int
398
412
Number of iterations of initializer
399
413
If 'advi', number of iterations, if 'metropolis', number of draws.
400
- sampler : str {'nuts', 'hmc', advi'}
401
- Sampler to use. Will be initialized using init algorithm.
402
- * nuts : Run NUTS sampler with the init covariance estimation as the scaling matrix.
403
- * hmc : Run HamiltonianMC sampler with the init covariance estimation as the scaling matrix.
404
- * advi : Sample from variational posterior, requires init='advi'.
405
- **kwargs : additional keyword argumemts
406
- Additional keyword argumemts are forwared to pymc3.sample()
414
+ model : Model (optional if in `with` context)
407
415
408
416
Returns
409
417
-------
410
- MultiTrace object with access to sampling values
418
+ start, nuts_sampler
419
+
420
+ start : pymc3.model.Point
421
+ Starting point for sampler
422
+ nuts_sampler : pymc3.step_methods.NUTS
423
+ Instantiated and initialized NUTS sampler object
411
424
"""
412
425
413
426
model = pm .modelcontext (model )
414
- pm ._log .info ('Initializing using {}...' .format (init ))
427
+
428
+ pm ._log .info ('Initializing NUTS using {}...' .format (init ))
415
429
416
430
if init == 'advi' :
417
431
v_params = pm .variational .advi (n = n_init )
@@ -433,19 +447,6 @@ def sample_init(draws=2000, init='advi', n_init=500000, sampler='nuts',
433
447
else :
434
448
raise NotImplemented ('Initializer {} is not supported.' .format (init ))
435
449
436
- pm ._log .info ('Sampling using {}...' .format (sampler ))
437
- if sampler == 'nuts' :
438
- step = pm .NUTS (scaling = cov , is_cov = True )
439
- elif sampler == 'hmc' :
440
- step = pm .HamiltonianMC (scaling = cov , is_cov = True )
441
- elif sampler != 'advi' :
442
- raise NotImplemented ('Sampler {} is not supported.' .format (init ))
443
-
444
- if sampler == 'advi' :
445
- if init != 'advi' :
446
- raise ValueError ("To sample via ADVI, you have to set init='advi'." )
447
- trace = pm .variational .sample_vp (v_params , draws = draws )
448
- else :
449
- trace = pm .sample (step = step , start = start , draws = draws , ** kwargs )
450
+ step = pm .NUTS (scaling = cov , is_cov = True )
450
451
451
- return trace
452
+ return start , step
0 commit comments