Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
probml
GitHub Repository: probml/pyprobml
Path: blob/master/deprecated/scripts/ais_demo.py
1192 views
1
# https://agustinus.kristia.de/techblog/2017/12/23/annealed-importance-sampling/
2
import numpy as np
3
import scipy.stats as st
4
import matplotlib.pyplot as plt
5
6
7
def f_0(x):
8
"""
9
Target distribution: \propto N(-5, 2)
10
"""
11
return np.exp(-(x+5)**2/2/2)
12
13
def f_j(x, beta):
14
"""
15
Intermediate distribution: interpolation between f_0 and f_n
16
"""
17
return f_0(x)**beta * f_n(x)**(1-beta)
18
19
20
# Proposal distribution: 1/Z * f_n
21
p_n = st.norm(0, 1)
22
23
def T(x, f, n_steps=10):
24
"""
25
Transition distribution: T(x'|x) using n-steps Metropolis sampler
26
"""
27
for t in range(n_steps):
28
# Proposal
29
x_prime = x + np.random.randn()
30
31
# Acceptance prob
32
a = f(x_prime) / f(x)
33
34
if np.random.rand() < a:
35
x = x_prime
36
37
return x
38
39
x = np.arange(-10, 5, 0.1)
40
41
n_inter = 50 # num of intermediate dists
42
betas = np.linspace(0, 1, n_inter)
43
44
# Sampling
45
n_samples = 100
46
samples = np.zeros(n_samples)
47
weights = np.zeros(n_samples)
48
49
for t in range(n_samples):
50
# Sample initial point from q(x)
51
x = p_n.rvs()
52
w = 1
53
54
for n in range(1, len(betas)):
55
# Transition
56
x = T(x, lambda x: f_j(x, betas[n]), n_steps=5)
57
58
# Compute weight in log space (log-sum):
59
# w *= f_{n-1}(x_{n-1}) / f_n(x_{n-1})
60
w += np.log(f_j(x, betas[n])) - np.log(f_j(x, betas[n-1]))
61
62
samples[t] = x
63
weights[t] = np.exp(w) # Transform back using exp
64
65
# Compute expectation
66
a = 1/np.sum(weights) * np.sum(weights * samples)
67
68