예제 #1
0
 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);
 }
예제 #2
0
        /**
         * /// 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;
        }
예제 #3
0
        /**
         * /// 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();
        }
예제 #4
0
 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);
        }