Skip to content

Commit b499c73

Browse files
authored
Merge pull request #3600 from aloctavodia/smc_lh
reduce number of logp evaluations
2 parents 879cb49 + fd5a2bb commit b499c73

File tree

3 files changed

+15
-9
lines changed

3 files changed

+15
-9
lines changed

RELEASE-NOTES.md

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
- SMC: stabilize covariance matrix [3573](https://github.com/pymc-devs/pymc3/pull/3573)
1919
- SMC is no longer a step method of `pm.sample` now it should be called using `pm.sample_smc` [3579](https://github.com/pymc-devs/pymc3/pull/3579)
2020
- SMC: improve computation of the proposal scaling factor [3594](https://github.com/pymc-devs/pymc3/pull/3594)
21+
- SMC: reduce number of logp evaluations [3600](https://github.com/pymc-devs/pymc3/pull/3600)
2122
- Now uses `multiprocessong` rather than `psutil` to count CPUs, which results in reliable core counts on Chromebooks.
2223
- `sample_posterior_predictive` now preallocates the memory required for its output to improve memory usage. Addresses problems raised in this [discourse thread](https://discourse.pymc.io/t/memory-error-with-posterior-predictive-sample/2891/4).
2324
- Fixed a bug in `Categorical.logp`. In the case of multidimensional `p`'s, the indexing was done wrong leading to incorrectly shaped tensors that consumed `O(n**2)` memory instead of `O(n)`. This fixes issue [#3535](https://github.com/pymc-devs/pymc3/issues/3535)

pymc3/smc/smc.py

+11-8
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,12 @@ def sample_smc(
191191

192192
if parallel and cores > 1:
193193
pool = mp.Pool(processes=cores)
194+
results = pool.starmap(likelihood_logp, [(sample,) for sample in posterior])
195+
else:
196+
results = [likelihood_logp(sample) for sample in posterior]
197+
likelihoods = np.array(results).squeeze()
194198

195199
while beta < 1:
196-
if parallel and cores > 1:
197-
results = pool.starmap(likelihood_logp, [(sample,) for sample in posterior])
198-
else:
199-
results = [likelihood_logp(sample) for sample in posterior]
200-
likelihoods = np.array(results).squeeze()
201200
beta, old_beta, weights, sj = calc_beta(beta, likelihoods, threshold)
202201

203202
model.marginal_likelihood *= sj
@@ -238,16 +237,20 @@ def sample_smc(
238237
if parallel and cores > 1:
239238
results = pool.starmap(
240239
metrop_kernel,
241-
[(posterior[draw], tempered_logp[draw], *parameters) for draw in range(draws)],
240+
[
241+
(posterior[draw], tempered_logp[draw], likelihoods[draw], *parameters)
242+
for draw in range(draws)
243+
],
242244
)
243245
else:
244246
results = [
245-
metrop_kernel(posterior[draw], tempered_logp[draw], *parameters)
247+
metrop_kernel(posterior[draw], tempered_logp[draw], likelihoods[draw], *parameters)
246248
for draw in tqdm(range(draws), disable=not progressbar)
247249
]
248250

249-
posterior, acc_list = zip(*results)
251+
posterior, acc_list, likelihoods = zip(*results)
250252
posterior = np.array(posterior)
253+
likelihoods = np.array(likelihoods)
251254
acc_rate = sum(acc_list) / proposed
252255
stage += 1
253256

pymc3/smc/smc_utils.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ def _posterior_to_trace(posterior, variables, model, var_info):
110110
def metrop_kernel(
111111
q_old,
112112
old_tempered_logp,
113+
old_likelihood,
113114
proposal,
114115
scaling,
115116
accepted,
@@ -147,9 +148,10 @@ def metrop_kernel(
147148
q_old, accept = metrop_select(new_tempered_logp - old_tempered_logp, q_new, q_old)
148149
if accept:
149150
accepted += 1
151+
old_likelihood = ll
150152
old_tempered_logp = new_tempered_logp
151153

152-
return q_old, accepted
154+
return q_old, accepted, old_likelihood
153155

154156

155157
def calc_beta(beta, likelihoods, threshold=0.5, psis=True):

0 commit comments

Comments
 (0)