def inference(self, x, w, relaxed=False, return_energy=False, invert=False): """Inference for x using parameters w. Finds (approximately) argmin_y np.dot(w, joint_feature(x, y)) using self.inference_method. Parameters ---------- x : tuple Instance of a graph with unary & pairwise potentials. x=(unaries, edges, pairwise) unaries are an nd-array of shape (n_nodes, n_states), edges are an nd-array of shape (n_edges, 2) pairwise are an nd-array of shape (n_edges, n_states, n_states) w : ndarray, shape=(size_joint_feature,) Parameters for the CRF energy function. relaxed : bool, default=False We do not support it yet. return_energy : bool, default=False Whether to return the energy of the solution (x, y) that was found. Returns ------- y_pred : ndarray By default an integer ndarray of shape=(width, height) of variable assignments for x is returned. """ self._check_size_w(w) self.inference_calls += 1 unary_potentials = self._get_unary_potentials(x, w) pairwise_potentials = self._get_pairwise_potentials(x, w) edges = self._get_edges(x) if invert: unary_potentials = -unary_potentials pairwise_potentials = -pairwise_potentials if self.inference_method == 'gco': h = inference_gco(unary_potentials, pairwise_potentials, edges, n_iter=self.n_iter) y_ret = Label(h, None, None, True) elif self.inference_method == 'ad3': h = inference_ad3(unary_potentials, pairwise_potentials, edges, relaxed=relaxed, return_energy=False, n_iterations=self.n_iter) y_ret = Label(h, None, None, True, relaxed) elif self.inference_method == 'trw': from trw import trw h = trw(-unary_potentials, edges, -pairwise_potentials, max_iter=self.n_iter) y_ret = Label(h, None, None, True) return y_ret
def loss_augmented_inference(self, x, y, w, relaxed=False, return_energy=False): self.inference_calls += 1 self._check_size_w(w) unary_potentials = self._get_unary_potentials(x, w) pairwise_potentials = self._get_pairwise_potentials(x, w) edges = self._get_edges(x) if y.full_labeled: # loss augment unaries for label in xrange(self.n_states): mask = y.full != label unary_potentials[mask, label] += y.weights[mask] if self.inference_method == 'gco': h = inference_gco(unary_potentials, pairwise_potentials, edges, n_iter=self.n_iter, return_energy=True) y_ret = Label(h[0], None, y.weights, True) elif self.inference_method == 'ad3': h = inference_ad3(unary_potentials, pairwise_potentials, edges, relaxed=relaxed, return_energy=False, n_iterations=self.n_iter) y_ret = Label(h, None, y.weights, True, relaxed) elif self.inference_method == 'trw': from trw import trw h = trw(-unary_potentials, edges, -pairwise_potentials, max_iter=self.n_iter, relaxed=relaxed) y_ret = Label(h, None, y.weights, True, relaxed) # count = h[2] # energy = np.dot(w, self.joint_feature(x, y_ret)) + self.loss(y, y_ret) # # if count == 0 and np.abs(energy + h[1]) > 1e-4: # print 'FULL: energy does not match: %f, %f, difference=%f' % (energy, -h[1], # energy + h[1]) if return_energy: return y_ret, h[1] return y_ret else: if self.inference_method != 'gco': # only gco inference_method supported: we need label costs raise NotImplementedError # this is weak labeled example # use pygco with label costs label_costs = np.zeros(self.n_states) c = np.sum(y.weights) / float(self.n_states) for label in y.weak: label_costs[label] = c for label in xrange(0, self.n_states): if label not in y.weak: unary_potentials[:, label] += y.weights h = inference_gco(unary_potentials, pairwise_potentials, edges, label_costs, n_iter=self.n_iter, return_energy=True) y_ret = Label(h[0], None, y.weights, False) # energy = np.dot(w, self.joint_feature(x, y_ret)) + self._kappa(y, y_ret) # if h[2] == 0 and np.abs(energy + h[1]) > 1e-4: # print 'energy does not match: %f, %f, difference=%f' % (energy, -h[1], energy + h[1]) return y_ret