def simulate_prior(): # Account for stick breaking asymmetry mu_b, _ = compute_psi_cmoments(np.ones(K_true)) init_dynamics_distns = [ Gaussian(mu=np.array([-0, -0]), sigma=5 * np.eye(D_latent)) for _ in range(K) ] dynamics_distns = make_dynamics_distns() emission_distns = \ DiagonalRegression(D_obs, D_latent+1, alpha_0=2.0, beta_0=2.0) model = PGRecurrentSLDS(trans_params=dict(sigmasq_A=10., sigmasq_b=0.01), init_state_distn='uniform', init_dynamics_distns=init_dynamics_distns, dynamics_distns=dynamics_distns, emission_distns=emission_distns) # Print the true parameters np.set_printoptions(precision=2) print("True W_markov:\n{}".format(model.trans_distn.A[:, :K_true])) print("True W_input:\n{}".format(model.trans_distn.A[:, K_true:])) return model
def __init__(self, D_obs, D_latent, W=None, sigmasq=None, sigmasq_W_0=1.0, mu_W_0=0.0, alpha_0=3.0, beta_0=2.0): self.D_obs, self.D_latent = D_obs, D_latent # The weights and variances are encapsulated in a DiagonalRegression class self.regression = \ DiagonalRegression( self.D_obs, self.D_latent, mu_0=mu_W_0 * np.ones(self.D_latent), Sigma_0=sigmasq_W_0 * np.eye(self.D_latent), alpha_0=alpha_0, beta_0=beta_0, A=W, sigmasq=sigmasq) # Handle the mean separately since DiagonalRegression doesn't support affine :-/ self.mean = np.zeros(D_obs) self.data_list = []
def make_rslds_parameters(C_init): init_dynamics_distns = [ Gaussian( mu=np.zeros(D_latent), sigma=np.eye(D_latent), nu_0=D_latent + 2, sigma_0=3. * np.eye(D_latent), mu_0=np.zeros(D_latent), kappa_0=1.0, ) for _ in range(args.K)] dynamics_distns = [ Regression( nu_0=D_latent + 2, S_0=1e-4 * np.eye(D_latent), M_0=np.hstack((np.eye(D_latent), np.zeros((D_latent, 1)))), K_0=np.eye(D_latent + 1), ) for _ in range(args.K)] emission_distns = \ DiagonalRegression(args.D_obs, D_latent + 1, A=C_init.copy(), sigmasq=np.ones(args.D_obs), alpha_0=2.0, beta_0=2.0) return init_dynamics_distns, dynamics_distns, emission_distns
def sample_slds_model(): mu_init = np.zeros(D_latent) mu_init[0] = 2.0 sigma_init = 0.01 * np.eye(D_latent) def random_rotation(n, theta): rot = 0.99 * np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]]) out = np.zeros((n, n)) out[:2, :2] = rot q = np.linalg.qr(np.random.randn(n, n))[0] return q.dot(out).dot(q.T) def random_dynamics(n): A = np.random.randn(n,n) A = A.dot(A.T) U,S,V = np.linalg.svd(A) A_stable = U.dot(np.diag(S/(1.1*np.max(S)))).dot(V.T) # A_stable = U.dot(0.99 * np.eye(n)).dot(V.T) return A_stable ths = np.linspace(0, np.pi/8., K) As = [random_rotation(D_latent, ths[k]) for k in range(K)] # As = [random_dynamics(D_latent) for k in range(K)] bs = [np.zeros((D_latent, 1))] + [.25 * np.random.randn(D_latent, 1) for k in range(K-1)] C = np.random.randn(D_obs, D_latent) d = np.zeros((D_obs, 1)) sigma_obs = 0.5 * np.ones(D_obs) ################### # generate data # ################### init_dynamics_distns = [Gaussian(mu=mu_init, sigma=sigma_init) for _ in range(K)] dynamics_distns = [Regression(A=np.hstack((A, b)), sigma=0.01 * np.eye(D_latent)) for A,b in zip(As, bs)] emission_distns = DiagonalRegression(D_obs, D_latent+1, A=np.hstack((C, d)), sigmasq=sigma_obs) slds = HMMSLDS( dynamics_distns=dynamics_distns, emission_distns=emission_distns, init_dynamics_distns=init_dynamics_distns, alpha=3., init_state_distn='uniform') #### MANUALLY CREATE DATA P = np.ones((K,K)) + 1 * np.eye(K) P = P / np.sum(P,1,keepdims=True) z = np.zeros(T//D, dtype=np.int32) for t in range(1,T//D): z[t] = np.random.choice(np.arange(K), p=P[z[t-1]]) z = np.repeat(z, D) statesobj = slds._states_class(model=slds, T=z.size, stateseq=z, inputs=np.ones((z.size, 1))) statesobj.generate_gaussian_states() y = statesobj.data = statesobj.generate_obs() x = statesobj.gaussian_states slds.states_list.append(statesobj) return z,x,y,slds
def make_rslds_parameters(C_init): init_dynamics_distns = [ Gaussian( mu=np.zeros(D_latent), sigma=3 * np.eye(D_latent), nu_0=D_latent + 2, sigma_0=3. * np.eye(D_latent), mu_0=np.zeros(D_latent), kappa_0=1.0, ) for _ in range(K) ] ths = np.random.uniform(np.pi / 30., 1.0, size=K) As = [random_rotation(D_latent, th) for th in ths] As = [np.hstack((A, np.ones((D_latent, 1)))) for A in As] dynamics_distns = [ Regression( A=As[k], sigma=np.eye(D_latent), nu_0=D_latent + 1000, S_0=np.eye(D_latent), M_0=np.hstack((np.eye(D_latent), np.zeros((D_latent, 1)))), K_0=np.eye(D_latent + 1), ) for k in range(K) ] if C_init is not None: emission_distns = \ DiagonalRegression(D_obs, D_latent + 1, A=C_init.copy(), sigmasq=np.ones(D_obs), alpha_0=2.0, beta_0=2.0) else: emission_distns = \ DiagonalRegression(D_obs, D_latent + 1, alpha_0=2.0, beta_0=2.0) return init_dynamics_distns, dynamics_distns, emission_distns
def __init__(self, D_obs, D_latent, W=None, sigmasq=None, sigmasq_W_0=1.0, mu_W_0=0.0, alpha_0=3.0, beta_0=2.0): self.D_obs, self.D_latent = D_obs, D_latent # The weights and variances are encapsulated in a DiagonalRegression class self.regression = \ DiagonalRegression( self.D_obs, self.D_latent, mu_0=mu_W_0 * np.ones(self.D_latent), Sigma_0=sigmasq_W_0 * np.eye(self.D_latent), alpha_0=alpha_0, beta_0=beta_0, A=W, sigmasq=sigmasq) self.data_list = []
D_latent = 2 D_input = 0 T = 2000 # Simulate from an LDS with diagonal observation noise truemodel = DefaultLDS(D_obs, D_latent, D_input, sigma_obs=0.1 * np.eye(D_obs)) inputs = np.random.randn(T, D_input) data, stateseq = truemodel.generate(T, inputs=inputs) # Fit with an LDS with diagonal observation noise diag_model = LDS(dynamics_distn=Regression( nu_0=D_latent + 2, S_0=D_latent * np.eye(D_latent), M_0=np.zeros((D_latent, D_latent + D_input)), K_0=(D_latent + D_input) * np.eye(D_latent + D_input)), emission_distn=DiagonalRegression(D_obs, D_latent + D_input)) diag_model.add_data(data, inputs=inputs) # Also fit a model with a full covariance matrix full_model = DefaultLDS(D_obs, D_latent, D_input) full_model.add_data(data, inputs=inputs) # Fit with Gibbs sampling def update(model): model.resample_model() return model.log_likelihood() N_steps = 100 diag_lls = [update(diag_model) for _ in progprint_xrange(N_steps)]
def simulate_nascar(): assert K_true == 4 def random_rotation(n, theta): rot = np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]]) out = np.zeros((n,n)) out[:2,:2] = rot q = np.linalg.qr(np.random.randn(n,n))[0] # q = np.eye(n) return q.dot(out).dot(q.T) As = [random_rotation(D_latent, np.pi/24.), random_rotation(D_latent, np.pi/48.)] # Set the center points for each system centers = [np.array([+2.0, 0.]), np.array([-2.0, 0.])] bs = [-(A - np.eye(D_latent)).dot(center) for A, center in zip(As, centers)] # Add a "right" state As.append(np.eye(D_latent)) bs.append(np.array([+0.1, 0.])) # Add a "right" state As.append(np.eye(D_latent)) bs.append(np.array([-0.35, 0.])) # Construct multinomial regression to divvy up the space # w1, b1 = np.array([+1.0, 0.0]), np.array([-2.0]) # x + b > 0 -> x > -b w2, b2 = np.array([-1.0, 0.0]), np.array([-2.0]) # -x + b > 0 -> x < b w3, b3 = np.array([0.0, +1.0]), np.array([0.0]) # y > 0 reg_W = np.row_stack((w1, w2, w3)) reg_b = np.row_stack((b1, b2, b3)) # Scale the weights to make the transition boundary sharper reg_scale = 100. reg_b *= reg_scale reg_W *= reg_scale # Account for stick breaking asymmetry mu_b, _ = compute_psi_cmoments(np.ones(K_true)) reg_b += mu_b[:,None] # Make a recurrent SLDS with these params # dynamics_distns = [ Regression( A=np.column_stack((A,b)), sigma=1e-4 * np.eye(D_latent), nu_0=D_latent + 2, S_0=1e-4 * np.eye(D_latent), M_0=np.zeros((D_latent, D_latent + 1)), K_0=np.eye(D_latent + 1), ) for A,b in zip(As, bs)] init_dynamics_distns = [ Gaussian( mu=np.array([0.0, 1.0]), sigma=1e-3 * np.eye(D_latent)) for _ in range(K_true)] C = np.hstack((npr.randn(args.D_obs, D_latent), np.zeros((args.D_obs, 1)))) emission_distns = \ DiagonalRegression(args.D_obs, D_latent+1, A=C, sigmasq=1e-5 *np.ones(args.D_obs), alpha_0=2.0, beta_0=2.0) model = PGRecurrentSLDS( trans_params=dict(A=np.hstack((np.zeros((K_true-1, K_true)), reg_W)), b=reg_b, sigmasq_A=100., sigmasq_b=100.), init_state_distn='uniform', init_dynamics_distns=init_dynamics_distns, dynamics_distns=dynamics_distns, emission_distns=emission_distns) # Sample from the model inputs = np.ones((args.T, 1)) y, x, z = model.generate(T=args.T, inputs=inputs) # Maks off some data mask = np.ones((args.T, args.D_obs), dtype=bool) mask[args.mask_start:args.mask_stop] = False return model, inputs, z, x, y, mask
def make_roslds_mtpl(V, I_inj_values, V_compartment, K=3, D_latent=2, sigmasq_value=1e-4, penalty=.05): """ :param V: the (T,) array of voltage observations :param K: the number of discrete states (integer) :param D_latent: the dimension of the continuous latent states """ assert V.ndim == 1, "V must be a shape (T,) array of voltage observations" T = V.shape[0] D_obs = 2 directory = './results/' # set initial plane if K > 1: reg_W, reg_b = make_initial_plane(K) # Scale the weights to make the transition boundary sharper reg_scale = 100. reg_b *= reg_scale reg_W *= reg_scale # Create the model components # (initial state dist, dynamics dist, emissions dist) init_dynamics_distns = [ Gaussian( mu=np.zeros(D_latent), sigma=np.eye(D_latent), nu_0=D_latent + 2, sigma_0=3 * np.eye(D_latent), mu_0=np.zeros(D_latent), kappa_0=1.0, ) for _ in range(K)] dynamics_distns = [ Regression( nu_0=D_latent + 6,#4, S_0=1e-4 * np.eye(D_latent), M_0=np.hstack((np.eye(D_latent), np.zeros((D_latent, 3)))),#2)))), K_0=np.eye(D_latent + 3),#2), affine=False ) for _ in range(K)] # Constrain the emission matrix to have C = [[1, 0, ..., 0]] # and small sigmasq # C = np.hstack((np.eye(D_obs), np.zeros((D_obs, 2)))) C = np.hstack((np.eye(D_obs), np.zeros((D_latent, 3))))#2)))) #sigmasq = np.concatenate((np.array([1e-4]), np.ones(D_obs-1))) sigmasq = np.array([sigmasq_value, penalty]) emission_distns = \ DiagonalRegression(D_obs, D_latent+3,#+2, A=C, sigmasq=sigmasq) # Construct the full model if K == 1: rslds = PGRecurrentOnlySLDS( trans_params=dict(sigmasq_A=10000., sigmasq_b=10000.), init_state_distn='uniform', init_dynamics_distns=init_dynamics_distns, dynamics_distns=dynamics_distns, emission_distns=emission_distns, fixed_emission=True) else: rslds = PGRecurrentOnlySLDS( trans_params=dict(A=np.hstack((np.zeros((K-1, K)), reg_W)), b=reg_b, sigmasq_A=10000., sigmasq_b=10000.), init_state_distn='uniform', init_dynamics_distns=init_dynamics_distns, dynamics_distns=dynamics_distns, emission_distns=emission_distns, fixed_emission=True) # Initialize the continuous states to be V and its gradient assert D_latent == 2 from scipy.ndimage import gaussian_filter1d from sklearn.cluster import KMeans #dV = gaussian_filter1d(np.gradient(V), 1) #nconvolve = 0 #nconvolve =500#100 #dV =np.convolve(np.gradient(V), np.ones((nconvolve,))/nconvolve, mode='same') V_tmp = V.copy() v_thre = 0#3.3 (good)#3#3.5#4#3.5#3#2.5#2.2 V_tmp[V_tmp<v_thre] = 0 print('NEW INITIALIZATION!', v_thre) #dV = gaussian_filter1d(np.gradient(V_tmp), 1) dV = gaussian_filter1d(np.gradient(V_tmp), 10) print('convolue dV') #x_init = np.column_stack((V, dV)) x_init = np.column_stack((V_tmp, dV)) x_init = (x_init - np.mean(x_init, axis=0)) / np.std(x_init, axis=0) # Initialize the discrete states by clustering x_init km = KMeans(K).fit(x_init) z_init = km.labels_ # Plot the #''' plt.close('all') plt.figure() plt.subplot(211) plt.plot(x_init[:10000,:]) # plt.plot(Vs_true[:,j],'r') plt.subplot(212) plt.plot(z_init[:10000]) #plt.show() plt.savefig(directory+'-init-penalized.png') #plt.savefig('nconvolve'+str(nconvolve)+'-init-penalized.png') #''' # Provide an array of ones for the bias (affine term) assert I_inj_values.shape == (T,) data = np.column_stack((V, np.zeros(T,))) # pseudo obs # add voltage effect on rslds (V_compartments) inputs = np.column_stack((np.ones((T, 1)), I_inj_values, V_compartment)) #inputs = np.column_stack((np.ones((T, 1)), I_inj_values)) mask = np.ones((T, D_obs), dtype=bool) rslds.add_data(data, mask=mask, inputs=inputs, stateseq=z_init, gaussian_states=x_init) return rslds
def make_roslds(V, I_inj_values, not_noisy=True, K=6, D_latent=2, sigmasq_value=1e-4, penalty=.05): """ :param V: the (T,) array of voltage observations :param K: the number of discrete states (integer) :param D_latent: the dimension of the continuous latent states """ assert V.ndim == 1, "V must be a shape (T,) array of voltage observations" T = V.shape[0] D_obs = 2 ''' # initialization w1, b1 = np.array([+1.0, 0.0]), np.array([0.0]) # x >0 w2, b2 = np.array([0.0, +1.0]), np.array([0.0]) # y > 0 reg_W = np.row_stack((w1, w2)) reg_b = np.row_stack((b1, b2)) ''' reg_W, reg_b = make_initial_plane(K) # Scale the weights to make the transition boundary sharper reg_scale = 100. reg_b *= reg_scale reg_W *= reg_scale # Create the model components # (initial state dist, dynamics dist, emissions dist) init_dynamics_distns = [Gaussian(mu=np.zeros(D_latent), sigma=np.eye(D_latent), nu_0=D_latent + 2, sigma_0=3 * np.eye(D_latent), mu_0=np.zeros(D_latent), kappa_0=1.0, ) for _ in range(K)] dynamics_distns = [Regression( nu_0=D_latent + 4, S_0=1e-4 * np.eye(D_latent), M_0=np.hstack((np.eye(D_latent), np.zeros((D_latent, 2)))), K_0=np.eye(D_latent + 2), affine=False ) for _ in range(K)] # Constrain the emission matrix to have C = [[1, 0, ..., 0]] # and small sigmasq # C = np.hstack((np.eye(D_obs), np.zeros((D_obs, 2)))) C = np.hstack((np.eye(D_obs), np.zeros((D_latent, 2)))) #sigmasq = np.concatenate((np.array([1e-4]), np.ones(D_obs-1))) sigmasq = np.array([sigmasq_value, penalty]) emission_distns = DiagonalRegression(D_obs, D_latent+2, A=C, sigmasq=sigmasq) # Construct the full model if K == 1: rslds = PGRecurrentOnlySLDS(trans_params=dict(sigmasq_A=10000., sigmasq_b=10000.), init_state_distn='uniform', init_dynamics_distns=init_dynamics_distns, dynamics_distns=dynamics_distns, emission_distns=emission_distns, fixed_emission=True) else: rslds = PGRecurrentOnlySLDS(trans_params=dict(A=np.hstack((np.zeros((K-1, K)), reg_W)), b=reg_b, sigmasq_A=10000., sigmasq_b=10000.), init_state_distn='uniform', init_dynamics_distns=init_dynamics_distns, dynamics_distns=dynamics_distns, emission_distns=emission_distns, fixed_emission=True) # Initialize the continuous states to be V and its gradient assert D_latent == 2 if not_noisy: dV = gaussian_filter1d(np.gradient(V), 1) else: nconvolve =10000 dV =np.convolve(np.gradient(V), np.ones((nconvolve,))/nconvolve, mode='same') x_init = np.column_stack((V, dV)) x_init = (x_init - np.mean(x_init, axis=0)) / np.std(x_init, axis=0) # Initialize the discrete states by clustering x_init km = KMeans(K).fit(x_init) z_init = km.labels_ # Provide an array of ones for the bias (affine term) assert I_inj_values.shape == (T,) data = np.column_stack((V, np.zeros(T,))) # pseudo obs inputs = np.column_stack((np.ones((T, 1)), I_inj_values)) mask = np.ones((T, D_obs), dtype=bool) rslds.add_data(data, mask=mask, inputs=inputs, stateseq=z_init, gaussian_states=x_init) return rslds
# Make rSLDS parameters init_dynamics_distns = [ Gaussian( mu=np.zeros(D_latent), sigma=np.eye(D_latent), nu_0=D_latent + 2, sigma_0=3. * np.eye(D_latent), mu_0=np.zeros(D_latent), kappa_0=1.0, ) for _ in range(K)] # Create hierarchical dynamics model hierarchical_dynamics_distn = \ TreeStructuredHierarchicalDynamics(tree, 0.1 * np.eye(D_latent), 3 * np.eye(D_latent + 1)) emission_distns = \ DiagonalRegression(D_obs, D_latent + 1, alpha_0=2.0, beta_0=2.0) model = TreeStructuredPGRecurrentSLDS( trans_params=dict(sigmasq_A=10., sigmasq_b=0.01), init_state_distn='uniform', init_dynamics_distns=init_dynamics_distns, hierarchical_dynamics_distn=hierarchical_dynamics_distn, emission_distns=emission_distns) plt.figure(figsize=(12, 12)) ax = plt.subplot(3, 4, 2) plot_dynamics(hierarchical_dynamics_distn.As[0], 0, ax=ax) ax = plt.subplot(3, 4, 4+1) plot_dynamics(hierarchical_dynamics_distn.As[1], 1, ax=ax) ax = plt.subplot(3, 4, 4 + 2) plot_dynamics(hierarchical_dynamics_distn.As[4], 4, ax=ax)
], dynamics_distns=[ Regression( A=np.hstack( (np.eye(D_latent), np.zeros((D_latent, D_input)))), sigma=np.eye(D_latent), nu_0=D_latent + 3, S_0=D_latent * np.eye(D_latent), M_0=np.hstack( (np.eye(D_latent), np.zeros((D_latent, D_input)))), K_0=D_latent * np.eye(D_latent + D_input), ) for _ in range(Kmax) ], emission_distns=DiagonalRegression( D_obs, D_latent + D_input, alpha_0=2.0, beta_0=1.0, ), alpha=3., init_state_distn='uniform') model.add_data(data, inputs=np.ones((T, D_input))) model.resample_states() for _ in progprint_xrange(0): model.resample_model() model.states_list[0]._init_mf_from_gibbs() #################### # run mean field # ####################
] C = np.random.randn(D_obs, D_latent) sigma_obs = 0.5 * np.ones(D_obs) #%% ################### # generate data # ################### # K: x_0 ~ Normal(mu_init, sigma_init) init_dynamics_distns = [ Gaussian(mu=mu_init, sigma=sigma_init) for _ in range(K) ] # K : x_t ~ Normal( A_{z=k} x_t + b_{z=K}, I) dynamics_distns = [Regression(A=A, sigma=np.eye(D_latent)) for A in As] #K: y_t | x_t ~ Normal (C_{z=k} x_t + d_z{k=K}, diag(Sigma_obs)) emission_distns = DiagonalRegression(D_obs, D_latent, A=C, sigmasq=sigma_obs) truemodel = HMMSLDS(dynamics_distns=dynamics_distns, emission_distns=emission_distns, init_dynamics_distns=init_dynamics_distns, alpha=3., init_state_distn='uniform') #%% # Manually create the states object with the mask T = 1000 # get z is T x 1 stateseq = np.repeat(np.arange(T // 100) % 2, 100).astype(np.int32) statesobj = truemodel._states_class(model=truemodel, T=stateseq.size, stateseq=stateseq)
def trainModel(fileName, unit_trial, K=8, xDim=5): # unit_trial -- training data # randomization np.random.seed() numTrial, numUnit, numTime = unit_trial.shape # factor analysis for initialization factor_unit_trial = unit_trial.transpose([0, 2, 1]) factor_unit_trial = factor_unit_trial.reshape([-1, factor_unit_trial.shape[2]]) yDim = numUnit inputDim = 1 # some constants inputs = np.ones((numTime, inputDim)) estimator = factan(n_components=xDim, tol=0.00001, copy=True, max_iter=10000, noise_variance_init=None, svd_method='randomized', iterated_power=3, random_state=None) estimator.fit(factor_unit_trial) C_init = estimator.components_.T D_init = estimator.mean_.reshape([-1, 1]) # SLDS fit init_dynamics_distns = [Gaussian(nu_0=xDim+3, sigma_0=3.*np.eye(xDim), mu_0=np.zeros(xDim), kappa_0=0.01) for _ in range(K)] dynamics_distns = [Regression(nu_0=xDim + 1, S_0=xDim * np.eye(xDim), M_0=np.hstack((.99 * np.eye(xDim), np.zeros((xDim, inputDim)))), K_0=xDim * np.eye(xDim + inputDim)) for _ in range(K)] As = [np.eye(xDim) for _ in range(K)] if inputDim > 0: As = [np.hstack((A, np.zeros((xDim, inputDim)))) for A in As] for dd, A in zip(dynamics_distns, As): dd.A = A sigma_statess = [np.eye(xDim) for _ in range(K)] for dd, sigma in zip(dynamics_distns, sigma_statess): dd.sigma = sigma emission_distns = [DiagonalRegression(yDim, xDim + inputDim, mu_0=None, Sigma_0=None, alpha_0=3.0, beta_0=2.0, A=np.hstack((C_init.copy(), D_init.copy())), sigmasq=None, niter=1) for _ in range(K)] train_model = HMMSLDS( init_dynamics_distns= init_dynamics_distns, dynamics_distns= dynamics_distns, emission_distns= emission_distns, alpha=3., init_state_distn='uniform') # Adding training data for trial in range(numTrial): train_model.add_data(unit_trial[trial].T, inputs=inputs) print("Initializing with Gibbs") N_gibbs_samples = 2000 def initialize(model): model.resample_model() return model.log_likelihood() gibbs_lls = [initialize(train_model) for _ in progprint_xrange(N_gibbs_samples)] print("Fitting with VBEM") N_vbem_iters = 100 def update(model): model.VBEM_step() return model.log_likelihood() train_model._init_mf_from_gibbs() vbem_lls = [update(train_model) for _ in progprint_xrange(N_vbem_iters)] np.save(fileName + '_gibbs_lls', gibbs_lls) np.save(fileName + '_vbem_lls', vbem_lls) np.save(fileName + '_train_model', train_model) return train_model
mask = np.ones_like(data, dtype=bool) chunksz = 100 for i, offset in enumerate(range(0, T, chunksz)): j = i % (D_obs + 1) if j < D_obs: mask[offset:min(offset + chunksz, T), j] = False if j == D_obs: mask[offset:min(offset + chunksz, T), :] = False # Fit with another LDS model = LDS(dynamics_distn=Regression(nu_0=D_latent + 3, S_0=D_latent * np.eye(D_latent), M_0=np.zeros((D_latent, D_latent)), K_0=D_latent * np.eye(D_latent)), emission_distn=DiagonalRegression(D_obs, D_latent, alpha_0=2.0, beta_0=1.0)) model.add_data(data=data, mask=mask) # Fit the model N_samples = 500 sigma_obs_smpls = [] def gibbs_update(model): model.resample_model() sigma_obs_smpls.append(model.sigma_obs_flat) return model.log_likelihood() def em_update(model):
def simulate_nascar(): assert K_true == 4 As = [ random_rotation(D_latent, np.pi / 24.), random_rotation(D_latent, np.pi / 48.) ] # Set the center points for each system centers = [np.array([+2.0, 0.]), np.array([-2.0, 0.])] bs = [ -(A - np.eye(D_latent)).dot(center) for A, center in zip(As, centers) ] # Add a "right" state As.append(np.eye(D_latent)) bs.append(np.array([+0.1, 0.])) # Add a "right" state As.append(np.eye(D_latent)) bs.append(np.array([-0.25, 0.])) # Construct multinomial regression to divvy up the space w1, b1 = np.array([+1.0, 0.0]), np.array([-2.0]) # x + b > 0 -> x > -b w2, b2 = np.array([-1.0, 0.0]), np.array([-2.0]) # -x + b > 0 -> x < b w3, b3 = np.array([0.0, +1.0]), np.array([0.0]) # y > 0 w4, b4 = np.array([0.0, -1.0]), np.array([0.0]) # y < 0 reg_W = np.column_stack((100 * w1, 100 * w2, 10 * w3, 10 * w4)) reg_b = np.concatenate((100 * b1, 100 * b2, 10 * b3, 10 * b4)) # Make a recurrent SLDS with these params # dynamics_distns = [ Regression( A=np.column_stack((A, b)), sigma=1e-4 * np.eye(D_latent), nu_0=D_latent + 2, S_0=1e-4 * np.eye(D_latent), M_0=np.zeros((D_latent, D_latent + 1)), K_0=np.eye(D_latent + 1), ) for A, b in zip(As, bs) ] init_dynamics_distns = [ Gaussian(mu=np.array([0.0, 1.0]), sigma=1e-3 * np.eye(D_latent)) for _ in range(K) ] C = np.hstack((npr.randn(D_obs, D_latent), np.zeros((D_obs, 1)))) emission_distns = \ DiagonalRegression(D_obs, D_latent+1, A=C, sigmasq=1e-5 *np.ones(D_obs), alpha_0=2.0, beta_0=2.0) model = SoftmaxRecurrentOnlySLDS(trans_params=dict(W=reg_W, b=reg_b), init_state_distn='uniform', init_dynamics_distns=init_dynamics_distns, dynamics_distns=dynamics_distns, emission_distns=emission_distns, alpha=3.) ######################### # Sample from the model # ######################### inputs = np.ones((T, 1)) y, x, z = model.generate(T=T, inputs=inputs) # Maks off some data if mask_start == mask_stop: mask = None else: mask = np.ones((T, D_obs), dtype=bool) mask[mask_start:mask_stop] = False # Print the true parameters np.set_printoptions(precision=2) print("True W:\n{}".format(model.trans_distn.W)) print("True logpi:\n{}".format(model.trans_distn.logpi)) return model, inputs, z, x, y, mask