def propose(self,trace,scaffold): self.trace = trace self.scaffold = scaffold if not registerVariationalLKernels(trace,scaffold): self.delegate = MHOperator() return self.delegate.propose(trace,scaffold) _,self.rhoDB = detachAndExtract(trace,scaffold.border[0],scaffold) assertTorus(scaffold) for _ in range(self.numIters): gradients = {} gain = regenAndAttach(trace,scaffold.border[0],scaffold,False,OmegaDB(),gradients) detachAndExtract(trace,scaffold.border[0],scaffold) assertTorus(scaffold) for node,lkernel in scaffold.lkernels.iteritems(): if isinstance(lkernel,VariationalLKernel): assert node in gradients lkernel.updateParameters(gradients[node],gain,self.stepSize) rhoWeight = regenAndAttach(trace,scaffold.border[0],scaffold,True,self.rhoDB,{}) detachAndExtract(trace,scaffold.border[0],scaffold) assertTorus(scaffold) xiWeight = regenAndAttach(trace,scaffold.border[0],scaffold,False,OmegaDB(),{}) return trace,xiWeight - rhoWeight
def propose(self,trace,scaffold): from particle import Particle self.trace = trace self.scaffold = scaffold assertTrace(self.trace,self.scaffold) #print map(len, scaffold.border) self.T = len(self.scaffold.border) T = self.T P = self.P # assert T == 1 # TODO temporary rhoDBs = [None for t in range(T)] rhoWeights = [None for t in range(T)] for t in reversed(range(T)): rhoWeights[t],rhoDBs[t] = detachAndExtract(trace,scaffold.border[t],scaffold) assertTorus(scaffold) particles = [Particle(trace) for p in range(P+1)] self.particles = particles particleWeights = [None for p in range(P+1)] # Simulate and calculate initial xiWeights for p in range(P): particleWeights[p] = regenAndAttach(particles[p],scaffold.border[0],scaffold,False,OmegaDB(),{}) particleWeights[P] = regenAndAttach(particles[P],scaffold.border[0],scaffold,True,rhoDBs[0],{}) assert_almost_equal(particleWeights[P],rhoWeights[0]) # for every time step, for t in range(1,T): newParticles = [None for p in range(P+1)] newParticleWeights = [None for p in range(P+1)] # Sample new particle and propagate for p in range(P): parent = sampleLogCategorical(particleWeights) newParticles[p] = Particle(particles[parent]) newParticleWeights[p] = regenAndAttach(newParticles[p],self.scaffold.border[t],self.scaffold,False,OmegaDB(),{}) newParticles[P] = Particle(particles[P]) newParticleWeights[P] = regenAndAttach(newParticles[P],self.scaffold.border[t],self.scaffold,True,rhoDBs[t],{}) assert_almost_equal(newParticleWeights[P],rhoWeights[t]) particles = newParticles particleWeights = newParticleWeights # Now sample a NEW particle in proportion to its weight finalIndex = sampleLogCategorical(particleWeights[0:-1]) assert finalIndex < P self.finalIndex = finalIndex self.particles = particles return particles[finalIndex],self._compute_alpha(particleWeights, finalIndex)
def makeConsistent(self,trace,indexer): # Go through every local child and do extra and regen. # This is to be called at the end of a number of transitions. if not hasattr(self, "global_scaffold"): self.global_scaffold = indexer.sampleGlobalIndex(trace) for local_child in self.global_scaffold.local_children: local_scaffold = indexer.sampleLocalIndex(trace,local_child) _,local_rhoDB = detachAndExtract(trace, local_scaffold.border[0], local_scaffold) regenAndAttach(trace,local_scaffold.border[0],local_scaffold,False,local_rhoDB,{})
def reject(self): # TODO This is the same as MHOperator reject except for the # delegation thing -- abstract if self.delegate is None: detachAndExtract(self.trace,self.scaffold.border[0],self.scaffold) assertTorus(self.scaffold) regenAndAttach(self.trace,self.scaffold.border[0],self.scaffold,True,self.rhoDB,{}) else: self.delegate.reject()
def propose(self,trace,scaffold): self.trace = trace self.scaffold = scaffold assertTrace(self.trace,self.scaffold) self.T = len(self.scaffold.border) T = self.T P = self.P rhoWeights = [None for t in range(T)] omegaDBs = [[None for p in range(P+1)] for t in range(T)] ancestorIndices = [[None for p in range(P)] + [P] for t in range(T)] self.omegaDBs = omegaDBs self.ancestorIndices = ancestorIndices for t in reversed(range(T)): (rhoWeights[t],omegaDBs[t][P]) = detachAndExtract(trace,scaffold.border[t],scaffold) assertTorus(scaffold) xiWeights = [None for p in range(P)] # Simulate and calculate initial xiWeights for p in range(P): regenAndAttach(trace,scaffold.border[0],scaffold,False,OmegaDB(),{}) (xiWeights[p],omegaDBs[0][p]) = detachAndExtract(trace,scaffold.border[0],scaffold) # for every time step, for t in range(1,T): newWeights = [None for p in range(P)] # Sample new particle and propagate for p in range(P): extendedWeights = xiWeights + [rhoWeights[t-1]] ancestorIndices[t][p] = sampleLogCategorical(extendedWeights) path = constructAncestorPath(ancestorIndices,t,p) restoreAncestorPath(trace,self.scaffold.border,self.scaffold,omegaDBs,t,path) regenAndAttach(trace,self.scaffold.border[t],self.scaffold,False,OmegaDB(),{}) (newWeights[p],omegaDBs[t][p]) = detachAndExtract(trace,self.scaffold.border[t],self.scaffold) detachRest(trace,self.scaffold.border,self.scaffold,t) xiWeights = newWeights # Now sample a NEW particle in proportion to its weight finalIndex = sampleLogCategorical(xiWeights) path = constructAncestorPath(ancestorIndices,T-1,finalIndex) + [finalIndex] assert len(path) == T restoreAncestorPath(trace,self.scaffold.border,self.scaffold,omegaDBs,T,path) assertTrace(self.trace,self.scaffold) return trace,self._compute_alpha(rhoWeights[T-1], xiWeights, finalIndex)
def evalOneLocalSection(self, trace, local_scaffold, compute_gradient = False): assert(self.global_scaffold.globalBorder is not None) # Detach and extract _,local_rhoDB = detachAndExtract(trace, local_scaffold.border[0], local_scaffold, compute_gradient) # Regen and attach with the old value proposed_value = trace.valueAt(self.global_scaffold.globalBorder) trace.setValueAt(self.global_scaffold.globalBorder, self.global_rhoDB.getValue(self.global_scaffold.globalBorder)) regenAndAttach(trace,local_scaffold.border[0],local_scaffold,False,local_rhoDB,{}) # Detach and extract rhoWeight,local_rhoDB = detachAndExtract(trace, local_scaffold.border[0], local_scaffold, compute_gradient) # Regen and attach with the new value trace.setValueAt(self.global_scaffold.globalBorder, proposed_value) xiWeight = regenAndAttach(trace,local_scaffold.border[0],local_scaffold,False,local_rhoDB,{}) return xiWeight - rhoWeight
def propose(self,trace,scaffold): from particle import Particle assertTrace(trace,scaffold) pnodes = scaffold.getPrincipalNodes() currentValues = getCurrentValues(trace,pnodes) allSetsOfValues = getCartesianProductOfEnumeratedValues(trace,pnodes) registerDeterministicLKernels(trace,scaffold,pnodes,currentValues) detachAndExtract(trace,scaffold.border[0],scaffold) assertTorus(scaffold) xiWeights = [] xiParticles = [] for p in range(len(allSetsOfValues)): newValues = allSetsOfValues[p] xiParticle = Particle(trace) assertTorus(scaffold) registerDeterministicLKernels(trace,scaffold,pnodes,newValues) xiParticles.append(xiParticle) xiWeights.append(regenAndAttach(xiParticle,scaffold.border[0],scaffold,False,OmegaDB(),{})) # Now sample a NEW particle in proportion to its weight finalIndex = sampleLogCategorical(xiWeights) self.finalParticle = xiParticles[finalIndex] return self.finalParticle,0
def propose(self, trace, scaffold): self.prepare(trace, scaffold) logBound = computeRejectionBound(trace, scaffold, scaffold.border[0]) accept = False while not accept: xiWeight = regenAndAttach(trace, scaffold.border[0], scaffold, False, self.rhoDB, {}) accept = random.random() < math.exp(xiWeight - logBound) if not accept: detachAndExtract(trace, scaffold.border[0], scaffold) return trace, 0
def fixed_regen(self, values): # Ensure repeatability of randomness cur_pyr_state = random.getstate() cur_numpyr_state = npr.get_state() try: random.setstate(self.pyr_state) npr.set_state(self.numpyr_state) registerDeterministicLKernels(self.trace, self.scaffold, self.pnodes, values) answer = regenAndAttach(self.trace, self.scaffold.border[0], self.scaffold, False, OmegaDB(), {}) finally: random.setstate(cur_pyr_state) npr.set_state(cur_numpyr_state) return answer
def propose(self, trace, global_scaffold): rhoWeight = self.prepare(trace, global_scaffold) xiWeight = regenAndAttach(trace,global_scaffold.border[0],global_scaffold,False,self.global_rhoDB,{}) return trace, xiWeight - rhoWeight
def reject(self): detachAndExtract(self.trace,self.scaffold.border[0],self.scaffold) assertTorus(self.scaffold) regenAndAttach(self.trace,self.scaffold.border[0],self.scaffold,True,self.rhoDB,{})
def reject(self): # Only restore the global section. detachAndExtract(self.trace,self.global_scaffold.border[0],self.global_scaffold) assertTorus(self.global_scaffold) regenAndAttach(self.trace,self.global_scaffold.border[0],self.global_scaffold,True,self.global_rhoDB,{})
def propose(self, trace, scaffold): program = trace.proposal_programs[self.program_name] pnodes = [node for tar in program.tlist for node in trace.getNodesInBlock(tar[0],tar[1])] cnodes = [node for cond in program.clist for node in trace.scopes[cond[0]][cond[1]]] # drawScaffoldKernel(trace,scaffold,pnodes,cnodes,program.tlist,program.clist) try: assert len(pnodes) == program.n_target except: raise(Exception('Expect to have one and only one random node in a block. Check if 1) multiple nodes are defined in a target block; 2) some target nodes are observed (and thus not random).')) old_target = [node.value.number for node in pnodes] conditioned = [node.value.number for node in cnodes] # print conditioned registerDeterministicLKernels(trace,scaffold,pnodes,map(lambda x:VentureNumber(x),old_target)) rhoWeight = self.prepare(trace, scaffold) # print "CustomMHOperator rhoWeight: ", rhoWeight, "old_target: ", old_target # print rhoWeight # TODO: get conditioned values # TODO: invoke program, get target values and qratio from proposal # print 'cond:', conditioned # print 'old tar:', old_target # (new_target, qratio) = program.propose(conditioned,old_target) conditioned_labels, latent_labels, target_labels = [], [], [] conditioned_src = program.gen_conditioned_src(conditioned) if conditioned_src: (conditioned_labels, conditioned_strings, _) = execute_and_record(program.ripl, conditioned_src, "conditioned") latent_src = program.gen_latent_src(conditioned) if latent_src: (latent_labels, latent_strings, _) = execute_and_record(program.ripl, latent_src, "latent") target_src = program.gen_target_src(conditioned) if target_src: (target_labels, target_strings, new_target) = execute_and_record(program.ripl, target_src, "target") else: raise(Exception("No target_src found. Procedure 'gen_target_src' must be specified.")) for label in reversed(target_labels): program.ripl.forget(label) if self.method == 'assumed_gibbs': qratio = 1e10 else: old_logscores, new_logscores = [], [] if not latent_src: self.mc_samples = 1 for i in range(self.mc_samples): predict_to_observe(program.ripl, target_strings, new_target) new_logscores.append(sum_directive_logscore(program.ripl, target_labels)) for label in reversed(target_labels): program.ripl.forget(label) predict_to_observe(program.ripl, target_strings, old_target) old_logscores.append(sum_directive_logscore(program.ripl, target_labels)) for label in reversed(target_labels): program.ripl.forget(label) for label in reversed(latent_labels): program.ripl.forget(label) execute_and_record(program.ripl, latent_src, "latent") old_logscore = logaddexp(old_logscores) new_logscore = logaddexp(new_logscores) qratio = old_logscore - new_logscore # print "CustomMHOperator old_logscores: ", old_logscores, "CustomMHOperator new_logscores: ", new_logscores for label in reversed(latent_labels): program.ripl.forget(label) for label in reversed(conditioned_labels): program.ripl.forget(label) # print map(lambda x:VentureNumber(x),new_target) # TODO: use DeterministicLKernel to fill in new target values registerDeterministicLKernels(trace,scaffold,pnodes,map(lambda x:VentureNumber(x),new_target)) # TODO: get xiWeight # print scaffold.border[0] xiWeight = regenAndAttach(trace,scaffold.border[0],scaffold,False,OmegaDB(),{}) # print "CustomMHOperator xiWeight: ", xiWeight, "new_target: ", new_target # print "CustomMHOperator qratio: ", qratio # TODO: return (new_trace, xiWeight + qratio - rhoWeight) # print '=====================' # print 'new_target', new_target # print 'xiWeight:', xiWeight # print 'qratio:', qratio # print 'rhoWeight:', rhoWeight return (trace, xiWeight + qratio - rhoWeight)
def restoreAncestorPath(trace,border,scaffold,omegaDBs,t,path): for i in range(t): selectedDB = omegaDBs[i][path[i]] regenAndAttach(trace,border[i],scaffold,True,selectedDB,{})