def bp_update_params_new(args): lmds, pis = args.lmds, args.pis vert_parent, vert_children = args.vert_parent, args.vert_children #print pis[0].shape I, T, L = args.X.shape K = args.gamma.shape[0] theta, alpha, beta, gamma, emit_probs, X = (args.theta, args.alpha, args.beta, args.gamma, args.emit_probs, args.X) evidence = args.evidence #evid_allchild(lmds, vert_children) emit_probs_mat = sp.exp(args.log_obs_mat) #emit_probs_mat /= emit_probs_mat.max(axis=2).reshape(I, T, 1) gamma_p = copy.copy(gamma) alpha_p = copy.copy(alpha) beta_p = copy.copy(beta) theta_p = copy.copy(theta) emit_probs_p = copy.copy(emit_probs) theta[:] = args.pseudocount alpha[:] = args.pseudocount beta[:] = args.pseudocount gamma[:] = args.pseudocount emit_probs[:] = args.pseudocount #evidence = evid_allchild(lmds, args.vert_children) ##support = casual_support(pis) emit_sum = sp.zeros(K) for i in xrange(I): vp = vert_parent[i] for t in xrange(T): if i==0 and t==0: gamma += emit_probs_mat[i, t, :]*evidence[i,t,:] Q = emit_probs_mat[i, t, :]*evidence[i,t,:] else: if i == 0: tmp1, tmp2 = sp.ix_(pis[i][-1,t-1,:], emit_probs_mat[i, t, :]*evidence[i,t,:]) tmp = alpha_p * (tmp1*tmp2) #tmp /= tmp.sum() Q = tmp.sum(axis=0) alpha += tmp/tmp.sum() elif t == 0: tmp1, tmp2 = sp.ix_(pis[vp][i-1,t,:], emit_probs_mat[i, t, :]*evidence[i,t,:]) tmp = beta_p *(tmp1*tmp2) Q = tmp.sum(axis=0) beta += tmp/tmp.sum() else: tmp1, tmp2, tmp3 = sp.ix_(pis[vp][i-1,t,:], pis[i][-1, t-1,:], emit_probs_mat[i, t, :]*evidence[i,t,:]) tmp = theta_p *(tmp1*tmp2 *tmp3) Q = (tmp.sum(axis=0)).sum(axis=0) theta += tmp/tmp.sum() Q /= Q.sum() for l in xrange(L): if X[i,t,l]: emit_probs[:, l] += Q emit_sum += Q normalize_trans(theta, alpha, beta, gamma) emit_probs[:] = sp.dot(sp.diag(1./emit_sum), emit_probs) args.emit_sum = emit_sum make_log_obs_matrix(args)
def params_from_clique_marginals(theta, alpha, beta, gamma, emit_probs, clq_Q, clq_Q_pairs, X, args): """Recompute parameters using marginal probabilities""" I, T, L = X.shape K = gamma.shape[0] vp = 0 pc = 1e-10 # pseudocount theta[:] = pc alpha[:] = pc beta[:] = pc gamma[:] = pc emit_probs[:] = pc #theta[:] = 0; alpha[:] = 0; beta[:] = 0; gamma[:] = 0; emit_probs[:] = 0 global combinations combinations = list(enumerate(itertools.product(range(K), repeat=I))) #e_sum = sp.ones(emit_probs.shape[0]) * pc e_sum = sp.ones_like(emit_probs) * pc #e_sum = sp.ones(emit_probs.shape[1]) * 0 t = 0 for k_to, to_val in combinations: for i in xrange(I): for l in xrange(L): if X[i, t, l]: emit_probs[to_val[i], l] += clq_Q[t, k_to] #e_sum[to_val[i]] += clq_Q[t, k_to] e_sum[to_val[i], l] += clq_Q[t, k_to] gamma[to_val[vp]] += clq_Q[t, k_to] for i in xrange(1, I): beta[to_val[vp], to_val[i]] += clq_Q[t, k_to] #import ipdb; ipdb.set_trace() for t in xrange(1, T): for k_to, to_val in combinations: for i in xrange(I): for l in xrange(L): if X[i, t, l]: #import ipdb; ipdb.set_trace() emit_probs[to_val[i], l] += clq_Q[t, k_to] #e_sum[to_val[i]] += clq_Q[t, k_to] e_sum[to_val[i], l] += clq_Q[t, k_to] for k_from, from_val in combinations: alpha[from_val[vp], to_val[vp]] += clq_Q_pairs[t, k_from, k_to] for i in xrange(1, I): theta[to_val[vp], from_val[i], to_val[i]] += clq_Q_pairs[t, k_from, k_to] #import ipdb; ipdb.set_trace() #theta, alpha, beta, gamma = theta+pc*theta.max(), alpha+pc*alpha.max(),beta+pc*beta.max(),gamma+pc*gamma.max() normalize_trans(theta, alpha, beta, gamma) #emit_probs[:] = sp.dot(sp.diag(1./e_sum), emit_probs) #emit_probs[:] = sp.dot(emit_probs, sp.diag(1./e_sum * L)) emit_probs[:] = emit_probs / e_sum #emit_probs[:] = sp.dot(emit_probs + pc*emit_probs.max(), sp.diag(1./(e_sum + pc*emit_probs.max()))) args.emit_sum = e_sum
def params_from_clique_marginals(theta, alpha, beta, gamma, emit_probs, clq_Q, clq_Q_pairs, X, args): """Recompute parameters using marginal probabilities""" I,T,L = X.shape K = gamma.shape[0] vp = 0 pc = 1e-10 # pseudocount theta[:] = pc; alpha[:] = pc; beta[:] = pc; gamma[:] = pc; emit_probs[:] = pc #theta[:] = 0; alpha[:] = 0; beta[:] = 0; gamma[:] = 0; emit_probs[:] = 0 global combinations combinations = list(enumerate(itertools.product(range(K), repeat=I))) #e_sum = sp.ones(emit_probs.shape[0]) * pc e_sum = sp.ones_like(emit_probs) * pc #e_sum = sp.ones(emit_probs.shape[1]) * 0 t = 0 for k_to, to_val in combinations: for i in xrange(I): for l in xrange(L): if X[i,t,l]: emit_probs[to_val[i], l] += clq_Q[t, k_to] #e_sum[to_val[i]] += clq_Q[t, k_to] e_sum[to_val[i], l] += clq_Q[t, k_to] gamma[to_val[vp]] += clq_Q[t,k_to] for i in xrange(1, I): beta[to_val[vp], to_val[i]] += clq_Q[t,k_to] #import ipdb; ipdb.set_trace() for t in xrange(1, T): for k_to, to_val in combinations: for i in xrange(I): for l in xrange(L): if X[i,t,l]: #import ipdb; ipdb.set_trace() emit_probs[to_val[i], l] += clq_Q[t, k_to] #e_sum[to_val[i]] += clq_Q[t, k_to] e_sum[to_val[i], l] += clq_Q[t, k_to] for k_from, from_val in combinations: alpha[from_val[vp], to_val[vp]] += clq_Q_pairs[t,k_from, k_to] for i in xrange(1, I): theta[to_val[vp], from_val[i], to_val[i]] += clq_Q_pairs[t,k_from, k_to] #import ipdb; ipdb.set_trace() #theta, alpha, beta, gamma = theta+pc*theta.max(), alpha+pc*alpha.max(),beta+pc*beta.max(),gamma+pc*gamma.max() normalize_trans(theta, alpha, beta, gamma) #emit_probs[:] = sp.dot(sp.diag(1./e_sum), emit_probs) #emit_probs[:] = sp.dot(emit_probs, sp.diag(1./e_sum * L)) emit_probs[:] = emit_probs / e_sum #emit_probs[:] = sp.dot(emit_probs + pc*emit_probs.max(), sp.diag(1./(e_sum + pc*emit_probs.max()))) args.emit_sum = e_sum
def do_parallel_inference(args): """Perform inference in parallel on several observations matrices with joint parameters """ from histone_tree_hmm import random_params, do_inference, plot_params, plot_energy, load_params from vb_mf import normalize_trans args.I, _, args.L = sp.load(args.observe_matrix[0]).shape K = args.K L = args.L args.T = 'all' args.free_energy = [] args.observe = 'all.npy' args.last_free_energy = 0 args.emit_sum = 0 args.out_dir = args.out_dir.format(timestamp=time.strftime('%x_%X').replace('/','-'), **args.__dict__) try: print 'making', args.out_dir os.makedirs(args.out_dir) except OSError: pass if args.warm_start: #args.last_free_energy, args.theta, args.alpha, args.beta, args.gamma, args.emit_probs, args.emit_sum = load_params(args) #args.warm_start = False print '# loading previous params for warm start from %s' % args.warm_start tmpargs = copy.deepcopy(args) tmpargs.out_dir = args.warm_start tmpargs.observe = 'all.npy' args.free_energy, args.theta, args.alpha, args.beta, args.gamma, args.emit_probs, args.emit_sum = load_params(tmpargs) try: args.free_energy = list(args.free_energy) except TypeError: # no previous free energy args.free_energy = [] print 'done' args.warm_start = False else: (args.theta, args.alpha, args.beta, args.gamma, args.emit_probs) = \ random_params(args.K,args.L) for p in ['free_energy', 'theta', 'alpha', 'beta', 'gamma', 'emit_probs', 'last_free_energy', 'emit_sum']: sp.save(os.path.join(args.out_dir, args.out_params.format(param=p, **args.__dict__)), args.__dict__[p]) print '# setting up job arguments' # set up new versions of args for other jobs job_args = [copy.copy(args) for i in range(len(args.observe_matrix))] for j, a in enumerate(job_args): a.observe_matrix = args.observe_matrix[j] a.observe = os.path.split(args.observe_matrix[j])[1] a.subtask = True a.func = None a.iteration = 0 a.max_iterations = 1 a.quiet_mode = True if j % 1000 == 0: print j if args.run_local: pool = multiprocessing.Pool() else: pool = sge.SGEPool() job_handle = pool.imap_unordered(do_inference, job_args) converged = False for args.iteration in range(args.max_iterations): #import ipdb; ipdb.set_trace() # fresh parameters-- to be aggregated after jobs are run print 'iteration', args.iteration total_free = 0 args.theta = sp.zeros((K,K,K), dtype=sp.float64) args.alpha = sp.zeros((K,K), dtype=sp.float64) args.beta = sp.zeros((K,K), dtype=sp.float64) args.gamma = sp.zeros((K), dtype=sp.float64) args.emit_probs = sp.zeros((K,L), dtype=sp.float64) args.emit_sum = sp.zeros(K, sp.float64) if args.run_local: iterator = pool.imap_unordered(do_inference, job_args) # wait for jobs to finish for result in iterator: pass else: jobs_handle = pool.map_async(do_inference, job_args, chunksize=100) # wait for all jobs to finish for j in jobs_handle: j.wait() # sum free energies and parameters from jobs for a in job_args: #print '# loading from %s' % a.observe free_energy, theta, alpha, beta, gamma, emit_probs, emit_sum = load_params(a) if len(free_energy) > 0: last_free_energy = free_energy[-1] else: last_free_energy = 0 total_free += last_free_energy args.theta += theta args.alpha += alpha args.beta += beta args.gamma += gamma args.emit_probs += emit_probs args.emit_sum += emit_sum # renormalize and plot print 'normalize aggregation... total free energy is:', total_free args.free_energy.append(total_free) if len(args.free_energy) > 1 and args.free_energy[-1] != 0 and args.free_energy[-2] != 0 \ and abs(args.free_energy[-2] - args.free_energy[-1]) / args.free_energy[-2] < args.epsilon: converged = True normalize_trans(args.theta, args.alpha, args.beta, args.gamma) args.emit_probs[:] = sp.dot(sp.diag(1./args.emit_sum), args.emit_probs) for a in job_args: a.theta, a.alpha, a.beta, a.gamma, a.emit_probs = args.theta, args.alpha, args.beta, args.gamma, args.emit_probs for p in ['free_energy', 'theta', 'alpha', 'beta', 'gamma', 'emit_probs']: sp.save(os.path.join(args.out_dir, args.out_params.format(param=p, **args.__dict__)), args.__dict__[p]) plot_params(args) plot_energy(args) if args.save_Q >= 3: print '# reconstructing chromosomes from *chunk*', in_order = {} # Q_chr16_all.trimmed.chunk*.npy => Q_chr16_all.trimmed.npy all_chunks = glob.glob(os.path.join(args.out_dir, '*_Q_*chunk*.npy')) for chunk in all_chunks: print chunk chunk_num = int(re.search(r'chunk(\d+)', chunk).groups()[0]) chrom_out = re.sub('chunk(\d+)\.', '', chunk) if chrom_out not in in_order: in_order[chrom_out] = {} in_order[chrom_out][chunk_num] = sp.load(chunk) for chrom_out in in_order: print 'reconstructing chromosomes from', in_order[chrom_out] if len(in_order[chrom_out]) > 1: final_array = sp.concatenate((in_order[chrom_out][0], in_order[chrom_out][1]), axis=1) for i in range(2, max(in_order[chrom_out])): final_array = sp.concatenate((final_array, in_order[chrom_out][i]), axis=1) else: final_array = in_order[chrom_out][0] sp.save(chrom_out, final_array) if converged: break
def independent_update_params(args, renormalize=True): X = args.X Q, Q_pairs, theta, alpha, beta, gamma, vert_parent, vert_children, log_obs_mat, pseudocount = ( args.Q, args.Q_pairs, args.theta, args.alpha, args.beta, args.gamma, args.vert_parent, args.vert_children, args.log_obs_mat, args.pseudocount) I, T, K = Q.shape L = X.shape[2] if args.continuous_observations: new_means = np.zeros_like(args.means) new_variances = np.zeros_like(args.variances) total_q = np.zeros_like(args.variances) else: emit_probs = args.emit_probs emit_probs[:] = pseudocount theta[:] = pseudocount alpha[:] = pseudocount beta[:] = pseudocount gamma[:] = pseudocount for i in xrange(I): vp = vert_parent[i] for t in xrange(T): for k in xrange(K): if i==0 and t==0: gamma[k] += Q[i, t, k] else: for v in xrange(K): if t == 0: beta[v,k] += Q[vp,t,v] * Q[i,t,k] else: alpha[v,k] += Q_pairs[i,t,v,k] if not args.continuous_observations: for l in xrange(L): if X[i,t,l]: emit_probs[k, l] += Q[i, t, k] if args.continuous_observations: for i in xrange(I): for t in xrange(T): for k in xrange(K): for l in xrange(L): new_means[k,l] += Q[i, t, k] * X[i,t,l] # expectation of X wrt Q total_q[k,l] += Q[i,t,k] args.means[:] = new_means = new_means / total_q + 1e-50 np.seterr(under='ignore') for i in xrange(I): for t in xrange(T): for k in xrange(K): for l in xrange(L): new_variances[k,l] += Q[i, t, k] * (X[i,t,l] - new_means[k,l]) * (X[i,t,l] - new_means[k,l]) np.seterr(under='print') args.variances[:] = new_variances / total_q # 1 / N_k args.variances += pseudocount else: normalize_emit(Q, emit_probs, pseudocount, args, renormalize) if renormalize: theta += theta.max() * (pseudocount * 1e-20) alpha += alpha.max() * (pseudocount * 1e-20) beta += beta.max() * (pseudocount * 1e-20) gamma += gamma.max() * (pseudocount * 1e-20) normalize_trans(theta, alpha, beta, gamma) if args.continuous_observations: make_log_obs_matrix_gaussian(args) else: make_log_obs_matrix(args)
def independent_update_params(args, renormalize=True): X = args.X Q, Q_pairs, theta, alpha, beta, gamma, vert_parent, vert_children, log_obs_mat, pseudocount = ( args.Q, args.Q_pairs, args.theta, args.alpha, args.beta, args.gamma, args.vert_parent, args.vert_children, args.log_obs_mat, args.pseudocount) I, T, K = Q.shape L = X.shape[2] if args.continuous_observations: new_means = np.zeros_like(args.means) new_variances = np.zeros_like(args.variances) total_q = np.zeros_like(args.variances) else: emit_probs = args.emit_probs emit_probs[:] = pseudocount theta[:] = pseudocount alpha[:] = pseudocount beta[:] = pseudocount gamma[:] = pseudocount for i in xrange(I): vp = vert_parent[i] for t in xrange(T): for k in xrange(K): if i == 0 and t == 0: gamma[k] += Q[i, t, k] else: for v in xrange(K): if t == 0: beta[v, k] += Q[vp, t, v] * Q[i, t, k] else: alpha[v, k] += Q_pairs[i, t, v, k] if not args.continuous_observations: for l in xrange(L): if X[i, t, l]: emit_probs[k, l] += Q[i, t, k] if args.continuous_observations: for i in xrange(I): for t in xrange(T): for k in xrange(K): for l in xrange(L): new_means[k, l] += Q[i, t, k] * X[i, t, l] # expectation of X wrt Q total_q[k, l] += Q[i, t, k] args.means[:] = new_means = new_means / total_q + 1e-50 np.seterr(under='ignore') for i in xrange(I): for t in xrange(T): for k in xrange(K): for l in xrange(L): new_variances[k, l] += Q[i, t, k] * ( X[i, t, l] - new_means[k, l]) * (X[i, t, l] - new_means[k, l]) np.seterr(under='print') args.variances[:] = new_variances / total_q # 1 / N_k args.variances += pseudocount else: normalize_emit(Q, emit_probs, pseudocount, args, renormalize) if renormalize: theta += theta.max() * (pseudocount * 1e-20) alpha += alpha.max() * (pseudocount * 1e-20) beta += beta.max() * (pseudocount * 1e-20) gamma += gamma.max() * (pseudocount * 1e-20) normalize_trans(theta, alpha, beta, gamma) if args.continuous_observations: make_log_obs_matrix_gaussian(args) else: make_log_obs_matrix(args)
def bp_update_params_new(args, renormalize=True): lmds, pis = args.lmds, args.pis vert_parent, vert_children = args.vert_parent, args.vert_children #print pis[0].shape I, T, L = args.X.shape K = args.gamma.shape[0] theta, alpha, beta, gamma, emit_probs, X = (args.theta, args.alpha, args.beta, args.gamma, args.emit_probs, args.X) evidence = args.evidence #evid_allchild(lmds, vert_children) emit_probs_mat = sp.exp(args.log_obs_mat) #emit_probs_mat /= emit_probs_mat.max(axis=2).reshape(I, T, 1) gamma_p = copy.copy(gamma) alpha_p = copy.copy(alpha) beta_p = copy.copy(beta) theta_p = copy.copy(theta) # emit_probs_p = copy.copy(emit_probs) theta[:] = args.pseudocount alpha[:] = args.pseudocount beta[:] = args.pseudocount gamma[:] = args.pseudocount emit_probs[:] = args.pseudocount #evidence = evid_allchild(lmds, args.vert_children) ##support = casual_support(pis) emit_sum = sp.zeros((K, L)) for i in xrange(I): vp = vert_parent[i] if i != 0: idx_i = vert_children[vp].tolist().index(i) for t in xrange(T): if i == 0 and t == 0: gamma += emit_probs_mat[i, t, :] * evidence[i, t, :] Q = emit_probs_mat[i, t, :] * evidence[i, t, :] elif i == 0: tmp1, tmp2 = sp.ix_( pis[i][-1, t - 1, :], emit_probs_mat[i, t, :] * evidence[i, t, :]) tmp = alpha_p * (tmp1 * tmp2) # belief #tmp /= tmp.sum() Q = tmp.sum(axis=0) alpha += tmp / tmp.sum() elif t == 0: tmp1, tmp2 = sp.ix_(pis[vp][idx_i, t, :], emit_probs_mat[i, t, :] * evidence[i, t, :]) # i-1->0 tmp = beta_p * (tmp1 * tmp2) # belief Q = tmp.sum(axis=0) beta += tmp / tmp.sum() else: tmp1, tmp2, tmp3 = sp.ix_( pis[vp][idx_i, t, :], pis[i][-1, t - 1, :], emit_probs_mat[i, t, :] * evidence[i, t, :]) tmp = theta_p * (tmp1 * tmp2 * tmp3) Q = (tmp.sum(axis=0)).sum(axis=0) theta += tmp / tmp.sum() Q /= Q.sum() for l in xrange(L): if args.mark_avail[i, l] and X[i, t, l]: emit_probs[:, l] += Q emit_sum[:, l] += Q if renormalize: normalize_trans(theta, alpha, beta, gamma) emit_probs[:] = sp.dot(sp.diag(1. / emit_sum), emit_probs) args.emit_sum = emit_sum make_log_obs_matrix(args)