latticeoptimizer.java

来自「It is the Speech recognition software. 」· Java 代码 · 共 480 行 · 第 1/2 页

JAVA
480
字号
     * Given two edges from equivalent nodes to a single nodes,     * replace with one edge from one node with incomming edges     * that are a union of the incomming edges of the old two nodes.     *     *  A --> B --> C     *  X --> B' --/     *     *  where B and B' are equivalent.     *     *  is replaced with     *     *  A --> B" --> C     *  X --/     *     *  where B" is the merge of B and B'     *     *  Note that equivalent nodes must have the same outgoing edges.     *  For example     *     *  A --> X     *    \     *     \     *      \     *  A' --> B     *     *  A and A' would not be equivalent because the outgoing edges     *  are different     */    protected void optimizeBackward() {        //System.err.println("*** Optimizing backward ***");        boolean moreChanges = true;        while (moreChanges) {            moreChanges = false;            // search for a node that can be optimized            // note that we use getCopyOfNodes to avoid concurrent changes to nodes            for (Iterator i = lattice.getCopyOfNodes().iterator(); i.hasNext();) {                Node n = (Node) i.next();                // we are iterating down a list of node before optimization                // previous iterations may have removed nodes from the list                // therefore we have to check that the node stiff exists                if (lattice.hasNode(n)) {                    moreChanges |= optimizeNodeBackward(n);                }            }        }    }    /**     * Look for 2 entering edges from equivalent nodes.  Replace the edges     * with one edge to one new node that is a merge of the equivalent nodes     * Nodes are equivalent if they have equivalent to edges, and the same      * label. Merged nodes have a union of entering and leaving edges     *     * @param n     * @return true if Node n required opimizing backwards     */    protected boolean optimizeNodeBackward(Node n) {        Vector enteringEdges = new Vector(n.getEnteringEdges());        for (int j = 0; j < enteringEdges.size(); j++) {            Edge e = (Edge) enteringEdges.elementAt(j);            for (int k = j + 1; k < n.getEnteringEdges().size(); k++) {                Edge e2 = (Edge) enteringEdges.elementAt(k);                /*                 * If these are not the same edge, and they point to                 * equivalent nodes, we have a hit, return true                 */                assert e != e2;                if (equivalentNodesBackward(e.getFromNode(),                                            e2.getFromNode())) {                    mergeNodesAndEdgesBackward(n, e, e2);                    return true;                }            }        }        /*         * return false if we did not get a hit         */        return false;    }    /**     * nodes are equivalent backward if they have "to" edges to the same nodes,     * and have equivalent labels (Token, start/end times)     *     * @param n1     * @param n2     * @return true if n1 and n2 are "equivalent backwards"     */    protected boolean equivalentNodesBackward(Node n1, Node n2) {        assert lattice.hasNode(n1);        assert lattice.hasNode(n2);        // do the labels match?        if (!equivalentNodeLabels(n1, n2)) return false;        // if they have different number of "to" edges they are not equivalent        // or if there is a "to" edge with no match then the nodes are not equiv        return n1.hasEquivalentLeavingEdges(n2);    }    /**     * Is the contents of these Node equivalent?     *     * @param n1     * @param n2     * @return true if n1 and n2 have "equivalent labels"     */    protected boolean equivalentNodeLabels(Node n1, Node n2) {        return (n1.getWord().equals(n2.getWord()) &&                (n1.getBeginTime() == n2.getBeginTime() &&                 n1.getEndTime() == n2.getEndTime()));    }    /**     * given edges e1 and e2 to node n from nodes n1 and n2     *     * merge e1 and e2, that is, merge the scores of e1 and e2     * create n' that is a merge of n1 and n2     * add n'     * add edge e' from n' to n     *     * remove n1 and n2 and all associated edges     *     * @param n     * @param e1     * @param e2     */    protected void mergeNodesAndEdgesBackward(Node n, Edge e1, Edge e2) {        assert lattice.hasNode(n);        assert lattice.hasEdge(e1);        assert lattice.hasEdge(e2);        assert e1.getToNode() == n;        assert e2.getToNode() == n;        Node n1 = e1.getFromNode();        Node n2 = e2.getFromNode();        assert n1.hasEquivalentLeavingEdges(n2);        assert n1.getWord().equals(n2.getWord());        // merge the scores of e1 and e2 into e1        e1.setAcousticScore(mergeAcousticScores(e1.getAcousticScore(),                                                e2.getAcousticScore()));        e1.setLMScore(mergeLanguageScores(e1.getLMScore(),                                          e2.getLMScore()));        // add n2's "from" edges to n1        for (Iterator i = n2.getEnteringEdges().iterator(); i.hasNext();) {            Edge e = (Edge) i.next();            e2 = n1.getEdgeFromNode( e.getFromNode() );            if ( e2 == null ) {                lattice.addEdge(e.getFromNode(), n1,                                e.getAcousticScore(), e.getLMScore());            } else {                // if we got here then n1 and n2 had edges from the same node                // choose the edge with best score                e2.setAcousticScore                    (mergeAcousticScores(e.getAcousticScore(),                                         e2.getAcousticScore()));                e2.setLMScore(mergeLanguageScores(e.getLMScore(),                                                  e2.getLMScore()));            }        }        // remove n2 and all associated edges        lattice.removeNodeAndEdges(n2);    }    /**     * Remove all Nodes that have no Edges to them (but not <s>)     */    protected void removeHangingNodes() {        for (Iterator i = lattice.getCopyOfNodes().iterator(); i.hasNext();) {            Node n = (Node) i.next();            if (lattice.hasNode(n)) {                if (n == lattice.getInitialNode()) {                } else if (n == lattice.getTerminalNode()) {                } else {                    if (n.getLeavingEdges().size() == 0                        || n.getEnteringEdges().size() == 0) {                        lattice.removeNodeAndEdges(n);                        removeHangingNodes();                        return;                    }                }            }        }    }    /**     * Provides a single method to merge acoustic scores, so that changes     * to how acoustic score are merged can be made at one point only.     *     * @param score1 the first acoustic score     * @param score2 the second acoustic score     *     * @return the merged acoustic score     */    private double mergeAcousticScores(double score1, double score2) {        // return lattice.getLogMath().addAsLinear(score1, score2);        return Math.max(score1, score2);    }    /**     * Provides a single method to merge language scores, so that changes     * to how language score are merged can be made at one point only.     *     * @param score1 the first language score     * @param score2 the second language score     *     * @return the merged language score     */    private double mergeLanguageScores(double score1, double score2) {        // return lattice.getLogMath().addAsLinear(score1, score2);        return Math.max(score1, score2);    }    /**     * Self test for LatticeOptimizer     *     * @param args     */    public static void main(String[] args) {        Lattice lattice = new Lattice(args[0]);        LatticeOptimizer optimizer = new LatticeOptimizer(lattice);        optimizer.optimize();        lattice.dump(args[1]);    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?