def info_E_step(self): self._normalizer, self.smoothed_mus, \ self.smoothed_sigmas, E_xtp1_xtT = \ info_E_step(*self.info_params) self._set_expected_stats(self.smoothed_mus, self.smoothed_sigmas, E_xtp1_xtT)
def E_step(self, verbose=False): self.gaussian_states = self.laplace_approximation(verbose=verbose) # Compute normalizer and covariances with E step T, D = self.T, self.D_latent H_diag, H_upper_diag = self.sparse_hessian_log_joint( self.gaussian_states) J_init = J_11 = J_22 = np.zeros((D, D)) h_init = h_1 = h_2 = np.zeros((D, )) # Negate the Hessian since precision is -H J_21 = np.swapaxes(-H_upper_diag, -1, -2) J_node = -H_diag h_node = np.zeros((T, D)) logZ, _, self.smoothed_sigmas, E_xtp1_xtT = \ info_E_step(J_init, h_init, 0, J_11, J_21, J_22, h_1, h_2, np.zeros((T - 1)), J_node, h_node, np.zeros(T)) # Laplace approximation -- normalizer is the joint times # the normalizer from the Gaussian approx. self._normalizer = self.log_joint(self.gaussian_states) + logZ self._set_expected_stats(self.gaussian_states, self.smoothed_sigmas, E_xtp1_xtT)
def check_info_Estep(A, B, sigma_states, C, D, sigma_obs, mu_init, sigma_init, inputs, data): ll, smoothed_mus, smoothed_sigmas, ExnxT = E_step(mu_init, sigma_init, A, B, sigma_states, C, D, sigma_obs, inputs, data) ll2, smoothed_mus2, smoothed_sigmas2, ExnxT2 = info_E_step( *info_params(A, B, sigma_states, C, D, sigma_obs, mu_init, sigma_init, data, inputs)) assert np.isclose(ll, ll2) assert np.allclose(smoothed_mus, smoothed_mus2) assert np.allclose(smoothed_sigmas, smoothed_sigmas2) assert np.allclose(ExnxT, ExnxT2)
def check_info_Estep(A, B, C, D, mu_init, sigma_init, data): ll, smoothed_mus, smoothed_sigmas, ExnxT = E_step( mu_init, sigma_init, A, B.dot(B.T), C, D.dot(D.T), data) partial_ll, smoothed_mus2, smoothed_sigmas2, ExnxT2 = info_E_step( *info_params(A, B, C, D, mu_init, sigma_init, data)) ll2 = partial_ll + LDSStates._extra_loglike_terms( A, B.dot(B.T), C, D.dot(D.T), mu_init, sigma_init, data) assert np.isclose(ll,ll2) assert np.allclose(smoothed_mus, smoothed_mus2) assert np.allclose(smoothed_sigmas, smoothed_sigmas2) assert np.allclose(ExnxT, ExnxT2)
def check_info_Estep(A, B, C, D, mu_init, sigma_init, data): ll, smoothed_mus, smoothed_sigmas, ExnxT = E_step(mu_init, sigma_init, A, B.dot(B.T), C, D.dot(D.T), data) partial_ll, smoothed_mus2, smoothed_sigmas2, ExnxT2 = info_E_step( *info_params(A, B, C, D, mu_init, sigma_init, data)) ll2 = partial_ll + LDSStates._extra_loglike_terms(A, B.dot( B.T), C, D.dot(D.T), mu_init, sigma_init, data) assert np.isclose(ll, ll2) assert np.allclose(smoothed_mus, smoothed_mus2) assert np.allclose(smoothed_sigmas, smoothed_sigmas2) assert np.allclose(ExnxT, ExnxT2)
def solve_symm_block_tridiag(H_diag, H_upper_diag, v): """ use the info smoother to solve a symmetric block tridiagonal system """ T, D, _ = H_diag.shape assert H_diag.ndim == 3 and H_diag.shape[2] == D assert H_upper_diag.shape == (T - 1, D, D) assert v.shape == (T, D) J_init = J_11 = J_22 = np.zeros((D, D)) h_init = h_1 = h_2 = np.zeros((D, )) J_21 = np.swapaxes(H_upper_diag, -1, -2) J_node = H_diag h_node = v _, y, _, _ = info_E_step(J_init, h_init, 0, J_11, J_21, J_22, h_1, h_2, np.zeros((T - 1)), J_node, h_node, np.zeros(T)) return y
def compute_symm_block_tridiag_covariances(H_diag, H_upper_diag): """ use the info smoother to solve a symmetric block tridiagonal system """ T, D, _ = H_diag.shape assert H_diag.ndim == 3 and H_diag.shape[2] == D assert H_upper_diag.shape == (T - 1, D, D) J_init = J_11 = J_22 = np.zeros((D, D)) h_init = h_1 = h_2 = np.zeros((D, )) J_21 = np.swapaxes(H_upper_diag, -1, -2) J_node = H_diag h_node = np.zeros((T, D)) _, _, sigmas, E_xt_xtp1 = \ info_E_step(J_init, h_init, 0, J_11, J_21, J_22, h_1, h_2, np.zeros((T-1)), J_node, h_node, np.zeros(T)) return sigmas, E_xt_xtp1
def check_info_Estep(A, B, C, D, mu_init, sigma_init, data): def Covxxn_to_ExnxT(Covxxn, smoothed_mus): outs = np.empty_like(Covxxn) for out, cov, mu_t, mu_tp1 in zip(outs,Covxxn, smoothed_mus[:-1], smoothed_mus[1:]): out[...] = cov.T + np.outer(mu_tp1,mu_t) return outs ll, smoothed_mus, smoothed_sigmas, ExnxT = E_step( mu_init, sigma_init, A, B.dot(B.T), C, D.dot(D.T), data) partial_ll, smoothed_mus2, smoothed_sigmas2, Covxxn = info_E_step( *info_params(A, B, C, D, mu_init, sigma_init, data)) ll2 = partial_ll + extra_loglike_terms( A, B, C, D, mu_init, sigma_init, data) ExnxT2 = Covxxn_to_ExnxT(Covxxn,smoothed_mus2) assert np.isclose(ll,ll2) assert np.allclose(smoothed_mus, smoothed_mus2) assert np.allclose(smoothed_sigmas, smoothed_sigmas2) assert np.allclose(ExnxT, ExnxT2)
def check_info_Estep(A, B, C, D, mu_init, sigma_init, data): def Covxxn_to_ExnxT(Covxxn, smoothed_mus): outs = np.empty_like(Covxxn) for out, cov, mu_t, mu_tp1 in zip(outs, Covxxn, smoothed_mus[:-1], smoothed_mus[1:]): out[...] = cov.T + np.outer(mu_tp1, mu_t) return outs ll, smoothed_mus, smoothed_sigmas, ExnxT = E_step(mu_init, sigma_init, A, B.dot(B.T), C, D.dot(D.T), data) partial_ll, smoothed_mus2, smoothed_sigmas2, Covxxn = info_E_step( *info_params(A, B, C, D, mu_init, sigma_init, data)) ll2 = partial_ll + extra_loglike_terms(A, B, C, D, mu_init, sigma_init, data) ExnxT2 = Covxxn_to_ExnxT(Covxxn, smoothed_mus2) assert np.isclose(ll, ll2) assert np.allclose(smoothed_mus, smoothed_mus2) assert np.allclose(smoothed_sigmas, smoothed_sigmas2) assert np.allclose(ExnxT, ExnxT2)
def meanfield_update_gaussian_states(self): J_init = np.linalg.inv(self.sigma_init) h_init = np.linalg.solve(self.sigma_init, self.mu_init) def get_paramseq(distns): contract = partial(np.tensordot, self.expected_states, axes=1) std_param = lambda d: d._natural_to_standard(d.mf_natural_hypparam) params = [mniw_expectedstats(*std_param(d)) for d in distns] return map(contract, zip(*params)) J_pair_22, J_pair_21, J_pair_11, logdet_pair = \ get_paramseq(self.dynamics_distns) J_yy, J_yx, J_node, logdet_node = get_paramseq(self.emission_distns) h_node = np.einsum('ni,nij->nj', self.data, J_yx) self._mf_lds_normalizer, self.smoothed_mus, self.smoothed_sigmas, \ E_xtp1_xtT = info_E_step( J_init,h_init,J_pair_11,-J_pair_21,J_pair_22,J_node,h_node) self._mf_lds_normalizer += LDSStates._info_extra_loglike_terms( J_init, h_init, logdet_pair, J_yy, logdet_node, self.data) self._set_gaussian_expected_stats( self.smoothed_mus,self.smoothed_sigmas,E_xtp1_xtT)
def meanfieldupdate(self): self._mf_lds_normalizer, self.smoothed_mus, self.smoothed_sigmas, \ E_xtp1_xtT = info_E_step(*self.expected_info_params) self._set_expected_stats(self.smoothed_mus, self.smoothed_sigmas, E_xtp1_xtT)