/** * /// Returns the list of successors to this state * * /// @return a list of SearchState objects */ public override ISearchStateArc[] GetSuccessors() { ISearchStateArc[] arcs = GetCachedArcs(); if (arcs == null) { HMMNode[] nodes = Parent.GetHMMNodes(GetEndNode()); arcs = new ISearchStateArc[nodes.Length]; if (Parent.GenerateUnitStates) { for (int i = 0; i < nodes.Length; i++) { arcs[i] = new LexTreeUnitState(nodes[i], WordHistory, SmearTerm, SmearProb, Parent.LogOne, Parent.LogOne, GetNode(), Parent); } } else { for (int i = 0; i < nodes.Length; i++) { IHMM hmm = nodes[i].HMM; arcs[i] = new LexTreeHmmState(nodes[i], WordHistory, SmearTerm, SmearProb, hmm.GetInitialState(), Parent.LogOne, Parent.LogOne, GetNode(), Parent); } } PutCachedArcs(arcs); } return(arcs); }
/** * /// Gets the set of hmm nodes associated with the given end node * * /// @param endNode the end node * /// @return an array of associated hmm nodes */ public HMMNode[] GetHMMNodes(EndNode endNode) { HMMNode[] results = _endNodeMap.Get(endNode.Key); if (results == null) { // System.out.println("Filling cache for " + endNode.getKey() // + " size " + endNodeMap.size()); HashMap <IHMM, HMMNode> resultMap = new HashMap <IHMM, HMMNode>(); Unit baseUnit = endNode.BaseUnit; Unit lc = endNode.LeftContext; foreach (Unit rc in EntryPoints) { IHMM hmm = HMMPool.GetHMM(baseUnit, lc, rc, HMMPosition.End); HMMNode hmmNode = resultMap.Get(hmm); if (hmmNode == null) { hmmNode = new HMMNode(hmm, LogMath.LogOne); resultMap.Add(hmm, hmmNode); } hmmNode.AddRC(rc); foreach (Node node in endNode.GetSuccessors()) { WordNode wordNode = (WordNode)node; hmmNode.AddSuccessor(wordNode); } } // cache it results = resultMap.Values.ToArray(); _endNodeMap.Add(endNode.Key, results); } // System.out.println("GHN: " + endNode + " " + results.length); return(results); }
/** * /// Returns the list of successors to this state * * /// @return a list of SearchState objects */ public override ISearchStateArc[] GetSuccessors() { ISearchStateArc[] arcs = new ISearchStateArc[1]; IHMM hmm = GetHMMNode().HMM; arcs[0] = new LexTreeHmmState(GetHMMNode(), WordHistory, SmearTerm, SmearProb, hmm.GetInitialState(), _parent.LogOne, _parent.LogOne, _parentNode, _parent); return(arcs); }
/** * /// Adds the given pronunciation to the lex tree * * /// @param pronunciation the pronunciation * /// @param probability the unigram probability */ private void AddPronunciation(Pronunciation pronunciation, float probability) { Unit baseUnit; Unit lc; Unit rc; Node curNode; WordNode wordNode; Unit[] units = pronunciation.Units; baseUnit = units[0]; EntryPoint ep = _entryPointTable.GetEntryPoint(baseUnit); ep.AddProbability(probability); if (units.Length > 1) { curNode = ep.Node; lc = baseUnit; for (int i = 1; i < units.Length - 1; i++) { baseUnit = units[i]; rc = units[i + 1]; IHMM hmm = HMMPool.GetHMM(baseUnit, lc, rc, HMMPosition.Internal); if (hmm == null) { if (_debug) { Trace.TraceError("Missing HMM for unit " + baseUnit.Name + " with lc=" + lc.Name + " rc=" + rc.Name); } } else { curNode = curNode.AddSuccessor(hmm, probability); } lc = baseUnit; // next lc is this baseUnit } // now add the last unit as an end unit baseUnit = units[units.Length - 1]; EndNode endNode = new EndNode(baseUnit, lc, probability); curNode = curNode.AddSuccessor(endNode, probability); wordNode = curNode.AddSuccessor(pronunciation, probability, WordNodeMap); if (wordNode.GetWord().IsSentenceEndWord) { sentenceEndWordNode = wordNode; } } else { ep.AddSingleUnitWord(pronunciation); } }
private void CreateContextDependentSuccessors() { _cdHMMs = new HashMap <Unit, HashMap <Unit, List <IHMM> > >(); _senonesToUnits = new HashMap <SenoneSequence, List <Unit> >(); _fillerHMMs = new List <IHMM>(); _leftContextSilHMMs = new List <IHMM>(); var hmmIter = AcousticModel.GetHMMIterator(); while (hmmIter.MoveNext()) { IHMM hmm = hmmIter.Current; List <Unit> sameSenonesUnits; SenoneSequence senoneSeq = ((SenoneHMM)hmm).SenoneSequence; if ((sameSenonesUnits = _senonesToUnits.Get(senoneSeq)) == null) { sameSenonesUnits = new List <Unit>(); _senonesToUnits.Put(senoneSeq, sameSenonesUnits); } sameSenonesUnits.Add(hmm.Unit as Unit); if (hmm.Unit.IsFiller) { _fillerHMMs.Add(hmm); continue; } if (hmm.Unit.IsContextDependent()) { LeftRightContext context = (LeftRightContext)hmm.Unit.Context; Unit lc = context.LeftContext[0] as Unit; if (lc == UnitManager.Silence) { _leftContextSilHMMs.Add(hmm); continue; } Unit baseUnit = hmm.Unit.BaseUnit as Unit; HashMap <Unit, List <IHMM> > lcSuccessors; if ((lcSuccessors = _cdHMMs.Get(lc)) == null) { lcSuccessors = new HashMap <Unit, List <IHMM> >(); _cdHMMs.Put(lc, lcSuccessors); } List <IHMM> lcBaseSuccessors; if ((lcBaseSuccessors = lcSuccessors.Get(baseUnit)) == null) { lcBaseSuccessors = new List <IHMM>(); lcSuccessors.Put(baseUnit, lcBaseSuccessors); } lcBaseSuccessors.Add(hmm); } } _leftContextSilHMMs.AddRange(_fillerHMMs); }
/// <summary> /// Connects the single unit words associated with this entry point. The singleUnitWords list contains all /// single unit pronunciations that have as their sole unit, the unit associated with this entry point. Entry /// points for these words are added to the epNode for all possible left (exit) and right (entry) contexts. /// </summary> /// <param name="lc">the left context</param> /// <param name="epNode">the entry point node</param> /// <param name="map"></param> private void ConnectSingleUnitWords(Unit lc, Node epNode, Dictionary <IHMM, HMMNode> map) { if (!_singleUnitWords.IsEmpty()) { foreach (Unit rc in _parent.EntryPoints) { IHMM hmm = _parent.HMMPool.GetHMM(BaseUnit, lc, rc, HMMPosition.Single); if (hmm == null) { continue; } HMMNode tailNode = null; if (hmm != null && map.ContainsKey(hmm)) { tailNode = map[hmm]; } if (tailNode == null) { tailNode = (HMMNode)epNode.AddSuccessor(hmm, Probability); map.Add(hmm, tailNode); } else { epNode.PutSuccessor(hmm, tailNode); } WordNode wordNode; tailNode.AddRC(rc); nodeCount++; foreach (Pronunciation p in _singleUnitWords) { if (p.Word == _parent.Dictionary.GetSentenceStartWord()) { _parent.InitialNode = new InitialWordNode(p, tailNode); } else { float prob = _parent.GetWordUnigramProbability(p.Word); wordNode = tailNode.AddSuccessor(p, prob, _parent.WordNodeMap); if (p.Word == _parent.Dictionary.GetSentenceEndWord()) { _parent.sentenceEndWordNode = wordNode; } } nodeCount++; } } } }
/** * /// Given a unit state, return the set of sentence hmm states associated with the unit * * /// @param unitState the unit state of intereset * /// @return the hmm tree for the unit */ private HMMStateState GetHMMStates(UnitState unitState) { HMMStateState hmmTree; HMMStateState finalState; Unit unit = unitState.Unit; HMMPosition position = unitState.GetPosition(); IHMM hmm = _parent._acousticModel.LookupNearestHMM(unit, position, false); IHMMState initialState = hmm.GetInitialState(); hmmTree = new HMMStateState(unitState, initialState); AttachState(unitState, hmmTree, LogOne, LogOne); AddStateToCache(hmmTree); finalState = ExpandHMMTree(unitState, hmmTree); return(finalState); }
private void CreateContextIndependentSuccessors() { var hmmIter = AcousticModel.GetHMMIterator(); CISuccessors = new List <IHMM>(); _senonesToUnits = new HashMap <SenoneSequence, List <Unit> >(); while (hmmIter.MoveNext()) { IHMM hmm = hmmIter.Current; if (!hmm.Unit.IsContextDependent()) { List <Unit> sameSenonesUnits; SenoneSequence senoneSeq = ((SenoneHMM)hmm).SenoneSequence; if ((sameSenonesUnits = _senonesToUnits.Get(senoneSeq)) == null) { sameSenonesUnits = new List <Unit>(); _senonesToUnits.Put(senoneSeq, sameSenonesUnits); } sameSenonesUnits.Add(hmm.Unit as Unit); CISuccessors.Add(hmm); } } }
/// <summary> /// A version of createEntryPointMap that compresses common hmms across all entry points. /// </summary> public void CreateEntryPointMap() { Dictionary <IHMM, Node> map = new Dictionary <IHMM, Node>(); Dictionary <IHMM, HMMNode> singleUnitMap = new Dictionary <IHMM, HMMNode>(); foreach (Unit lc in _parent.ExitPoints) { Node epNode = new Node(LogMath.LogZero); foreach (Unit rc in GetEntryPointRC()) { IHMM hmm = _parent.HMMPool.GetHMM(BaseUnit, lc, rc, HMMPosition.Begin); if (hmm == null) { continue; } Node addedNode = null; if (map.ContainsKey(hmm)) { addedNode = map[hmm]; } if (addedNode == null) { addedNode = epNode.AddSuccessor(hmm, Probability); map.Add(hmm, addedNode); } else { epNode.PutSuccessor(hmm, addedNode); } nodeCount++; ConnectEntryPointNode(addedNode, rc); } ConnectSingleUnitWords(lc, epNode, singleUnitMap); Java.Put(UnitToEntryPointMap, lc, epNode); } }
/** * /// Creates a unit search state for the given unit node * * /// @param hmmNode the unit node * * /// @return the search state */ public ISearchStateArc CreateUnitStateArc(HMMNode hmmNode, LexTreeState previous) { ISearchStateArc arc; float insertionProbability = Parent.CalculateInsertionProbability(hmmNode); float smearProbability = Parent.GetUnigramSmear(hmmNode) + previous.SmearTerm; float languageProbability = smearProbability - previous.SmearProb; //if we want a unit state create it, otherwise //get the first hmm state of the unit if (Parent.GenerateUnitStates) { arc = new LexTreeUnitState(hmmNode, WordHistory, previous.SmearTerm, smearProbability, languageProbability, insertionProbability, Parent); } else { IHMM hmm = hmmNode.HMM; arc = new LexTreeHmmState(hmmNode, WordHistory, previous.SmearTerm, smearProbability, hmm.GetInitialState(), languageProbability, insertionProbability, null, Parent); } return(arc); }
/// <summary> /// Adds a child node holding an hmm to the successor. If a node similar to the child has already been added, we use /// the previously added node, otherwise we add this. Also, we record the base unit of the child in the set of right /// context /// </summary> /// <param name="hmm">the hmm to add</param> /// <param name="probability"></param> /// <returns>the node that holds the hmm (new or old)</returns> public Node AddSuccessor(IHMM hmm, float probability) { if (hmm == null) { return(null); } Node child = null; Node matchingChild = GetSuccessor(hmm); if (matchingChild == null) { child = new HMMNode(hmm, probability); PutSuccessor(hmm, child); } else { if (matchingChild.UnigramProbability < probability) { matchingChild.UnigramProbability = probability; } child = matchingChild; } return(child); }
/** * /// Creates the node, wrapping the given hmm * * /// @param hmm the hmm to hold */ public HMMNode(IHMM hmm, float probablilty) : base(probablilty) { HMM = hmm; Unit _base = BaseUnit; int type = SimpleUnit; if (_base.IsSilence) { type = SilenceUnit; } else if (_base.IsFiller) { type = FillerUnit; } else if (hmm.Position.IsWordBeginning()) { type = WordBeginningUnit; } Type = type; }
/// <summary> /// Initializes a new instance of the <see cref="HMMPool"/> class. /// </summary> /// <param name="model">The model to use for the pool</param> /// <param name="unitManager">The unit manager.</param> /// <exception cref="System.Exception"> /// LexTreeLinguist: Unsupported left context size /// or /// LexTreeLinguist: Unsupported right context size /// </exception> public HMMPool(AcousticModel model, UnitManager unitManager) { var maxCiUnits = 0; this.Model = model; this._unitManager = unitManager; TimerPool.GetTimer(this, "Build HMM Pool").Start(); if (model.GetLeftContextSize() != 1) { throw new Exception("LexTreeLinguist: Unsupported left context size"); } if (model.GetRightContextSize() != 1) { throw new Exception("LexTreeLinguist: Unsupported right context size"); } // count CI units: var i = model.GetContextIndependentUnitIterator(); while (i.MoveNext()) { var unit = i.Current; //this.LogInfo("CI unit " + unit); if (unit.BaseID > maxCiUnits) { maxCiUnits = unit.BaseID; } } NumCiUnits = maxCiUnits + 1; _unitTable = new Unit[NumCiUnits * NumCiUnits * NumCiUnits]; var iHMM = model.GetHMMIterator(); while (iHMM.MoveNext()) { var hmm = iHMM.Current; var unit = hmm.Unit; var id = GetId(unit); _unitTable[id] = unit; //this.LogInfo("Unit " + unit + " id " + id); } // build up the hmm table to allow quick access to the hmms _hmmTable = new Dictionary <HMMPosition, IHMM[]>(); foreach (HMMPosition position in Enum.GetValues(typeof(HMMPosition))) { var hmms = new IHMM[_unitTable.Length]; Java.Put(_hmmTable, position, hmms); //hmmTable.Put(position, hmms); for (var j = 1; j < _unitTable.Length; j++) { var unit = _unitTable[j]; if (unit == null) { unit = SynthesizeUnit(j); } if (unit != null) { hmms[j] = model.LookupNearestHMM(unit, position, false); Debug.Assert(hmms[j] != null); } } } TimerPool.GetTimer(this, "Build HMM Pool").Stop(); }