Пример #1
0
def get_classes(hierarchy: Tree, output_all_nodes=False):
    """
    Return all classes associated with a hierarchy. The classes are sorted in
    alphabetical order using their label, putting all leaf nodes first and the
    non-leaf nodes afterwards.

    Args:
        hierarhcy: The hierarchy to use.
        all_nodes: Set to true if the non-leaf nodes (excepted the origin) must
            also be included.

    Return:
        A pair (classes, positions) of the array of all classes (sorted) and the
        associated tree positions.
    """
    def get_classes_from_positions(positions):
        classes = [get_label(hierarchy[p]) for p in positions]
        class_order = np.argsort(
            classes)  # we output classes in alphabetical order
        positions = [positions[i] for i in class_order]
        classes = [classes[i] for i in class_order]
        return classes, positions

    positions = hierarchy.treepositions("leaves")
    classes, positions = get_classes_from_positions(positions)

    if output_all_nodes:
        positions_nl = [
            p for p in hierarchy.treepositions() if p not in positions
        ]
        classes_nl, positions_nl = get_classes_from_positions(positions_nl)
        classes += classes_nl
        positions += positions_nl

    return classes, positions
Пример #2
0
def _get_lbrb_const_length(t : tree.Tree):
    lb_const_lengths = 0
    max_lb_const_length = 0
    lb_const_num = 0
    rb_const_lengths = 0
    max_rb_const_length = 0
    rb_const_num = 0
    # total_length = len(t.leaves())
    for position in t.treepositions():
        # print(t[position])
        if not (isinstance(t[position],str) or isinstance(t[position][0],str)):
            if len(t[position][0]) == 2:
                lb_const_num += 1
                this_length = len(t[position][0].leaves())
                lb_const_lengths += this_length
                if this_length > max_lb_const_length:
                    max_lb_const_length = this_length
            if len(t[position][1]) == 2:
                rb_const_num += 1
                this_length = len(t[position][1].leaves())
                rb_const_lengths += this_length
                if this_length > max_rb_const_length:
                    max_rb_const_length = this_length
    rb_const_lengths = rb_const_lengths/rb_const_num if rb_const_num != 0 else 0
    lb_const_lengths = lb_const_lengths/lb_const_num if lb_const_num != 0 else 0
    # max_lb_const_length /= total_length
    # max_rb_const_length /= total_length
    return lb_const_lengths, rb_const_lengths, max_lb_const_length, max_rb_const_length
Пример #3
0
def translate(tree: Tree, translation_rules: list, draw=False):
    put_left = list(
        filter(
            lambda i: isinstance(tree[i], Tree) and tree[i].label() in
            translation_rules and not 'put_left' in locals(),
            tree.treepositions()))[0] if len(tree) != 0 else []

    if len(put_left) != 0:
        tree = apply_translation(put_left, tree)
        if tree[tree.treepositions()[-2]].label() not in [
                Nonterminal("AUX"), Nonterminal("VERB")
        ]:
            tree = apply_translation(tree.treepositions()[-2], tree)
        if draw: tree.draw()

    return tree
Пример #4
0
    def __init__(self, hierarchy: Tree, classes: List[str], weights: Tree):
        """
        Initialise the loss with a given hierarchy.

        Args:
            hierarchy: The hierarchy used to define the loss.
            classes: A list of classes defining the order of all nodes.
            weights: The weights as a tree of similar shapre as hierarchy.
        """
        super(YOLOLoss, self).__init__()

        assert hierarchy.treepositions() == weights.treepositions()

        self.cascade = SoftmaxCascade(hierarchy, classes)

        weights_dict = {
            get_label(hierarchy[p]): get_label(weights[p])
            for p in weights.treepositions()
        }
        self.weights = torch.nn.Parameter(torch.unsqueeze(
            torch.tensor([weights_dict[c] for c in classes],
                         dtype=torch.float32), 0),
                                          requires_grad=False)
Пример #5
0
    def __init__(self, hierarchy: Tree, classes: List[str], weights: Tree):
        super(HierarchicalLLLoss, self).__init__()

        assert hierarchy.treepositions() == weights.treepositions()

        # the tree positions of all the leaves
        positions_leaves = {
            get_label(hierarchy[p]): p
            for p in hierarchy.treepositions("leaves")
        }
        num_classes = len(positions_leaves)

        # we use classes in the given order
        positions_leaves = [positions_leaves[c] for c in classes]

        # the tree positions of all the edges (we use the bottom node position)
        positions_edges = hierarchy.treepositions()[
            1:]  # the first one is the origin

        # map from position tuples to leaf/edge indices
        index_map_leaves = {
            positions_leaves[i]: i
            for i in range(len(positions_leaves))
        }
        index_map_edges = {
            positions_edges[i]: i
            for i in range(len(positions_edges))
        }

        # edge indices corresponding to the path from each index to the root
        edges_from_leaf = [[
            index_map_edges[position[:i]] for i in range(len(position), 0, -1)
        ] for position in positions_leaves]

        # get max size for the number of edges to the root
        num_edges = max([len(p) for p in edges_from_leaf])

        # helper that returns all leaf positions from another position wrt to the original position
        def get_leaf_positions(position):
            node = hierarchy[position]
            if isinstance(node, Tree):
                return node.treepositions("leaves")
            else:
                return [()]

        # indices of all leaf nodes for each edge index
        leaf_indices = [[
            index_map_leaves[position + leaf]
            for leaf in get_leaf_positions(position)
        ] for position in positions_edges]

        # save all relevant information as pytorch tensors for computing the loss on the gpu
        self.onehot_den = torch.nn.Parameter(torch.zeros(
            [num_classes, num_classes, num_edges]),
                                             requires_grad=False)
        self.onehot_num = torch.nn.Parameter(torch.zeros(
            [num_classes, num_classes, num_edges]),
                                             requires_grad=False)
        self.weights = torch.nn.Parameter(torch.zeros([num_classes,
                                                       num_edges]),
                                          requires_grad=False)

        # one hot encoding of the numerators and denominators and store weights
        for i in range(num_classes):
            for j, k in enumerate(edges_from_leaf[i]):
                self.onehot_num[i, leaf_indices[k], j] = 1.0
                self.weights[i, j] = get_label(weights[positions_edges[k]])
            for j, k in enumerate(edges_from_leaf[i][1:]):
                self.onehot_den[i, leaf_indices[k], j] = 1.0
            self.onehot_den[
                i, :,
                j + 1] = 1.0  # the last denominator is the sum of all leaves