def get_sampled_eta_psi(i, theta_sampled, N): print i psi = numpy.empty([100,3]) eta = numpy.empty([int(N + N*(N-1)/2),100]) alpha = [.999,1.,1.001] for j in range(100): for k, a in enumerate(alpha): if k == 1: eta[:,j], psi[j,k] = bethe_approximation.compute_eta_hybrid( a*theta_sampled[i,:,j], int(N), return_psi=True) else: psi[j,k] = bethe_approximation.compute_eta_hybrid( a*theta_sampled[i,:,j], int(N), return_psi=True)[1] return eta, psi, i
def gradient_1sample(n_samples, emd): """ Computes one sample of the expectation inside the equation for the gradient of the q function with respect to the network parameters of the Ising models of the main fetures. :param container .EMData emd: All data pertaining to the EM algorithm. """ # Take 1 sample of theta for all time steps generated_theta = sample_theta(emd) # Compute 1 sample sample_value = 0 for t in range(emd.T): theta_mixed = transforms.compute_mixed_theta(generated_theta[t,:], \ emd.J) if emd.exact: p = transforms.compute_p(theta_mixed) eta_tilde = transforms.compute_eta(p) else: eta_tilde = bethe_approximation.compute_eta_hybrid(theta_mixed, emd.N) a = emd.F_tilde[t,:] - eta_tilde # Summation for all time bins sample_value += emd.R * numpy.dot(a[:,numpy.newaxis], \ generated_theta[t,numpy.newaxis,:]) return sample_value
def log_likelihood(f_t, theta_f_t, J, R, N, exact): """ Computes the likelihood of observed pattern rates given the natural parameters, all for a single timestep. :param numpy.ndarray y_t: Frequency of observed patterns for one timestep. :param numpy.ndarray theta_f_t: Natural parameters of observed patterns for one timestep. :param numpy.ndarray J: Fitted graphs matrix :param int R: Number of trials over which patterns were observed. :param int N: Number of cells in the `spikes' train to analyze. :param boolean exact Whether to use exact solution (True) or Bethe approximation (False) for the computation of eta, psi and fisher info :returns: Log likelhood of the observed patterns given the natural parameters, as a float. """ theta_mixed = transforms.compute_mixed_theta(theta_f_t, J) if exact: psi = transforms.compute_psi(theta_mixed) else: psi = bethe_approximation.compute_eta_hybrid(theta_mixed, N, return_psi=True)[1] log_p = R * (numpy.dot(f_t, theta_f_t) - psi) return log_p
def KL_distance(theta1, theta2, N): D = theta1.shape[0] eta1, psi1 = bethe_approximation.compute_eta_hybrid(theta1, N, return_psi=True) eta2, psi2 = bethe_approximation.compute_eta_hybrid(theta1, N, return_psi=True) S1 = energies.compute_entropy(theta1.reshape(1, D), eta1.reshape(1, D), psi1, 2) S2 = energies.compute_entropy(theta2.reshape(1, D), eta2.reshape(1, D), psi2, 2) KL1 = -S1 + psi2 - eta1.dot(theta2) KL2 = -S2 + psi1 - eta2.dot(theta1) KL = (KL1 + KL2) / 2 return KL
def newton_raphson(emd, t): """ Computes the MAP estimate of the natural parameters at some timestep, given the observed spike patterns at that timestep and the one-step-prediction mean and covariance for the same timestep. :param container.EMData emd: All data pertaining to the EM algorithm. :param int t: Timestep for which to compute the maximum posterior probability. :returns: Tuple containing the mean and covariance of the posterior probability density, each as a numpy.ndarray. """ # Extract one-step predictions for time t theta_o = emd.theta_o[t, :] sigma_o = emd.sigma_o[t, :, :] R = emd.R N = emd.N exact = emd.exact # Extract the feature vector for time t f_t = emd.f[t, :] # Extract the fitted parameters of the original Ising models J = emd.J # Initialise theta_max to the smooth theta value of the previous iteration theta_max = emd.theta_s[t, :] # Use non-normalised posterior prob. as loop guard lpp = -numpy.inf lpc = probability.log_likelihood(f_t, theta_max, J, R, N, exact) +\ probability.log_multivariate_normal(theta_max, theta_o, sigma_o) iterations = 0 # Iterate the gradient ascent algorithm until convergence or failure while lpc - lpp > GA_CONVERGENCE: # Compute mixed theta theta_mixed = transforms.compute_mixed_theta(theta_max, J) # Compute the eta of the current theta values if exact: p = transforms.compute_p(theta_mixed) eta_tilde = transforms.compute_eta(p) else: eta_tilde = bethe_approximation.compute_eta_hybrid(theta_mixed, N) eta = transforms.compute_eta_LD(eta_tilde, J) # Compute the inverse of one-step covariance sigma_o_i = numpy.linalg.inv(sigma_o) # Compute the first derivative of the posterior prob. w.r.t. theta_max dllk = R * (f_t - eta) dlpr = -numpy.dot(sigma_o_i, theta_max - theta_o) dlpo = dllk + dlpr # Compute the second derivative of the posterior prob. w.r.t. theta_max if exact: fisher_tilde = transforms.compute_fisher_info(p, eta_tilde) else: fisher_tilde = numpy.diag( bethe_approximation.construct_fisher_diag(eta_tilde, N)) fisher = transforms.compute_fisher_info_LD(fisher_tilde, J) ddlpo = -R * fisher - sigma_o_i # Dot the results to climb the gradient, and accumulate the result ddlpo_i = numpy.linalg.inv(ddlpo) theta_max -= numpy.dot(ddlpo_i, dlpo) # Update previous and current posterior prob. lpp = lpc lpc = probability.log_likelihood(f_t, theta_max, J, R, N, exact)\ + probability.log_multivariate_normal(theta_max, theta_o, sigma_o) # Count iterations iterations += 1 # Check for check for overrun if iterations == MAX_GA_ITERATIONS: raise Exception('The maximum-a-posterior gradient-ascent '+\ 'algorithm did not converge before reaching the maximum '+\ 'number iterations.') return theta_max, -ddlpo_i
psi_ind = numpy.zeros((12, T)) S1 = numpy.zeros((12, T)) for k in range(12): if emd.marg_llk == probability.log_marginal: # If exact: for t in range(T): p = transforms.compute_p(theta_m[k, t, :]) psi[k, t] = transforms.compute_psi(theta_m[k, t, :]) eta[k, t, :] = transforms.compute_eta(p) tmp1 = transforms.compute_psi(theta_m[k, t, :] * (1 + epsilon)) tmp2 = transforms.compute_psi(theta_m[k, t, :] * (1 - epsilon)) c = tmp1 - 2 * psi[k, t] + tmp2 d = epsilon**2 C[k, t] = c / d else: # If approximations for t in range(T): eta[k, t, :], psi[k, t] = bethe_approximation.compute_eta_hybrid( theta_m[k, t, :], N, return_psi=True) tmp1 = bethe_approximation.compute_eta_hybrid(theta_m[k, t, :] * (1 + epsilon), N, return_psi=True)[1] tmp2 = bethe_approximation.compute_eta_hybrid(theta_m[k, t, :] * (1 - epsilon), N, return_psi=True)[1] c = tmp1 - 2 * psi[k, t] + tmp2 d = epsilon**2 C[k, t] = c / d p_silence[k, :] = numpy.exp(-psi[k, :]) p_spike[k, :] = numpy.sum(eta[k, :, :N], axis=1) / N S2[k, :] = energies.compute_entropy(theta_m[k, :, :], eta[k, :, :], psi[k, :], 2)
def generate_data_figure3and4(data_path = '../Data/', num_of_iterations=10): R, T, N, O = 200, 500, 15, 2 f = h5py.File(data_path + 'figure1data.h5', 'r') theta = f['data']['theta1'].value f.close() transforms.initialise(N, O) psi_true = numpy.empty(T) for i in range(T): psi_true[i] = transforms.compute_psi(theta[i]) p = numpy.zeros((T, 2 ** N)) for i in range(T): p[i, :] = transforms.compute_p(theta[i, :]) fitting_methods = ['exact', 'bethe_hybrid', 'mf'] f = h5py.File(data_path + 'figure2and3data.h5', 'w') f.create_dataset('psi_true', data=psi_true) f.create_dataset('theta_true', data=theta) for fit in fitting_methods: g = f.create_group(fit) g.create_dataset('MISE_theta', shape=[num_of_iterations]) g.create_dataset('MISE_psi', shape=[num_of_iterations]) g.create_dataset('psi', shape=[num_of_iterations, T]) f.close() for iteration in range(num_of_iterations): print 'Iteration %d' % iteration spikes = synthesis.generate_spikes(p, R, seed=None) for fit in fitting_methods: if fit == 'exact': emd = __init__.run(spikes, O, map_function='cg', param_est='exact', param_est_eta='exact') else: emd = __init__.run(spikes, O, map_function='cg', param_est='pseudo', param_est_eta=fit) psi = numpy.empty(T) if fit == 'exact': for i in range(T): psi[i] = transforms.compute_psi(emd.theta_s[i]) elif fit == 'bethe_hybrid': for i in range(T): psi[i] = bethe_approximation.compute_eta_hybrid( emd.theta_s[i], N, return_psi=1)[1] elif fit == 'mf': for i in range(T): eta_mf = mean_field.forward_problem(emd.theta_s[i], N, 'TAP') psi[i] = mean_field.compute_psi(emd.theta_s[i], eta_mf, N) mise_theta = numpy.mean((theta - emd.theta_s) ** 2) mise_psi = numpy.mean((psi_true - psi) ** 2) f = h5py.File(data_path + 'figure2and3data.h5', 'r+') g = f[fit] g['MISE_theta'][iteration] = mise_theta g['MISE_psi'][iteration] = mise_psi if iteration == 0: g.create_dataset('theta', data=emd.theta_s) g.create_dataset('sigma', data=emd.sigma_s) g['psi'][iteration] = psi f.close() print 'Fitted with %s' % fit
def generate_data_figure2(data_path='../Data/', max_network_size=60): N, O, R, T = 10, 2, 200, 500 num_of_networks = max_network_size/N mu = numpy.zeros(T) x = numpy.arange(1, 401) mu[100:] = 1. * (3. / (2. * numpy.pi * (x / 400. * 3.) ** 3)) ** .5 * \ numpy.exp(-3. * ((x / 400. * 3.) - 1.) ** 2 / (2. * (x / 400. * 3.))) D = transforms.compute_D(N, O) thetas = numpy.empty([num_of_networks, T, D]) etas = numpy.empty([num_of_networks, T, D]) psi = numpy.empty([num_of_networks, T]) S = numpy.empty([num_of_networks, T]) C = numpy.empty([num_of_networks, T]) transforms.initialise(N, O) for i in range(num_of_networks): thetas[i] = synthesis.generate_thetas(N, O, T, mu1=-2.) thetas[i, :, :N] += mu[:, numpy.newaxis] for t in range(T): p = transforms.compute_p(thetas[i, t]) etas[i, t] = transforms.compute_eta(p) psi[i, t] = transforms.compute_psi(thetas[i, t]) psi1 = transforms.compute_psi(.999 * thetas[i, t]) psi2 = transforms.compute_psi(1.001 * thetas[i, t]) C[i, t] = (psi1 - 2. * psi[i, t] + psi2) / .001 ** 2 S[i, t] = -(numpy.sum(etas[i, t] * thetas[i, t]) - psi[i, t]) C /= numpy.log(2) S /= numpy.log(2) f = h5py.File(data_path + 'figure2data.h5', 'w') g1 = f.create_group('data') g1.create_dataset('thetas', data=thetas) g1.create_dataset('etas', data=etas) g1.create_dataset('psi', data=psi) g1.create_dataset('S', data=S) g1.create_dataset('C', data=C) g2 = f.create_group('error') g2.create_dataset('MISE_thetas', shape=[num_of_networks]) g2.create_dataset('MISE_population_rate', shape=[num_of_networks]) g2.create_dataset('MISE_psi', shape=[num_of_networks]) g2.create_dataset('MISE_S', shape=[num_of_networks]) g2.create_dataset('MISE_C', shape=[num_of_networks]) g2.create_dataset('population_rate', shape=[num_of_networks, T]) g2.create_dataset('psi', shape=[num_of_networks, T]) g2.create_dataset('S', shape=[num_of_networks, T]) g2.create_dataset('C', shape=[num_of_networks, T]) f.close() for i in range(num_of_networks): print 'N=%d' % ((i + 1) * N) D = transforms.compute_D((i + 1) * N, O) theta_all = numpy.empty([T, D]) triu_idx = numpy.triu_indices(N, k=1) triu_idx_all = numpy.triu_indices((i + 1) * N, k=1) for j in range(i + 1): theta_all[:, N * j:(j + 1) * N] = thetas[j, :, :N] for t in range(T): theta_ij = numpy.zeros([(i + 1) * N, (i + 1) * N]) for j in range(i + 1): theta_ij[triu_idx[0] + j * N, triu_idx[1] + j * N] = \ thetas[j, t, N:] theta_all[t, (i + 1) * N:] = theta_ij[triu_idx_all] spikes = synthesis.generate_spikes_gibbs_parallel(theta_all , (i + 1) * N, O, R, sample_steps=10, num_proc=4) emd = __init__.run(spikes, O, map_function='cg', param_est='pseudo', param_est_eta='bethe_hybrid', lmbda1=100, lmbda2=200) eta_est = numpy.empty(emd.theta_s.shape) psi_est = numpy.empty(T) S_est = numpy.empty(T) C_est = numpy.empty(T) for t in range(T): eta_est[t], psi_est[t] = bethe_approximation.compute_eta_hybrid( emd.theta_s[t], (i + 1) * N, return_psi=1) psi1 = bethe_approximation.compute_eta_hybrid( .999 * emd.theta_s[t], (i + 1) * N, return_psi=1)[1] psi2 = bethe_approximation.compute_eta_hybrid( 1.001 * emd.theta_s[t], (i + 1) * N, return_psi=1)[1] S_est[t] = -(numpy.sum(eta_est[t] * emd.theta_s[t]) - psi_est[t]) C_est[t] = (psi1 - 2. * psi_est[t] + psi2) / .001 ** 2 S_est /= numpy.log(2) C_est /= numpy.log(2) population_rate = numpy.mean(numpy.mean(etas[:i + 1, :, :N], axis=0), axis=1) population_rate_est = numpy.mean(eta_est[:, :(i + 1) * N], axis=1) psi_true = numpy.sum(psi[:(i + 1), :], axis=0) S_true = numpy.sum(S[:(i + 1), :], axis=0) C_true = numpy.sum(C[:(i + 1), :], axis=0) f = h5py.File(data_path + 'figure2data.h5', 'r+') f['error']['MISE_thetas'][i] = numpy.mean( (theta_all - emd.theta_s) ** 2) f['error']['MISE_population_rate'][i] = numpy.mean( (population_rate - population_rate_est) ** 2) f['error']['MISE_psi'][i] = numpy.mean((psi_est - psi_true) ** 2) f['error']['MISE_S'][i] = numpy.mean((S_est - S_true) ** 2) f['error']['MISE_C'][i] = numpy.mean((C_est - C_true) ** 2) f['error']['population_rate'][i] = population_rate_est f['error']['psi'][i] = psi_est f['error']['S'][i] = S_est f['error']['C'][i] = C_est f.close() f = h5py.File(data_path + 'figure2data.h5', 'r+') thetas = f['data']['thetas'].value etas = f['data']['etas'].value psi = f['data']['psi'].value S = f['data']['S'].value C = f['data']['C'].value g2 = f.create_group('error500') g2.create_dataset('population_rate', shape=[num_of_networks, T]) g2.create_dataset('psi', shape=[num_of_networks, T]) g2.create_dataset('S', shape=[num_of_networks, T]) g2.create_dataset('C', shape=[num_of_networks, T]) g2.create_dataset('MISE_thetas', shape=[num_of_networks]) g2.create_dataset('MISE_population_rate', shape=[num_of_networks]) g2.create_dataset('MISE_psi', shape=[num_of_networks]) g2.create_dataset('MISE_S', shape=[num_of_networks]) g2.create_dataset('MISE_C', shape=[num_of_networks]) f.close() R = 500 for i in range(num_of_networks): print 'N=%d' % ((i + 1) * N) D = transforms.compute_D((i + 1) * N, O) theta_all = numpy.empty([T, D]) triu_idx = numpy.triu_indices(N, k=1) triu_idx_all = numpy.triu_indices((i + 1) * N, k=1) for j in range(i + 1): theta_all[:, N * j:(j + 1) * N] = thetas[j, :, :N] for t in range(T): theta_ij = numpy.zeros([(i + 1) * N, (i + 1) * N]) for j in range(i + 1): theta_ij[triu_idx[0] + j * N, triu_idx[1] + j * N] = \ thetas[j, t, N:] theta_all[t, (i + 1) * N:] = theta_ij[triu_idx_all] spikes = synthesis.generate_spikes_gibbs_parallel(theta_all, (i + 1) * N, O, R, sample_steps=10, num_proc=4) emd = __init__.run(spikes, O, map_function='cg', param_est='pseudo', param_est_eta='bethe_hybrid', lmbda1=100, lmbda2=200) eta_est = numpy.empty(emd.theta_s.shape) psi_est = numpy.empty(T) S_est = numpy.empty(T) C_est = numpy.empty(T) for t in range(T): eta_est[t], psi_est[t] = \ bethe_approximation.compute_eta_hybrid(emd.theta_s[t], (i + 1) * N, return_psi=1) psi1 = bethe_approximation.compute_eta_hybrid(.999 * emd.theta_s[t], (i + 1) * N, return_psi=1)[1] psi2 = bethe_approximation.compute_eta_hybrid( 1.001 * emd.theta_s[t], (i + 1) * N, return_psi=1)[1] S_est[t] = -(numpy.sum(eta_est[t] * emd.theta_s[t]) - psi_est[t]) C_est[t] = (psi1 - 2. * psi_est[t] + psi2) / .001 ** 2 S_est /= numpy.log(2) C_est /= numpy.log(2) population_rate = numpy.mean(numpy.mean(etas[:i + 1, :, :N], axis=0), axis=1) population_rate_est = numpy.mean(eta_est[:, :(i + 1) * N], axis=1) psi_true = numpy.sum(psi[:(i + 1), :], axis=0) S_true = numpy.sum(S[:(i + 1), :], axis=0) C_true = numpy.sum(C[:(i + 1), :], axis=0) f = h5py.File(data_path + 'figure2data.h5', 'r+') f['error500']['MISE_thetas'][i] = numpy.mean( (theta_all - emd.theta_s) ** 2) f['error500']['MISE_population_rate'][i] = numpy.mean( (population_rate - population_rate_est) ** 2) f['error500']['MISE_psi'][i] = numpy.mean((psi_est - psi_true) ** 2) f['error500']['MISE_S'][i] = numpy.mean((S_est - S_true) ** 2) f['error500']['MISE_C'][i] = numpy.mean((C_est - C_true) ** 2) f['error500']['population_rate'][i] = population_rate_est f['error500']['psi'][i] = psi_est f['error500']['S'][i] = S_est f['error500']['C'][i] = C_est f.close()
# p_silence p_silence = numpy.exp(-psi) # p_spike p_spike = numpy.mean(eta[:, :N], axis=1) # Heat capacity tmp1 = numpy.zeros((T, )) tmp2 = numpy.zeros((T, )) if exact: for t in range(T): tmp1[t] = transforms.compute_psi(theta_sampled[t, :] * (1 + epsilon)) tmp2[t] = transforms.compute_psi(theta_sampled[t, :] * (1 - epsilon)) else: for t in range(T): tmp1[t] = bethe_approximation.compute_eta_hybrid( theta_sampled[t, :] * (1 + epsilon), N, return_psi=True)[1] tmp2[t] = bethe_approximation.compute_eta_hybrid( theta_sampled[t, :] * (1 - epsilon), N, return_psi=True)[1] c = tmp1 - 2 * psi + tmp2 d = epsilon**2 C = c / d # Entropy (1st order) eta_ind = eta[:, :N] theta_ind = energies.compute_ind_theta(eta_ind) psi_ind = energies.compute_ind_psi(theta_ind) S1 = energies.compute_entropy(theta_ind, eta_ind, psi_ind, 1) # Entropy ratio ratio = (S1 - S2) / (S0 - S2) # Record results physics_matrix[n, 2, :] = p_spike physics_matrix[n, 3, :] = p_silence