npr.seed(0) import matplotlib import matplotlib.pyplot as plt from ssm.models import HMM # Set the parameters of the HMM T = 500 # number of time bins K = 5 # number of discrete states D = 2 # number of observed dimensions # Make an HMM with the true parameters true_hmm = HMM(K, D, observations="gaussian") z, y = true_hmm.sample(T) z_test, y_test = true_hmm.sample(T) true_ll = true_hmm.log_probability(y) # Fit models N_sgd_iters = 1000 N_em_iters = 100 print("Fitting HMM with SGD") hmm = HMM(K, D, observations="gaussian") hmm_sgd_lls = hmm.fit(y, method="sgd", num_iters=N_sgd_iters) hmm_sgd_test_ll = hmm.log_probability(y_test) hmm_sgd_smooth = hmm.smooth(y) print("Fitting HMM with EM") hmm = HMM(K, D, observations="gaussian")
def test_sample(T=10, K=4, D=3, M=2): """ Test that we can construct and sample an HMM with or withou, prefixes, noise, and noise. """ transition_names = [ "standard", "sticky", "inputdriven", "recurrent", "recurrent_only", "rbf_recurrent", "nn_recurrent" ] observation_names = [ "gaussian", "diagonal_gaussian", "t", "diagonal_t", "bernoulli", "categorical", "poisson", "vonmises", "ar", "diagonal_ar", "independent_ar", "robust_ar", "diagonal_robust_ar" ] # Sample basic (no prefix, inputs, etc.) for transitions in transition_names: for observations in observation_names: hmm = HMM(K, D, M=0, transitions=transitions, observations=observations) zsmpl, xsmpl = hmm.sample(T) # Sample with prefix for transitions in transition_names: for observations in observation_names: hmm = HMM(K, D, M=0, transitions=transitions, observations=observations) zpre, xpre = hmm.sample(3) zsmpl, xsmpl = hmm.sample(T, prefix=(zpre, xpre)) # Sample with inputs for transitions in transition_names: for observations in observation_names: hmm = HMM(K, D, M=M, transitions=transitions, observations=observations) zpre, xpre = hmm.sample(3, input=npr.randn(3, M)) zsmpl, xsmpl = hmm.sample(T, prefix=(zpre, xpre), input=npr.randn(T, M)) # Sample without noise for transitions in transition_names: for observations in observation_names: hmm = HMM(K, D, M=M, transitions=transitions, observations=observations) zpre, xpre = hmm.sample(3, input=npr.randn(3, M)) zsmpl, xsmpl = hmm.sample(T, prefix=(zpre, xpre), input=npr.randn(T, M), with_noise=False)
T = 200 # number of time bins K = 5 # number of discrete states D = 2 # data dimension # Make an HMM true_hmm = HMM(K, D, observations="gaussian") # Manually tweak the means to make them farther apart thetas = np.linspace(0, 2 * np.pi, K, endpoint=False) true_hmm.observations.mus = 3 * np.column_stack( (np.cos(thetas), np.sin(thetas))) # In[3]: # Sample some data from the HMM z, y = true_hmm.sample(T) true_ll = true_hmm.log_probability(y) # In[4]: # Plot the observation distributions lim = .85 * abs(y).max() XX, YY = np.meshgrid(np.linspace(-lim, lim, 100), np.linspace(-lim, lim, 100)) data = np.column_stack((XX.ravel(), YY.ravel())) input = np.zeros((data.shape[0], 0)) mask = np.ones_like(data, dtype=bool) tag = None lls = true_hmm.observations.log_likelihoods(data, input, mask, tag) # In[36]:
plt.plot(x[z == k, 0], x[z == k, 1], 'o', mfc=colors[k], mec='none', ms=4) plt.plot(x[:, 0], x[:, 1], '-k', lw=2, alpha=.5) plt.xlabel("$x_1$") plt.ylabel("$x_2$") plt.title("Observation Distributions") plt.tight_layout() if save_figures: plt.savefig("lds_3.pdf") # In[16]: # Simulate from the HMM fit smpls = [hmm.sample(T - 1, prefix=(z[:1], x[:1])) for _ in range(1)] # In[17]: plt.figure(figsize=(8, 6)) lim = abs(x).max() for d in range(D): plt.plot(x[:, d] - d * lim, '-k', lw=4) for i, (_, x_smpl) in enumerate(smpls): x_smpl = np.concatenate((x[:1], x_smpl)) plt.plot(x_smpl[:, d] - d * lim, '-', lw=1, color=colors[i]) plt.yticks(-np.arange(D) * lim, ["$x_{}$".format(d + 1) for d in range(D)]) plt.xlabel("time") plt.xlim(0, T) plt.title("True LDS States and Fitted HMM Simulations")
M = 1 # input dimension C = 3 # number of output types/categories # Make an HMM true_hmm = HMM(K, D, M, observations="categorical", observation_kwargs=dict(C=C), transitions="inputdriven") # Optionally, turn up the input weights to exaggerate the effect # true_hmm.transitions.Ws *= 3 # Create an exogenous input inpt = np.sin(2 * np.pi * np.arange(T) / 50)[:, None] + 1e-1 * npr.randn(T, M) # Sample some data from the HMM z, y = true_hmm.sample(T, input=inpt) # Compute the true log probability of the data, summing out the discrete states true_lp = true_hmm.log_probability(y, inputs=inpt) # In[3]: # Plot the data plt.figure(figsize=(8, 5)) plt.subplot(311) plt.plot(inpt) plt.xticks([]) plt.xlim(0, T)
mog.fit(x) # In[8]: plt.plot(x[:, 0], x[:, 1]) for mu in mog.observations.mus: plt.plot(mu[0], mu[1], 'o') # In[9]: arhmm = HMM(K=8, D=D, observations="ar") arhmm.fit(x) # In[10]: z_smpl, x_smpl = arhmm.sample(T=3000) plt.plot(x_smpl[:, 0], x_smpl[:, 1]) # In[11]: def sample(T=3000, num_samples=25, num_burnin=100, schedule=None, filename="samples.mp4"): print("Running Gibbs sampler") z_smpls, x_smpls, i_smpls = gibbs_sample_constrained_arhmm( T, arhmm,