@@ -327,16 +327,20 @@ class MaxVar(AcquisitionBase):
327
327
328
328
"""
329
329
330
- def __init__ (self , quantile_eps = .01 , * args , ** opts ):
330
+ def __init__ (self , model , prior , quantile_eps = .01 , ** opts ):
331
331
"""Initialise MaxVar.
332
332
333
333
Parameters
334
334
----------
335
+ model : elfi.GPyRegression
336
+ Gaussian process model used to calculate the unnormalised approximate likelihood.
337
+ prior : scipy-like distribution
338
+ Prior distribution.
335
339
quantile_eps : int, optional
336
340
Quantile of the observed discrepancies used in setting the ABC threshold.
337
341
338
342
"""
339
- super (MaxVar , self ).__init__ (* args , ** opts )
343
+ super (MaxVar , self ).__init__ (model , prior = prior , ** opts )
340
344
self .name = 'max_var'
341
345
self .label_fn = 'Variance of the Unnormalised Approximate Posterior'
342
346
self .quantile_eps = quantile_eps
@@ -492,30 +496,41 @@ class RandMaxVar(MaxVar):
492
496
493
497
"""
494
498
495
- def __init__ (self , quantile_eps = .01 , sampler = 'nuts' , n_samples = 50 ,
496
- limit_faulty_init = 10 , sigma_proposals = None , * args , ** opts ):
499
+ def __init__ (self , model , prior , quantile_eps = .01 , sampler = 'nuts' , n_samples = 50 , warmup = None ,
500
+ limit_faulty_init = 1000 , init_from_prior = False , sigma_proposals = None , ** opts ):
497
501
"""Initialise RandMaxVar.
498
502
499
503
Parameters
500
504
----------
505
+ model : elfi.GPyRegression
506
+ Gaussian process model used to calculate the unnormalised approximate likelihood.
507
+ prior : scipy-like distribution
508
+ Prior distribution.
501
509
quantile_eps : int, optional
502
510
Quantile of the observed discrepancies used in setting the ABC threshold.
503
511
sampler : string, optional
504
512
Name of the sampler (options: metropolis, nuts).
505
513
n_samples : int, optional
506
514
Length of the sampler's chain for obtaining the acquisitions.
515
+ warmup : int, optional
516
+ Number of samples discarded as warmup. Defaults to n_samples/2.
507
517
limit_faulty_init : int, optional
508
518
Limit for the iterations used to obtain the sampler's initial points.
519
+ init_from_prior : bool, optional
520
+ Controls whether the sampler's initial points are sampled from the prior or
521
+ a uniform distribution within model bounds. Defaults to model bounds.
509
522
sigma_proposals : dict, optional
510
523
Standard deviations for Gaussian proposals of each parameter for Metropolis
511
524
Markov Chain sampler. Defaults to 1/10 of surrogate model bound lengths.
512
525
513
526
"""
514
- super (RandMaxVar , self ).__init__ (quantile_eps , * args , ** opts )
527
+ super (RandMaxVar , self ).__init__ (model , prior , quantile_eps , ** opts )
515
528
self .name = 'rand_max_var'
516
529
self .name_sampler = sampler
517
530
self ._n_samples = n_samples
531
+ self ._warmup = warmup or n_samples // 2
518
532
self ._limit_faulty_init = limit_faulty_init
533
+ self ._init_from_prior = init_from_prior
519
534
if self .name_sampler == 'metropolis' :
520
535
self ._sigma_proposals = resolve_sigmas (self .model .parameter_names ,
521
536
sigma_proposals ,
@@ -538,8 +553,8 @@ def acquire(self, n, t=None):
538
553
539
554
"""
540
555
if n > self ._n_samples :
541
- raise ValueError (("The number of acquisitions ({0}) has to be lower "
542
- "than the number of the samples ({1})." ).format (n , self ._n_samples ))
556
+ raise ValueError (("The number of acquisitions ({0}) has to be lower than the number "
557
+ "of the samples ({1})." ).format (n , self ._n_samples - self . _warmup ))
543
558
544
559
logger .debug ('Acquiring the next batch of %d values' , n )
545
560
gp = self .model
@@ -568,9 +583,15 @@ def _evaluate_logpdf(theta):
568
583
raise SystemExit ("Unable to find a suitable initial point." )
569
584
570
585
# Proposing the initial point.
571
- theta_init = np .zeros (shape = len (gp .bounds ))
572
- for idx_param , range_bound in enumerate (gp .bounds ):
573
- theta_init [idx_param ] = self .random_state .uniform (range_bound [0 ], range_bound [1 ])
586
+ if self ._init_from_prior :
587
+ theta_init = self .prior .rvs (random_state = self .random_state )
588
+ for idx_param , bound in enumerate (gp .bounds ):
589
+ theta_init [idx_param ] = np .clip (theta_init [idx_param ], bound [0 ], bound [1 ])
590
+
591
+ else :
592
+ theta_init = np .zeros (shape = len (gp .bounds ))
593
+ for idx_param , bound in enumerate (gp .bounds ):
594
+ theta_init [idx_param ] = self .random_state .uniform (bound [0 ], bound [1 ])
574
595
575
596
# Refusing to accept a faulty initial point.
576
597
if np .isinf (_evaluate_logpdf (theta_init )):
@@ -593,8 +614,13 @@ def _evaluate_logpdf(theta):
593
614
raise ValueError (
594
615
"Incompatible sampler. Please check the options in the documentation." )
595
616
596
- # Using the last n points of the MH chain for the acquisition batch.
597
- batch_theta = samples [- n :, :]
617
+ if n > 1 :
618
+ # Remove warmup samples and return n random points
619
+ samples = samples [self ._warmup :]
620
+ batch_theta = self .random_state .permutation (samples )[:n ]
621
+ else :
622
+ # Return the last point
623
+ batch_theta = samples [- 1 :]
598
624
break
599
625
600
626
return batch_theta
@@ -629,13 +655,17 @@ class ExpIntVar(MaxVar):
629
655
630
656
"""
631
657
632
- def __init__ (self , quantile_eps = .01 , integration = 'grid' , d_grid = .2 ,
658
+ def __init__ (self , model , prior , quantile_eps = .01 , integration = 'grid' , d_grid = .2 ,
633
659
n_samples_imp = 100 , iter_imp = 2 , sampler = 'nuts' , n_samples = 2000 ,
634
- sigma_proposals = None , * args , * *opts ):
660
+ sigma_proposals = None , ** opts ):
635
661
"""Initialise ExpIntVar.
636
662
637
663
Parameters
638
664
----------
665
+ model : elfi.GPyRegression
666
+ Gaussian process model used to calculate the approximate unnormalised likelihood.
667
+ prior : scipy-like distribution
668
+ Prior distribution.
639
669
quantile_eps : int, optional
640
670
Quantile of the observed discrepancies used in setting the discrepancy threshold.
641
671
integration : str, optional
@@ -661,7 +691,7 @@ def __init__(self, quantile_eps=.01, integration='grid', d_grid=.2,
661
691
Markov Chain sampler. Defaults to 1/10 of surrogate model bound lengths.
662
692
663
693
"""
664
- super (ExpIntVar , self ).__init__ (quantile_eps , * args , ** opts )
694
+ super (ExpIntVar , self ).__init__ (model , prior , quantile_eps , ** opts )
665
695
self .name = 'exp_int_var'
666
696
self .label_fn = 'Expected Loss'
667
697
self ._integration = integration
0 commit comments