def build_graph(self, fn_node, fn_edge):
        ''' build graph from graph file
            - nodes: NxD,
                     each row represents the feature of a node
            - adj:   NxN,
                     a symmetric similarity matrix with self-connection
        '''
        node = load_data(fn_node)
        edge = load_data(fn_edge)
        assert len(node) > 1, '#node of {}: {}'.format(fn_node, len(node))
        # take majority as label of the graph
        if not self.dataset.ignore_label:
            lb2cnt = {}
            for idx in node:
                if idx not in self.dataset.idx2lb:
                    continue
                lb = self.dataset.idx2lb[idx]
                if lb not in lb2cnt:
                    lb2cnt[lb] = 0
                lb2cnt[lb] += 1
            gt_lb, _ = get_majority(lb2cnt)
            gt_node = self.dataset.lb2idxs[gt_lb]
            if self.dataset.det_label == 'iou':
                label = compute_iou(node, gt_node)
            elif self.dataset.det_label == 'iop':
                label = compute_iop(node, gt_node)
            else:
                raise KeyError('Unknown det_label type: {}'.format(
                    self.dataset.det_label))
        else:
            label = -1.

        adj, _, _ = self.build_adj(node, edge)
        features = self.build_features(node)
        return features, adj, label
    def build_graph(self, fn_node, fn_edge):
        ''' build graph from graph file
            - nodes: NxD,
                     each row represents the feature of a node
            - adj:   NxN,
                     a symmetric similarity matrix with self-connection
        '''
        node = load_data(fn_node)
        edge = load_data(fn_edge)
        assert len(node) > 1, '#node of {}: {}'.format(fn_node, len(node))

        adj, abs2rel, rel2abs = self.build_adj(node, edge)
        # compute label & mask
        if self.dataset.use_random_seed:
            ''' except using node with max degree as seed,
                you can explore more creative designs.
                e.g., applying random seed for multiple times,
                and take the best results.
            '''
            if self.dataset.use_max_degree_seed:
                s = adj.sum(axis=1, keepdims=True)
                rel_center_idx = np.argmax(s)
                center_idx = rel2abs[rel_center_idx]
            else:
                center_idx = random.choice(node)
                rel_center_idx = abs2rel[center_idx]
            mask = np.zeros(len(node))
            mask[rel_center_idx] = 1
            mask = mask.reshape(-1, 1)
            if not self.dataset.ignore_label:
                lb = self.dataset.idx2lb[center_idx]
                gt_node = self.dataset.lb2idxs[lb]
        else:
            # do not use mask
            if not self.dataset.ignore_label:
                lb2cnt = {}
                for idx in node:
                    if idx not in self.dataset.idx2lb:
                        continue
                    lb = self.dataset.idx2lb[idx]
                    if lb not in lb2cnt:
                        lb2cnt[lb] = 0
                    lb2cnt[lb] += 1
                gt_lb, _ = get_majority(lb2cnt)
                gt_node = self.dataset.lb2idxs[gt_lb]

        if not self.dataset.ignore_label:
            g_label = self.get_node_lb(node, gt_node)
        else:
            g_label = np.zeros_like(node)

        features = self.build_features(node)
        if self.dataset.use_random_seed:
            features = np.concatenate((features, mask), axis=1)
        return features, adj, g_label
 def build_graph(self, fn_node, fn_edge):
     """ build graph from graph file
         - nodes: NxD,
                  each row represents the feature of a node
         - adj:   NxN,
                  a symmetric similarity matrix with self-connection
     """
     node = load_data(fn_node)
     edge = load_data(fn_edge)
     assert len(node) > 1, '#node of {}: {}'.format(fn_node, len(node))
     # take majority as label of the graph
     if not self.dataset.ignore_label:
         lb2cnt = {}
         for idx in node:
             if idx not in self.dataset.idx2lb:
                 continue
             lb = self.dataset.idx2lb[idx]
             if lb not in lb2cnt:
                 lb2cnt[lb] = 0
             lb2cnt[lb] += 1
         gt_lb, _ = get_majority(lb2cnt)
         gt_node = self.dataset.lb2idxs[gt_lb]
         iou = compute_iou(node, gt_node)
     else:
         iou = -1.
     # compute adj
     node = list(node)
     abs2rel = {}
     for i, n in enumerate(node):
         abs2rel[n] = i
     size = len(node)
     adj = np.eye(size)
     for e in edge:
         w = 1.
         if len(e) == 2:
             e1, e2 = e
         elif len(e) == 3:
             e1, e2, dist = e
             if not self.dataset.wo_weight:
                 w = 1. - dist
         else:
             raise ValueError('Unknown length of e: {}'.format(e))
         v1 = abs2rel[e1]
         v2 = abs2rel[e2]
         adj[v1][v2] = w
         adj[v2][v1] = w
     if self.dataset.featureless:
         vertices = adj.sum(axis=1, keepdims=True)
         vertices /= vertices.sum(axis=1, keepdims=True)
     else:
         vertices = self.dataset.features[node, :]
     if self.dataset.is_norm_adj:
         adj /= adj.sum(axis=1, keepdims=True)
     return vertices, adj, iou
 def _check_iop(self, fn_node):
     if not self.do_iop_check:
         return True
     node = load_data(fn_node)
     if not self.ignore_label and not self.fn2iop:
         lb2cnt = {}
         for idx in node:
             if idx not in self.idx2lb:
                 continue
             lb = self.idx2lb[idx]
             if lb not in lb2cnt:
                 lb2cnt[lb] = 0
             lb2cnt[lb] += 1
         gt_lb, _ = get_majority(lb2cnt)
         gt_node = self.lb2idxs[gt_lb]
         iop = compute_iop(node, gt_node)
     else:
         iop = self.fn2iop[fn_node]
     return (iop >= self.th_iop_min) and (iop <= self.th_iop_max)
    # get ground-truth iou
    ious = []
    for cluster in clusters:
        lb2cnt = {}
        cluster = set(cluster)
        # take majority as label of the graph
        for idx in cluster:
            if idx not in idx2lb:
                print('[warn] {} is not found'.format(idx))
                continue
            lb = idx2lb[idx]
            if lb not in lb2cnt:
                lb2cnt[lb] = 0
            lb2cnt[lb] += 1
        lb, _ = get_majority(lb2cnt)
        if lb is None:
            iou = -1e6
        else:
            idxs = lb2idxs[lb]
            iou = compute_iou(cluster, idxs)
        ious.append(iou)
    ious = np.array(ious)

    # rank by iou
    pos_g_labels = np.where(ious > args.th_pos)[0]
    clusters = [[clusters[i], ious[i]] for i in pos_g_labels]
    clusters = sorted(clusters, key=lambda x: x[1], reverse=True)
    clusters = [n for n, _ in clusters]

    inst_num = len(idx2lb)