📄 baumwelchlearner.java
字号:
// First, the emitting states. We have to do this because the // emitting states use probabilities from the previous // frame. The non-emitting states, however, since they don't // consume frames, use probabilities from the current frame for (int indexNode = 0; indexNode < graph.size(); indexNode++) { Node node = graph.getNode(indexNode); // Treat dummy node (and initial and final nodes) the same // as non-emitting if (!node.isType("STATE")) { continue; } SenoneHMMState state = (SenoneHMMState) node.getObject(); SenoneHMM hmm = (SenoneHMM) state.getHMM(); if (!state.isEmitting()) { continue; } // Initialize the current frame probability with 0.0f, log scale probCurrentFrame[indexNode] = LogMath.getLogZero(); for (node.startIncomingEdgeIterator(); node.hasMoreIncomingEdges(); ) { // Finds out what the previous node and previous state are Node previousNode = node.nextIncomingEdge().getSource(); int indexPreviousNode = graph.indexOf(previousNode); HMMState previousState = (HMMState) previousNode.getObject(); float logTransitionProbability; // previous state could be have an associated hmm state... if (previousState != null) { // Make sure that the transition happened from a state // that either is in the same model, or was a // non-emitting state assert ((!previousState.isEmitting()) || (previousState.getHMM() == hmm)); if (!previousState.isEmitting()) { logTransitionProbability = 0.0f; } else { logTransitionProbability = hmm.getTransitionProbability( previousState.getState(), state.getState()); } } else { // Previous state is a dummy state or beginning of // utterance. logTransitionProbability = 0.0f; } // Adds the alpha and transition from the previous // state into the current alpha probCurrentFrame[indexNode] = logMath.addAsLinear(probCurrentFrame[indexNode], probPreviousFrame[indexPreviousNode] + logTransitionProbability); // System.out.println("State= " + indexNode + " curr " // + probCurrentFrame[indexNode] + " prev " + // probPreviousFrame[indexNode] + " trans " + // logTransitionProbability); } // Finally, multiply by this state's output probability for the // current Feature (add in log scale) probCurrentFrame[indexNode] += outputProbs[indexNode]; // System.out.println("State= " + indexNode + " alpha= " + // probCurrentFrame[indexNode]); score[indexNode].setAlpha(probCurrentFrame[indexNode]); } // Finally, the non-emitting states for (int indexNode = 0; indexNode < graph.size(); indexNode++) { Node node = graph.getNode(indexNode); HMMState state = null; SenoneHMM hmm = null; if (node.isType("STATE")) { state = (HMMState) node.getObject(); hmm = (SenoneHMM) state.getHMM(); if (state.isEmitting()) { continue; } } else if (graph.isInitialNode(node)) { score[indexNode].setAlpha(LogMath.getLogZero()); probCurrentFrame[indexNode] = LogMath.getLogZero(); continue; } // Initialize the current frame probability 0.0f, log scale probCurrentFrame[indexNode] = LogMath.getLogZero(); for (node.startIncomingEdgeIterator(); node.hasMoreIncomingEdges(); ) { float logTransitionProbability; // Finds out what the previous node and previous state are Node previousNode = node.nextIncomingEdge().getSource(); int indexPreviousNode = graph.indexOf(previousNode); if (previousNode.isType("STATE")) { HMMState previousState = (HMMState) previousNode.getObject(); // Make sure that the transition happened from a // state that either is in the same model, or was // a non-emitting state assert ((!previousState.isEmitting()) || (previousState.getHMM() == hmm)); if (!previousState.isEmitting()) { logTransitionProbability = 0.0f; } else { // previousState == state logTransitionProbability = hmm.getTransitionProbability( previousState.getState(), state.getState()); } } else { logTransitionProbability = 0.0f; } // Adds the alpha and transition from the previous // state into the current alpha probCurrentFrame[indexNode] = logMath.addAsLinear(probCurrentFrame[indexNode], probCurrentFrame[indexPreviousNode] + logTransitionProbability); // System.out.println("State= " + indexNode + " curr " // + probCurrentFrame[indexNode] + " prev " + // probPreviousFrame[indexNode] + " trans " + // logTransitionProbability); } // System.out.println("State= " + indexNode + " alpha= " + // probCurrentFrame[indexNode]); // Non-emitting states have the equivalent of output // probability of 1.0. In log scale, this is the same as // adding 0.0f, or doing nothing. score[indexNode].setAlpha(probCurrentFrame[indexNode]); } } /** * Does the backward pass, one frame at a time. * * @param score the feature to be used */ private void backwardPass(TrainerScore[] score) { // Now, the backward pass. for (int i = 0; i < graph.size(); i++) { outputProbs[i] = score[i].getScore(); score[i].setBeta(probCurrentFrame[i]); } float[] probNextFrame = probCurrentFrame; probCurrentFrame = new float[graph.size()]; // First, the emitting states for (int indexNode = 0; indexNode < graph.size(); indexNode++) { Node node = graph.getNode(indexNode); // Treat dummy node (and initial and final nodes) the same // as non-emitting if (!node.isType("STATE")) { continue; } HMMState state = (HMMState) node.getObject(); SenoneHMM hmm = (SenoneHMM) state.getHMM(); if (!state.isEmitting()) { continue; } // Initialize the current frame probability with log // probability of log(0f) probCurrentFrame[indexNode] = LogMath.getLogZero(); for (node.startOutgoingEdgeIterator(); node.hasMoreOutgoingEdges(); ) { float logTransitionProbability; // Finds out what the next node and next state are Node nextNode = node.nextOutgoingEdge().getDestination(); int indexNextNode = graph.indexOf(nextNode); HMMState nextState = (HMMState) nextNode.getObject(); if (nextState != null) { // Make sure that the transition happened to a // non-emitting state, or to the same model assert ((!nextState.isEmitting()) || (nextState.getHMM() == hmm)); if (nextState.getHMM() != hmm) { logTransitionProbability = 0.0f; } else { logTransitionProbability = hmm.getTransitionProbability(state.getState(), nextState.getState()); } } else { // Next state is a dummy state or beginning of // utterance. logTransitionProbability = 0.0f; } // Adds the beta, the output prob, and the transition // from the next state into the current beta probCurrentFrame[indexNode] = logMath.addAsLinear(probCurrentFrame[indexNode], probNextFrame[indexNextNode] + logTransitionProbability + outputProbs[indexNextNode]); } // System.out.println("State= " + indexNode + " beta= " + probCurrentFrame[indexNode]); score[indexNode].setBeta(probCurrentFrame[indexNode]); } // Now, the non-emitting states // We have to go backwards because for non-emitting states we // use the current frame probability, and we need to refer to // states that are downstream in the graph for (int indexNode = graph.size() - 1; indexNode >= 0; indexNode--) { Node node = graph.getNode(indexNode); HMMState state = null; HMM hmm = null; if (node.isType("STATE")) { state = (HMMState) node.getObject(); hmm = state.getHMM(); if (state.isEmitting()) { continue; } } else if (graph.isFinalNode(node)) { score[indexNode].setBeta(LogMath.getLogZero()); probCurrentFrame[indexNode] = LogMath.getLogZero(); continue; } // Initialize the current frame probability with log(0f) probCurrentFrame[indexNode] = LogMath.getLogZero(); for (node.startOutgoingEdgeIterator(); node.hasMoreOutgoingEdges(); ) { float logTransitionProbability; // Finds out what the next node and next state are Node nextNode = node.nextOutgoingEdge().getDestination(); int indexNextNode = graph.indexOf(nextNode); if (nextNode.isType("STATE")) { HMMState nextState = (HMMState) nextNode.getObject(); // Make sure that the transition happened to a // state that either is the same, or is emitting assert ((nextState.isEmitting()) || (nextState == state)); // In any case, the transition (at this point) is // assumed to be 1.0f, or 0.0f in log scale. logTransitionProbability = 0.0f; /* if (!nextState.isEmitting()) { logTransitionProbability = 0.0f; } else { logTransitionProbability = hmm.getTransitionProbability(state.getState(), nextState.getState()); } */ } else { logTransitionProbability = 0.0f; } // Adds the beta, the transition, and the output prob // from the next state into the current beta probCurrentFrame[indexNode] = logMath.addAsLinear(probCurrentFrame[indexNode], probCurrentFrame[indexNextNode] + logTransitionProbability); } // System.out.println("State= " + indexNode + " beta= " + probCurrentFrame[indexNode]); score[indexNode].setBeta(probCurrentFrame[indexNode]); } } /* Pseudo code: forward pass: token = maketoken(initialstate); List initialTokenlist = new List; newtokenlist.add(token); // Initial token is on a nonemitting state; no need to score; List newList = expandToEmittingStateList(initialTokenList){ while (morefeatures){ scoreTokenList(emittingTokenList, featurevector[timestamp]); pruneTokenList(emittingTokenList); List newList = expandToEmittingStateList(emittingTokenList){ timestamp++; } // Some logic to expand to a final nonemitting state (how)? expandToNonEmittingStates(emittingTokenList); */ /* private void forwardPass() { ActiveList activelist = new FastActiveList(createInitialToken()); AcousticScorer acousticScorer = new ThreadedAcousticScorer(); FeatureFrame featureFrame = frontEnd.getFeatureFrame(1, ""); Pruner pruner = new SimplePruner(); // Initialization code pushing initial state to emitting state here while ((featureFrame.getFeatures() != null)) { ActiveList nextActiveList = new FastActiveList(); // At this point we have only emitting states. We score // and prune them ActiveList emittingStateList = new FastActiveList(); // activelist.getEmittingStateList(); acousticScorer.calculateScores(emittingStateList.getTokens()); // The pruner must clear up references to pruned objects emittingStateList = pruner.prune( emittingStateList); expandStateList(emittingStateList, nextActiveList); while (nextActiveList.hasNonEmittingStates()){ // extractNonEmittingStateList will pull out the list // of nonemitting states completely from the // nextActiveList. At this point nextActiveList does // not have a list of nonemitting states and must // instantiate a new one. ActiveList nonEmittingStateList = nextActiveList.extractNonEmittingStateList(); nonEmittingStateList = pruner.prune(nonEmittingStateList); expandStateList(nonEmittingStateList, nextActiveList); } activeList = newActiveList; } } */ /* Pseudo code backward pass: state = finaltoken.state.wholelistofeverythingthatcouldbefinal; while (moreTokensAtCurrentTime) { Token token = nextToken(); State state = token.state; state.gamma = state.logalpha + state.logbeta - logtotalprobability; SentenceHMM.updateState(state,state.gamma,vector[state.timestamp]); // state.update (state.gamma, vector[state.timestamp], updatefunction()); while token.hasMoreIncomingEdges() { Edge transition = token.nextIncomingEdge(); double logalpha = transition.source.alpha; double logbeta = transition.destination.beta; double logtransition = transition.transitionprob; // transition.posterior = alpha*transition*beta / // totalprobability; double localtransitionbetascore = logtransition + logbeta + transition.destination.logscore; double transition.posterior = localtransitionbetascore + logalpha - logtotalprobability; transition.updateaccumulator(transition.posterior); // transition.updateaccumulator(transition.posterior, updatefunction()); SentenceHMM.updateTransition(transition, transitionstate,state.gamma); transition.source.beta = Logadd(transition.source.beta, localtransitionbetascore); } } */ /* private void expandStateList(ActiveList stateList, ActiveList nextActiveList) { while (stateList.hasMoreTokens()) { Token token = emittingStateList.getNextToken(); // First get list of links to possible future states List successorList = getSuccessors(token); while (successorList.hasMoreEntries()) { UtteranceGraphEdge edge = successorList.getNextEntry(); // create a token for the future state, if its not // already in active list; The active list will check // for the key "edge.destination()" in both of its // lists if (nextActiveList.hasState(edge.destination())) { Token newToken = nextActiveList.getTokenForState(edge.destination()); } else { Token newToken = new Token(edge.destination()); } // create a link between current state and future state TrainerLink newlink = new TrainerLink(edge, token, newToken); newlink.logScore = token.logScore + edge.transition.logprob(); // add link to the appropriate lists for source and // destination tokens token.addOutGoingLink(newlink); newToken.addIncomingLink(newlink); newToken.alpha = logAdd(newToken.alpha, newlink.logScore); // At this point, we have placed a new token in the // successor state, and linked the token at the // current state to the token at the non-emitting // states. // Add token to appropriate active list nextActiveList.add(newToken); } } } */ /* private void expandToEmittingStateList(List tokenList){ List emittingTokenList = new List(); do { List nonEmittingTokenList = new List(); expandtokens(newtokenlist, emittingTokenList, nonemittingTokenList); while (nonEmittingTokenList.length() != 0); return emittingTokenList; } } */ /* private void expandtokens(List tokens, List nonEmittingStateList, List EmittingStateList){ while (moreTokens){ sucessorlist = SentenceHMM.gettransitions(nextToken()); while (moretransitions()){ transition = successor; State destinationState = successor.state; newtoken = gettokenfromHash(destinationState, currenttimestamp); newtoken.logscore = Logadd(newtoken.logscore, token.logscore + transition.logscore); // Add transition to newtoken predecessor list? // Add transition to token sucessor list // Should we define a token "arc" for this. ?? if (state.isemitting) EmittingStateList.add(newtoken); else nonEmittingStateList.add(newtoken); } } } */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -