def _segmentation_impl(self, graph, costs, time_limit=None, **kwargs): objective = nmc.multicutObjective(graph, costs) if self.solver == 'greedy-additive': solver_impl = objective.greedyAdditiveFactory().create(objective) elif self.solver == 'kernighan-lin': warmstart = self.solver_options.get('warmstart_greedy', True) # TODO need to set this if we use verbosity # greedyVisitNth = kwargs.pop('greedyVisitNth', 100) solver_impl = objective.kernighanLinFactory( warmStartGreedy=warmstart).create(objective) elif self.solver == 'fusion-moves': solver_impl = self._get_fusion_moves(objective) elif self.solver == 'ilp': ilp_backend = self.solver_options.get("ilp_backend", None) solver_impl = objective.multicutIlpFactory( ilpSolver=ilp_backend).create(objective) # TODO this needs to change once we suport verbosity / logging if time_limit is None: node_labels = solver_impl.optimize() else: visitor = objective.verboseVisitor(visitNth=100000000, timeLimitSolver=time_limit) node_labels = solver_impl.optimize(visitor=visitor) return node_labels
def multicut_kernighan_lin(graph, costs, time_limit=None, warmstart=True, **kwargs): """ Solve multicut problem with kernighan lin solver. Introduced in "An efficient heuristic procedure for partitioning graphs": http://xilinx.asia/_hdl/4/eda.ee.ucla.edu/EE201A-04Spring/kl.pdf Arguments: graph [nifty.graph] - graph of multicut problem costs [np.ndarray] - edge costs of multicut problem time_limit [float] - time limit for inference (default: None) warmstart [bool] - whether to warmstart with gaec solution (default: True) """ objective = nmc.multicutObjective(graph, costs) solver = objective.kernighanLinFactory( warmStartGreedy=warmstart).create(objective) if time_limit is None: return solver.optimize() else: visitor = objective.verboseVisitor(visitNth=1000000, timeLimitTotal=time_limit) return solver.optimize(visitor=visitor)
def _compute_mc(self, input_, feat_function, beta): # watershed and region adjacency graph ws, n_labels = self._compute_ws(input_) rag = nrag.gridRag(ws, numberOfLabels=n_labels, numberOfThreads=self.n_threads) if rag.numberOfEdges == 0: return np.zeros_like(ws) # features and features to costs feats = feat_function(rag, input_) probs, edge_len = feats[:, 0], feats[:, -1] costs = self._probs_to_costs(probs, edge_len, beta) # graph and multicut solver graph = nifty.graph.undirectedGraph(rag.numberOfNodes) graph.insertEdges(rag.uvIds()) objective = nmc.multicutObjective(graph, costs) solver = objective.kernighanLinFactory( warmStartGreedy=True).create(objective) # solve multicut and project back to segmentation # TODO time limit node_labels = solver.optimize() return nrag.projectScalarNodeDataToPixels( rag, node_labels, numberOfThreads=self.n_threads)
def _to_objective(graph, costs): if isinstance(graph, nifty.graph.UndirectedGraph): graph_ = graph else: graph_ = nifty.graph.undirectedGraph(graph.numberOfNodes) graph_.insertEdges(graph.uvIds()) objective = nmc.multicutObjective(graph_, costs) return objective
def multicut_gaec(graph, costs, time_limit=None, n_threads=1): objective = nmc.multicutObjective(graph, costs) solver = objective.greedyAdditiveFactory().create(objective) if time_limit is None: return solver.optimize() else: visitor = objective.verboseVisitor(visitNth=1000000, timeLimitTotal=time_limit) return solver.optimize(visitor=visitor)
def multicut_kernighan_lin(graph, costs, warmstart=True, time_limit=None, n_threads=1): objective = nmc.multicutObjective(graph, costs) solver = objective.kernighanLinFactory(warmStartGreedy=warmstart).create(objective) if time_limit is None: return solver.optimize() else: visitor = objective.verboseVisitor(visitNth=1000000, timeLimitTotal=time_limit) return solver.optimize(visitor=visitor)
def multicut_fusion_moves(graph, costs, time_limit=None, n_threads=1, solver='kernighan-lin'): assert solver in ('kernighan-lin', 'greedy-additive') objective = nmc.multicutObjective(graph, costs) if time_limit is None: return solver.optimize() else: visitor = objective.verboseVisitor(visitNth=1000000, timeLimitTotal=time_limit) return solver.optimize(visitor=visitor)
def _test_multicut(self, solver): # TODO remove the try-except once download is implemented try: graph, costs = self.load_problem(self.problem_root) except FileNotFoundError: return node_labels = solver(graph, costs) obj = nmc.multicutObjective(graph, costs) energy = obj.evalNodeLabels(node_labels) self.assertGreater(self.upper_bound, energy)
def multicut_fusion_moves(graph, costs, time_limit=None, n_threads=1, internal_solver='kernighan-lin', seed_fraction=.05, num_it=1000, num_it_stop=10): """ Solve multicut problem with fusion moves solver. Introduced in "Fusion moves for correlation clustering": http://openaccess.thecvf.com/content_cvpr_2015/papers/Beier_Fusion_Moves_for_2015_CVPR_paper.pdf Arguments: graph [nifty.graph] - graph of multicut problem costs [np.ndarray] - edge costs of multicut problem time_limit [float] - time limit for inference (default: None) n_threasd [int] - number of threads (default: 1) internal_solver [str] - name of solver used for connected components (default: 'kernighan-lin') seed_fraction [float] - fraction of nodes used as seeds for proposal generation (default: .05) num_it [int] - maximal number of iterations (default: 1000) num_it_stop [int] - stop if no improvement after num_it_stop (default: 1000) """ assert internal_solver in ('kernighan-lin', 'greedy-additive') objective = nmc.multicutObjective(graph, costs) if internal_solver == 'kernighan-lin': sub_solver = objective.greedyAdditiveFactory() else: sub_solver = objective.kernighanLinFactory(warmStartGreedy=True) sub_solver = objective.fusionMoveSettings(mcFactory=sub_solver) proposal_gen = objective.watershedProposals(sigma=10, seedFraction=seed_fraction) solver = objective.fusionMoveBasedFactory( fusionMove=sub_solver, verbose=1, fuseN=2, proposalGen=proposal_gen, numberOfIterations=num_it, numberOfParallelProposals=2 * n_threads, numberOfThreads=n_threads, stopIfNoImprovement=num_it_stop).create(objective) if time_limit is None: return solver.optimize() else: visitor = objective.verboseVisitor(visitNth=1000000, timeLimitTotal=time_limit) return solver.optimize(visitor=visitor)
def solve_multicut(graph, costs): assert graph.numberOfEdges == len(costs) _logger.debug('Creating multi-cut object from graph %s and costs %s', graph, costs.shape) _logger.trace('Costs are %s', costs) # TODO why do lower costs mean cut the edge? # Qutoing @constantinpape # the cost can be in ]-inf, inf[ (I usually clip at ~ ]-6, 6[), # where negative costs are repulsive (i.e. nodes are more likely to be disconnected) # and positive costs are attractive objective = nifty_mc.multicutObjective(graph, costs) solver = objective.kernighanLinFactory( warmStartGreedy=True).create(objective) return solver.optimize()
def multicut_gaec(graph, costs, time_limit=None, **kwargs): """ Solve multicut problem with greedy-addtive edge contraction solver. Introduced in "Fusion moves for correlation clustering": http://openaccess.thecvf.com/content_cvpr_2015/papers/Beier_Fusion_Moves_for_2015_CVPR_paper.pdf Arguments: graph [nifty.graph] - graph of multicut problem costs [np.ndarray] - edge costs of multicut problem time_limit [float] - time limit for inference (default: None) """ objective = nmc.multicutObjective(graph, costs) solver = objective.greedyAdditiveFactory().create(objective) if time_limit is None: return solver.optimize() else: visitor = objective.verboseVisitor(visitNth=1000000, timeLimitTotal=time_limit) return solver.optimize(visitor=visitor)
def _test_multicut(self, solver, **kwargs): graph, costs = load_multicut_problem('A', 'small', self.problem_path) node_labels = solver(graph, costs, **kwargs) obj = nmc.multicutObjective(graph, costs) energy = obj.evalNodeLabels(node_labels) self.assertGreater(self.upper_bound, energy)
def _check_result(self, graph, costs, node_labels): self.assertEqual(graph.numberOfNodes, len(node_labels)) obj = nmc.multicutObjective(graph, costs) energy = obj.evalNodeLabels(node_labels) self.assertGreater(self.upper_bound, energy) return energy