simplebreadthfirstsearchmanager.java

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

JAVA
631
字号
/* * Copyright 1999-2002 Carnegie Mellon University. * Portions Copyright 2002 Sun Microsystems, Inc. * Portions Copyright 2002 Mitsubishi Electric Research Laboratories. * All Rights Reserved.  Use is subject to license terms. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * */package edu.cmu.sphinx.decoder.search;import java.io.IOException;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.Set;import java.util.logging.Level;import java.util.logging.Logger;import edu.cmu.sphinx.decoder.pruner.Pruner;import edu.cmu.sphinx.decoder.scorer.AcousticScorer;import edu.cmu.sphinx.linguist.Linguist;import edu.cmu.sphinx.linguist.SearchState;import edu.cmu.sphinx.linguist.SearchStateArc;import edu.cmu.sphinx.linguist.WordSearchState;import edu.cmu.sphinx.result.Result;import edu.cmu.sphinx.util.LogMath;import edu.cmu.sphinx.util.StatisticsVariable;import edu.cmu.sphinx.util.Timer;import edu.cmu.sphinx.util.props.PropertyException;import edu.cmu.sphinx.util.props.PropertySheet;import edu.cmu.sphinx.util.props.PropertyType;import edu.cmu.sphinx.util.props.Registry;/** * Provides the breadth first search. To perform recognition an application * should call initialize before recognition begins, and repeatedly call <code> recognize </code> * until Result.isFinal() returns true. Once a final result has been obtained, * <code> terminate </code> should be called. *  * All scores and probabilities are maintained in the log math log domain. */// TODO - need to add in timing code.public class SimpleBreadthFirstSearchManager implements SearchManager {    /**     * Sphinx property that defines the name of the linguist to be used by this     * search manager.     */    public final static String PROP_LINGUIST = "linguist";    /**     * Sphinx property that defines the name of the linguist to be used by this     * search manager.     */    public final static String PROP_PRUNER = "pruner";    /**     * Sphinx property that defines the name of the scorer to be used by this     * search manager.     */    public final static String PROP_SCORER = "scorer";    /**     * Sphinx property that defines the name of the logmath to be used by this     * search manager.     */    public final static String PROP_LOG_MATH = "logMath";    /**     * Sphinx property that defines the name of the active list factory to be     * used by this search manager.     */    public final static String PROP_ACTIVE_LIST_FACTORY = "activeListFactory";    /**     * A sphinx property than, when set to <code>true</code> will cause the     * recognizer to count up all the tokens in the active list after every     * frame.     */    public final static String PROP_SHOW_TOKEN_COUNT = "showTokenCount";    /**     * The default value for the PROP_SHOW_TOKEN_COUNT property     */    public final static boolean PROP_SHOW_TOKEN_COUNT_DEFAULT = false;    /**     * Property that sets the minimum score relative to the maximum score in     * the word list for pruning. Words with a score less than     * relativeBeamWidth * maximumScore will be pruned from the list     */    public final static String PROP_RELATIVE_WORD_BEAM_WIDTH = "relativeWordBeamWidth";    /**     * The default value for the PROP_RELATIVE_WORD_BEAM_WIDTH property     */    public final static double PROP_RELATIVE_WORD_BEAM_WIDTH_DEFAULT = 0.0;    /**     * A sphinx property that controls whether or not relative beam pruning     * will be performed on the entry into a state.     */    public final static String PROP_WANT_ENTRY_PRUNING = "wantEntryPruning";    /**     * The default value for the PROP_WANT_ENTRY_PRUNING property     */    public final static boolean PROP_WANT_ENTRY_PRUNING_DEFAULT = false;    /**     * A sphinx property that controls the number of frames processed for every     * time the decode growth step is skipped. Setting this property to zero     * disables grow skipping. Setting this number to a small integer will     * increase the speed of the decoder but will also decrease its accuracy.     * The higher the number, the less often the grow code is skipped.     */    public final static String PROP_GROW_SKIP_INTERVAL = "growSkipInterval";    /**     * The default value for the PROP_GROW_SKIP_INTERVAL property.     */    public final static int PROP_GROW_SKIP_INTERVAL_DEFAULT = 0;    private Linguist linguist; // Provides grammar/language info    private Pruner pruner; // used to prune the active list    private AcousticScorer scorer; // used to score the active list    private int currentFrameNumber; // the current frame number    private ActiveList activeList; // the list of active tokens    private List resultList; // the current set of results    private LogMath logMath;    private Logger logger;        // ------------------------------------    // monitoring data    // ------------------------------------    private Timer scoreTimer; // TODO move these timers out    private Timer pruneTimer;    private Timer growTimer;    private String name;    private StatisticsVariable totalTokensScored;    private StatisticsVariable tokensPerSecond;    private StatisticsVariable curTokensScored;    private StatisticsVariable tokensCreated;    private StatisticsVariable viterbiPruned;    private StatisticsVariable beamPruned;    private boolean showTokenCount;    private boolean wantEntryPruning;    private Map bestTokenMap;    private float logRelativeWordBeamWidth;    private int totalHmms;    private double startTime = 0;    private float threshold;    private float wordThreshold;    private int growSkipInterval = 0;    private ActiveListFactory activeListFactory;    /*     * (non-Javadoc)     *      * @see edu.cmu.sphinx.util.props.Configurable#register(java.lang.String,     *      edu.cmu.sphinx.util.props.Registry)     */    public void register(String name, Registry registry)            throws PropertyException {        this.name = name;        registry.register(PROP_LOG_MATH, PropertyType.COMPONENT);        registry.register(PROP_LINGUIST, PropertyType.COMPONENT);        registry.register(PROP_PRUNER, PropertyType.COMPONENT);        registry.register(PROP_SCORER, PropertyType.COMPONENT);        registry.register(PROP_ACTIVE_LIST_FACTORY, PropertyType.COMPONENT);        registry.register(PROP_SHOW_TOKEN_COUNT, PropertyType.BOOLEAN);        registry.register(PROP_RELATIVE_WORD_BEAM_WIDTH, PropertyType.DOUBLE);        registry.register(PROP_WANT_ENTRY_PRUNING, PropertyType.BOOLEAN);        registry.register(PROP_GROW_SKIP_INTERVAL, PropertyType.INT);    }    /*     * (non-Javadoc)     *      * @see edu.cmu.sphinx.util.props.Configurable#newProperties(edu.cmu.sphinx.util.props.PropertySheet)     */    public void newProperties(PropertySheet ps) throws PropertyException {        logger = ps.getLogger();        logMath = (LogMath) ps.getComponent(PROP_LOG_MATH, LogMath.class);        linguist = (Linguist) ps.getComponent(PROP_LINGUIST, Linguist.class);        pruner = (Pruner) ps.getComponent(PROP_PRUNER, Pruner.class);        scorer = (AcousticScorer) ps.getComponent(PROP_SCORER,                AcousticScorer.class);        activeListFactory = (ActiveListFactory) ps.getComponent(                PROP_ACTIVE_LIST_FACTORY, ActiveListFactory.class);        showTokenCount = ps.getBoolean(PROP_SHOW_TOKEN_COUNT,                PROP_SHOW_TOKEN_COUNT_DEFAULT);        double relativeWordBeamWidth = ps.getDouble(                PROP_RELATIVE_WORD_BEAM_WIDTH,                PROP_RELATIVE_WORD_BEAM_WIDTH_DEFAULT);        growSkipInterval = ps.getInt(PROP_GROW_SKIP_INTERVAL,                PROP_GROW_SKIP_INTERVAL_DEFAULT);        wantEntryPruning = ps.getBoolean(PROP_WANT_ENTRY_PRUNING,                PROP_WANT_ENTRY_PRUNING_DEFAULT);        logRelativeWordBeamWidth = logMath.linearToLog(relativeWordBeamWidth);    }    /**     * Called at the start of recognition. Gets the search manager ready to     * recognize     */    public void startRecognition() {        linguist.startRecognition();        pruner.startRecognition();        scorer.startRecognition();        localStart();        if (startTime == 0.0) {            startTime = System.currentTimeMillis();        }    }    /**     * Performs the recognition for the given number of frames.     *      * @param nFrames     *                the number of frames to recognize     *      * @return the current result or null if there is no Result (due to the     *         lack of frames to recognize)     */    public Result recognize(int nFrames) {        boolean done = false;        boolean noData = false;        Result result = null;        for (int i = 0; i < nFrames && !done; i++) {            done = recognize();            if (done && currentFrameNumber <= 0) {                noData = true;            }        }        if (!noData) {            result = new Result(activeList, resultList, currentFrameNumber,                    done, logMath);        }        if (showTokenCount) {            showTokenCount();        }        return result;    }    /**     * Terminates a recognition     */    public void stopRecognition() {        localStop();        scorer.stopRecognition();        pruner.stopRecognition();        linguist.stopRecognition();    }    /**     * Performs recognition for one frame. Returns true if recognition has been     * completed.     *      * @return <code>true</code> if recognition is completed.     */    protected boolean recognize() {        boolean more = scoreTokens(); // score emitting tokens        if (more) {            pruneBranches(); // eliminate poor branches            currentFrameNumber++;            if (growSkipInterval == 0                    || (currentFrameNumber % growSkipInterval) != 0) {                growBranches(); // extend remaining branches            }        }        return !more;    }    /**     * Gets the initial grammar node from the linguist and creates a     * GrammarNodeToken     */    protected void localStart() {        currentFrameNumber = 0;        curTokensScored.value = 0;        ActiveList newActiveList = activeListFactory.newInstance();        SearchState state = linguist.getSearchGraph().getInitialState();        newActiveList.add(new Token(state, currentFrameNumber));        activeList = newActiveList;        growBranches();    }    /**     * Local cleanup for this search manager     */    protected void localStop() {    }    /**     * Goes through the active list of tokens and expands each token, finding     * the set of successor tokens until all the successor tokens are emitting     * tokens.     *       */    protected void growBranches() {        int mapSize = activeList.size() * 10;        if (mapSize == 0) {            mapSize = 1;        }        growTimer.start();        bestTokenMap = new HashMap(mapSize);        ActiveList oldActiveList = activeList;        Iterator oldListIterator = activeList.iterator();        resultList = new LinkedList();        activeList = activeListFactory.newInstance();        threshold = oldActiveList.getBeamThreshold();        wordThreshold = oldActiveList.getBestScore() + logRelativeWordBeamWidth;        while (oldListIterator.hasNext()) {            Token token = (Token) oldListIterator.next();            collectSuccessorTokens(token);        }        growTimer.stop();

⌨️ 快捷键说明

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