public override bool Equals(Object o) { if (this == o) { return(true); } if (o is SenoneHMM) { var other = (SenoneHMM)o; return(SenoneSequence.Equals(other.SenoneSequence)); } return(false); }
/** * /// Constructs an HMM * * /// @param unit the unit for this HMM * /// @param senoneSequence the sequence of senones for this HMM * /// @param transitionMatrix the state transition matrix * /// @param position the position associated with this HMM */ public SenoneHMM(Unit unit, SenoneSequence senoneSequence, float[][] transitionMatrix, HMMPosition position) { Unit = unit; SenoneSequence = senoneSequence; TransitionMatrix = transitionMatrix; Position = position; Utilities.ObjectTracker("HMM", _objectCount++); _hmmStates = new IHMMState[transitionMatrix.Length]; for (var i = 0; i < _hmmStates.Length; i++) { _hmmStates[i] = new SenoneHMMState(this, i); } // baseUnit = Unit.getUnit(unit.getName()); BaseUnit = unit.BaseUnit; }
/** * /// Loads the sphinx3 density file, a set of density arrays are created and * /// placed in the given pool. * /// * /// @param useCDUnits * /// if true, loads also the context dependent units * /// @param inputStream * /// the open input stream to use * /// @param path * /// the path to a density file * /// @throws FileNotFoundException * /// if a file cannot be found * /// @throws IOException * /// if an error occurs while loading the data */ protected void LoadHMMPool(Boolean useCDUnits, Stream inputStream, string path) { var est = new ExtendedStreamTokenizer(inputStream, '#', false); this.LogInfo("Loading HMM file from: " + path); est.ExpectString(ModelVersion); var numBase = est.GetInt("numBase"); est.ExpectString("n_base"); var numTri = est.GetInt("numTri"); est.ExpectString("n_tri"); var numStateMap = est.GetInt("numStateMap"); est.ExpectString("n_state_map"); var numTiedState = est.GetInt("numTiedState"); est.ExpectString("n_tied_state"); var numContextIndependentTiedState = est .GetInt("numContextIndependentTiedState"); est.ExpectString("n_tied_ci_state"); var numTiedTransitionMatrices = est.GetInt("numTiedTransitionMatrices"); est.ExpectString("n_tied_tmat"); var numStatePerHMM = numStateMap / (numTri + numBase); Debug.Assert(numTiedState == MixtureWeightsPool.StatesNum); Debug.Assert(numTiedTransitionMatrices == MatrixPool.Size); // Load the base phones for (var i = 0; i < numBase; i++) { var name = est.GetString(); var left = est.GetString(); var right = est.GetString(); var position = est.GetString(); var attribute = est.GetString(); var tmat = est.GetInt("tmat"); var stid = new int[numStatePerHMM - 1]; for (var j = 0; j < numStatePerHMM - 1; j++) { stid[j] = est.GetInt("j"); Debug.Assert(stid[j] >= 0 && stid[j] < numContextIndependentTiedState); } est.ExpectString("N"); Debug.Assert(left.Equals("-")); Debug.Assert(right.Equals("-")); Debug.Assert(position.Equals("-")); Debug.Assert(tmat < numTiedTransitionMatrices); var unit = _unitManager.GetUnit(name, attribute.Equals(Filler)); ContextIndependentUnits.Put(unit.Name, unit); //this.LogInfo("Loaded " + unit.ToString()); // The first filler if (unit.IsFiller && unit.Name.Equals(SilenceCiphone)) { unit = UnitManager.Silence; } var transitionMatrix = MatrixPool.Get(tmat); var ss = GetSenoneSequence(stid); IHMM hmm = new SenoneHMM(unit, ss, transitionMatrix, GetHMMPosition(position)); HmmManager.Put(hmm); } if (HmmManager.Get(HMMPosition.Undefined, UnitManager.Silence) == null) { throw new IOException("Could not find SIL unit in acoustic model"); } // Load the context dependent phones. If the useCDUnits // property is false, the CD phones will not be created, but // the values still need to be read in from the file. var lastUnitName = ""; Unit lastUnit = null; int[] lastStid = null; SenoneSequence lastSenoneSequence = null; for (var i = 0; i < numTri; i++) { var name = est.GetString(); var left = est.GetString(); var right = est.GetString(); var position = est.GetString(); var attribute = est.GetString(); var tmat = est.GetInt("tmat"); var stid = new int[numStatePerHMM - 1]; for (var j = 0; j < numStatePerHMM - 1; j++) { stid[j] = est.GetInt("j"); Debug.Assert(stid[j] >= numContextIndependentTiedState && stid[j] < numTiedState); } est.ExpectString("N"); Debug.Assert(!left.Equals("-")); Debug.Assert(!right.Equals("-")); Debug.Assert(!position.Equals("-")); Debug.Assert(attribute.Equals("n/a")); Debug.Assert(tmat < numTiedTransitionMatrices); if (useCDUnits) { Unit unit; var unitName = (name + ' ' + left + ' ' + right); if (unitName.Equals(lastUnitName)) { unit = lastUnit; } else { var leftContext = new Unit[1]; leftContext[0] = ContextIndependentUnits.Get(left); var rightContext = new Unit[1]; rightContext[0] = ContextIndependentUnits.Get(right); Context context = LeftRightContext.Get(leftContext, rightContext); unit = _unitManager.GetUnit(name, false, context); } lastUnitName = unitName; lastUnit = unit; //this.LogInfo("Loaded " + unit.ToString()); var transitionMatrix = MatrixPool.Get(tmat); var ss = lastSenoneSequence; if (ss == null || !SameSenoneSequence(stid, lastStid)) { ss = GetSenoneSequence(stid); } lastSenoneSequence = ss; lastStid = stid; IHMM hmm = new SenoneHMM(unit, ss, transitionMatrix, GetHMMPosition(position)); HmmManager.Put(hmm); } } est.Close(); }
public override int GetHashCode() { return(SenoneSequence.GetHashCode()); }
/** * /// Get a composite senone sequence given the unit. * * /// The unit should have a LeftRightContext, where one or two of 'left' or * /// 'right' may be null to indicate that the match should succeed on any * /// context. * * /// @param unit the unit */ public SenoneSequence GetCompositeSenoneSequence(Unit unit, HMMPosition position) { var unitStr = unit.ToString(); var compositeSenoneSequence = _compositeSenoneSequenceCache.Get(unitStr); this.LogInfo("getCompositeSenoneSequence: " + unit + compositeSenoneSequence == null ? "" : "Cached"); if (compositeSenoneSequence != null) { return(compositeSenoneSequence); } // Iterate through all HMMs looking for // a) An hmm with a unit that has the proper base // b) matches the non-null context var context = unit.Context; List <SenoneSequence> senoneSequenceList; senoneSequenceList = new List <SenoneSequence>(); // collect all senone sequences that match the pattern for (var i = GetHMMIterator(); i.MoveNext();) { var hmm = (SenoneHMM)i.Current; if (hmm.Position == position) { var hmmUnit = hmm.Unit; if (hmmUnit.IsPartialMatch(unit.Name, context)) { this.LogInfo("collected: " + hmm.Unit); senoneSequenceList.Add(hmm.SenoneSequence); } } } // couldn't find any matches, so at least include the CI unit if (senoneSequenceList.Count == 0) { var ciUnit = UnitManager.GetUnit(unit.Name, unit.IsFiller); var baseHMM = lookupHMM(ciUnit, HMMPosition.Undefined); senoneSequenceList.Add(baseHMM.SenoneSequence); } // Add this point we have all of the senone sequences that // match the base/context pattern collected into the list. // Next we build a CompositeSenone consisting of all of the // senones in each position of the list. // First find the longest senone sequence var longestSequence = 0; foreach (var ss in senoneSequenceList) { if (ss.Senones.Length > longestSequence) { longestSequence = ss.Senones.Length; } } // now collect all of the senones at each position into // arrays so we can create CompositeSenones from them // QUESTION: is is possible to have different size senone // sequences. For now lets assume the worst case. var compositeSenones = new List <CompositeSenone>(); var logWeight = 0.0f; for (var i = 0; i < longestSequence; i++) { var compositeSenoneSet = new HashSet <ISenone>(); foreach (var senoneSequence in senoneSequenceList) { if (i < senoneSequence.Senones.Length) { var senone = senoneSequence.Senones[i]; compositeSenoneSet.Add(senone); } } compositeSenones.Add(CompositeSenone.Create( compositeSenoneSet, logWeight)); } compositeSenoneSequence = SenoneSequence.Create(compositeSenones); _compositeSenoneSequenceCache.Put(unit.ToString(), compositeSenoneSequence); this.LogInfo(unit + " consists of " + compositeSenones.Count + " composite senones"); compositeSenoneSequence.Dump("am"); return(compositeSenoneSequence); }