def _eval_weight_gradients_per_var(self, v_w, nodes): wgts = [] Hcond = [] for node in nodes: sc = self.mg.message_graph.node[node]['sc'] mu_p = self.mg.message_graph.node[node]['pseudo_belief'].marginal(sc) # mu_p = self.mg.message_graph.node[node]['pseudo_belief'] elimvars_in_node = sorted(sc, key=lambda x: self.elim_order.index(x)) v_w_ind = elimvars_in_node.index(v_w) mu_p_temp1 = mu_p.marginal(elimvars_in_node[v_w_ind:]) # P(xi, xi+1~) if type(mu_p_temp1) is not Factor: mu_p_temp1 = Factor({}, mu_p_temp1) if np.all(mu_p_temp1.t == 0): # when mu_u_temp1 is all zero factor, raise assertion error H1_p = 0.0 else: H1_p = mu_p_temp1.entropy() if v_w_ind + 1 < len(elimvars_in_node): mu_p_temp2 = mu_p.marginal(elimvars_in_node[v_w_ind + 1:]) # P(xi+1 , xi+2 ~) if type(mu_p_temp2) is not Factor: mu_p_temp2 = Factor({}, mu_p_temp2) if np.all(mu_p_temp2.t == 0): H2_p = 0.0 else: H2_p = mu_p_temp2.entropy() else: H2_p = 0.0 wgts.append(self.mg.message_graph.node[node]['w'][v_w]) Hcond.append(H1_p - H2_p) # conditional entropy Hbar = 0.0 for i in range(len(wgts)): Hbar += wgts[i] * Hcond[i] gradient = [w_i*(Hcond[ind] - Hbar) for ind, w_i in enumerate(wgts)] if self.verbose: print('wgts:', wgts) print('Hcond:', Hcond) print('Hbar:', Hbar) print('grad:', gradient) if debug: assert np.all(np.isfinite(gradient)) return gradient
def _eval_weight_gradients_per_var(self, v_w, nodes): wgts = [] Hcond_u = [] Hcond_p = [] for node in nodes: sc = self.mg.message_graph.node[node]['sc'] mu_p = self.mg.message_graph.node[node][ 'pseudo_belief'].prob.marginal(sc) mu_u = self.mg.message_graph.node[node][ 'pseudo_belief'].util.marginal(sc) elimvars_in_node = sorted(sc, key=lambda x: self.elim_order.index(x)) v_w_ind = elimvars_in_node.index(v_w) mu_p_temp1 = mu_p.marginal( elimvars_in_node[v_w_ind:]) # P(xi, xi+1~) if type(mu_p_temp1) is not Factor: mu_p_temp1 = Factor({}, mu_p_temp1) H1_p = mu_p_temp1.entropy() mu_u_temp1 = mu_u.marginal( elimvars_in_node[v_w_ind:]) # P(xi, xi+1~) if type(mu_u_temp1) is not Factor: mu_u_temp1 = Factor({}, mu_u_temp1) if np.all( mu_u_temp1.t == 0 ): # when mu_u_temp1 is all zero factor, raise assertion error H1_u = 0.0 else: H1_u = mu_u_temp1.entropy() if v_w_ind + 1 < len(elimvars_in_node): mu_p_temp2 = mu_p.marginal( elimvars_in_node[v_w_ind + 1:]) # P(xi+1 , xi+2 ~) if type(mu_p_temp2) is not Factor: mu_p_temp2 = Factor({}, mu_p_temp2) H2_p = mu_p_temp2.entropy() mu_u_temp2 = mu_u.marginal( elimvars_in_node[v_w_ind + 1:]) # P(xi+1 , xi+2 ~) if type(mu_u_temp2) is not Factor: mu_u_temp2 = Factor({}, mu_u_temp2) if np.all(mu_u_temp2.t == 0): H2_u = 0.0 else: H2_u = mu_u_temp2.entropy() else: H2_p = 0.0 H2_u = 0.0 wgts.append(self.mg.message_graph.node[node]['w'][v_w]) H_p_cond = H1_p - H2_p H_u_cond = H1_u - H2_u Hcond_p.append(H_p_cond) # conditional entropy Hcond_u.append(H_u_cond) # conditional entropy Hbar_u = 0.0 Hbar_p = 0.0 for m, node in enumerate(nodes): Hbar_u += wgts[m] * Hcond_u[m] * self._eval_util_bound_norms(node) Hbar_p += wgts[m] * Hcond_p[m] * ( self._eval_util_bound_norms() - self._eval_util_bound_norms(node)) gradient = [] for m, node in enumerate(nodes): grad = Hcond_u[m] * self._eval_util_bound_norms(node) - Hbar_u grad += Hcond_p[m] * (self._eval_util_bound_norms() - self._eval_util_bound_norms(node)) - Hbar_p grad *= wgts[m] grad *= self._eval_prob_bound_norms( ) # todo pull out this term with objective? gradient.append(grad) if self.verbose: print('wgts:', wgts) print('Hcond_p:', Hcond_p) print('Hcond_u:', Hcond_p) print('Hbar_u:', Hbar_u) print('Hbar_p:', Hbar_p) print('grad:', gradient) if debug: assert np.all(np.isfinite(gradient)) return gradient