private void createBaseGrammar( List<GrammarNode> wordGrammarNodes, GrammarNode branchNode, GrammarNode finalNode) { GrammarNode currNode = branchNode; ListIterator<GrammarNode> iter = wordGrammarNodes.listIterator(); while (iter.hasNext()) { GrammarNode nextNode = iter.next(); currNode.add(nextNode, logMath.getLogOne()); currNode = nextNode; } currNode.add(finalNode, logMath.getLogOne()); }
private void addSelfLoops(List<GrammarNode> wordGrammarNodes) { ListIterator<GrammarNode> iter = wordGrammarNodes.listIterator(); while (iter.hasNext()) { GrammarNode currNode = iter.next(); currNode.add(currNode, logMath.linearToLog(selfLoopProbability)); } }
/** * Creates a result * * @param activeList the active list associated with this result * @param resultList the result list associated with this result * @param frameNumber the frame number for this result. * @param isFinal if true, the result is a final result. This means that the last frame in the * speech segment has been decoded. */ public Result(ActiveList activeList, List<Token> resultList, int frameNumber, boolean isFinal) { this.activeList = activeList; this.resultList = resultList; this.currentFrameNumber = frameNumber; this.isFinal = isFinal; logMath = LogMath.getInstance(); }
/** @return the (linearly scaled) mixture weights of the component densities */ public float[] getComponentWeights() { float[] mixWeights = new float[getMixtureComponents().length]; for (int i = 0; i < mixWeights.length; i++) { mixWeights[i] = (float) logMath.logToLinear(logMixtureWeights[i]); } return mixWeights; }
public float calculateScore(Data feature) { if (feature instanceof DoubleData) { System.err.println("DoubleData conversion required on mixture level!"); } float[] featureVector = FloatData.toFloatData(feature).getValues(); float logTotal = LogMath.getLogZero(); for (int i = 0; i < mixtureComponents.length; i++) { // In linear form, this would be: // // Total += Mixture[i].score * MixtureWeight[i] logTotal = logMath.addAsLinear( logTotal, mixtureComponents[i].getScore(featureVector) + logMixtureWeights[i]); } return logTotal; }
private void addBackwardJumps( List<GrammarNode> wordGrammarNodes, GrammarNode branchNode, GrammarNode finalNode2) { GrammarNode currNode; for (int i = 0; i < wordGrammarNodes.size(); i++) { currNode = wordGrammarNodes.get(i); for (int j = Math.max(i - numAllowedWordJumps - 1, 0); j < i - 1; j++) { GrammarNode jumpToNode = wordGrammarNodes.get(j); currNode.add(jumpToNode, logMath.linearToLog(backwardTransitionProbability)); } } }
private void addForwardJumps( List<GrammarNode> wordGrammarNodes, GrammarNode branchNode, GrammarNode finalNode) { GrammarNode currNode = branchNode; for (int i = -1; i < wordGrammarNodes.size(); i++) { if (i > -1) { currNode = wordGrammarNodes.get(i); } for (int j = i + 2; j < Math.min(wordGrammarNodes.size(), i + numAllowedWordJumps + 1); j++) { GrammarNode jumpNode = wordGrammarNodes.get(j); currNode.add(jumpNode, logMath.linearToLog(forwardJumpProbability)); } } for (int i = wordGrammarNodes.size() - numAllowedWordJumps - 1; i < wordGrammarNodes.size() - 1; i++) { int j = wordGrammarNodes.size(); currNode = wordGrammarNodes.get(i); currNode.add( finalNode, logMath.linearToLog((float) forwardJumpProbability * Math.pow(Math.E, j - i))); } }
/** * Calculates probability p = w[1]*p[1] + w[2]*p[2] + ... (in log domain) * * @see * edu.cmu.sphinx.linguist.language.ngram.LanguageModel#getProbability(edu.cmu.sphinx.linguist.WordSequence) */ public float getProbability(WordSequence wordSequence) { float prob = 0; for (int i = 0; i < numberOfLanguageModels; i++) { float p = weights[i] + (languageModels.get(i)).getProbability(wordSequence); if (i == 0) { prob = p; } else { prob = logMath.addAsLinear(prob, p); } } return prob; }
/** Tests whether working with different types transformations works properly. */ @Test public void testUnivariateMeanTransformation() { float mean = 20; float var = 0.001f; MixtureComponent gaussian = new MixtureComponent( new float[] {mean}, new float[][] {{2}}, new float[] {5}, new float[] {var}, null, null); Assert.assertTrue( LogMath.getLogMath().logToLinear(gaussian.getScore(new float[] {2 * mean + 5})) > 10); }
InterpolatedLanguageModel(LogMath logMath, List<LanguageModel> languageModels, float[] floats) { this.languageModels = languageModels; this.numberOfLanguageModels = languageModels.size(); this.weights = new float[floats.length]; float weightSum = 0; for (int i = 0; i < floats.length; i++) { weightSum += floats[i]; this.weights[i] = logMath.linearToLog(floats[i]); } if (weightSum < 1.0 - EPSILON || weightSum > 1.0 + EPSILON) { throw new PropertyException( InterpolatedLanguageModel.class.getName(), PROP_LANGUAGE_MODEL_WEIGHTS, "Weights do not sum to 1.0"); } }
public void newProperties(PropertySheet ps) throws PropertyException { logMath = LogMath.getLogMath(); logger = ps.getLogger(); unitManager = (UnitManager) ps.getComponent(PROP_UNIT_MANAGER); hmmManager = new HMMManager(); contextIndependentUnits = new LinkedHashMap<String, Unit>(); phoneList = new LinkedHashMap<String, Integer>(); meanTransformationMatrixPool = createDummyMatrixPool("meanTransformationMatrix"); meanTransformationVectorPool = createDummyVectorPool("meanTransformationMatrix"); varianceTransformationMatrixPool = createDummyMatrixPool("varianceTransformationMatrix"); varianceTransformationVectorPool = createDummyVectorPool("varianceTransformationMatrix"); String modelName = ps.getString(MODEL_NAME); String location = ps.getString(LOCATION); String phone = ps.getString(PHONE_LIST); String dataDir = ps.getString(DATA_DIR); logger.info("Creating Sphinx3 acoustic model: " + modelName); logger.info(" Path : " + location); logger.info(" phonelist : " + phone); logger.info(" dataDir : " + dataDir); // load the HMM model file boolean useCDUnits = ps.getBoolean(PROP_USE_CD_UNITS); assert !useCDUnits; try { loadPhoneList( ps, useCDUnits, StreamFactory.getInputStream(location, phone), location + File.separator + phone); } catch (StreamCorruptedException sce) { printPhoneListHelp(); } catch (IOException e) { e.printStackTrace(); } }
/** * Adds transition matrix to the transition matrices pool * * @param pool the pool to add matrix to * @param hmmId current HMM's id * @param numEmittingStates number of states in current HMM * @param floor the transition probability floor * @param skip if true, states can be skipped * @throws IOException if an error occurs while loading the data */ private void addModelToTransitionMatrixPool( Pool<float[][]> pool, int hmmId, int numEmittingStates, float floor, boolean skip) throws IOException { assert pool != null; // Add one to account for the last, non-emitting, state int numStates = numEmittingStates + 1; float[][] tmat = new float[numStates][numStates]; for (int j = 0; j < numStates; j++) { for (int k = 0; k < numStates; k++) { // Just to be sure... tmat[j][k] = 0.0f; // the last row is just zeros, so we just do // the first (numStates - 1) rows // The value assigned could be anything, provided // we normalize it. if (j < numStates - 1) { // Usual case: state can transition to itself // or the next state. if (k == j || k == j + 1) { tmat[j][k] = floor; } // If we can skip, we can also transition to // the next state if (skip) { if (k == j + 2) { tmat[j][k] = floor; } } } } normalize(tmat[j]); logMath.linearToLog(tmat[j]); } pool.put(hmmId, tmat); }
/** * Compute the density values of a sampled interval with an univariate <code>MixtureComponent * </code> and compare values with the precomputed-computed ones. */ @Test public void testUnivariateDensity() { float minX = 10; float maxX = 30; float resolution = 0.1f; float mean = 20; float var = 3; MixtureComponent gaussian = new MixtureComponent(new float[] {mean}, new float[] {var}); for (float curX = minX; curX <= maxX; curX += resolution) { double gauLogScore = gaussian.getScore(new FloatData(new float[] {curX}, 16000, 0)); double manualScore = (1 / sqrt(var * 2 * PI)) * exp((-0.5 / var) * (curX - mean) * (curX - mean)); double gauScore = LogMath.getLogMath().logToLinear((float) gauLogScore); Assert.assertEquals(manualScore, gauScore, 1E-5); } }
public void newProperties(PropertySheet ps) throws PropertyException { if (allocated) { throw new RuntimeException("Can't change properties after allocation"); } logMath = (LogMath) ps.getComponent(PROP_LOG_MATH); languageModels = ps.getComponentList(PROP_LANGUAGE_MODELS, LanguageModel.class); numberOfLanguageModels = languageModels.size(); // read weights as a String List. List<String> items = ps.getStringList(PROP_LANGUAGE_MODEL_WEIGHTS); if (items.size() != numberOfLanguageModels) { throw new RuntimeException("Number of weights not equal to number of language models"); } // convert Strings to floats and assign weights. float[] floats = new float[items.size()]; weights = new float[floats.length]; float weightSum = 0; for (int i = 0; i < items.size(); i++) { try { floats[i] = Float.parseFloat(items.get(i)); weightSum += floats[i]; weights[i] = logMath.linearToLog(floats[i]); } catch (NumberFormatException e) { throw new PropertyException( InterpolatedLanguageModel.class.getName(), PROP_LANGUAGE_MODEL_WEIGHTS, "Float value expected from the property list. But found:" + items.get(i)); } } if (weightSum < 1.0 - EPSILON || weightSum > 1.0 + EPSILON) { throw new PropertyException( InterpolatedLanguageModel.class.getName(), PROP_LANGUAGE_MODEL_WEIGHTS, "Weights do not sum to 1.0"); } }
@Override protected GrammarNode createGrammar() throws IOException { logger.info("Creating Grammar"); initialNode = createGrammarNode(Dictionary.SILENCE_SPELLING); finalNode = createGrammarNode(Dictionary.SILENCE_SPELLING); finalNode.setFinalNode(true); final GrammarNode branchNode = createGrammarNode(false); final List<GrammarNode> wordGrammarNodes = new ArrayList<GrammarNode>(); final int end = tokens.size(); logger.info("Creating Grammar nodes"); for (final String word : tokens.subList(0, end)) { final GrammarNode wordNode = createGrammarNode(word.toLowerCase()); wordGrammarNodes.add(wordNode); } logger.info("Done creating grammar node"); // now connect all the GrammarNodes together initialNode.add(branchNode, LogMath.getLogOne()); createBaseGrammar(wordGrammarNodes, branchNode, finalNode); if (modelDeletions) { addForwardJumps(wordGrammarNodes, branchNode, finalNode); } if (modelBackwardJumps) { addBackwardJumps(wordGrammarNodes, branchNode, finalNode); } if (modelRepetitions) { addSelfLoops(wordGrammarNodes); } logger.info("Done making Grammar"); // initialNode.dumpDot("./graph.dot"); return initialNode; }
/** * Adds model to the mixture weights * * @param pool the pool to add models to * @param stateID vector containing state ids for hmm * @param numStreams the number of streams * @param numGaussiansPerState the number of Gaussians per state * @param floor the minimum mixture weight allowed * @throws IOException if an error occurs while loading the data */ private void addModelToMixtureWeightPool( Pool<float[]> pool, int[] stateID, int numStreams, int numGaussiansPerState, float floor) throws IOException { int numStates = stateID.length; assert pool != null; int numInPool = pool.getFeature(NUM_SENONES, 0); pool.setFeature(NUM_SENONES, numStates + numInPool); numInPool = pool.getFeature(NUM_STREAMS, -1); if (numInPool == -1) { pool.setFeature(NUM_STREAMS, numStreams); } else { assert numInPool == numStreams; } numInPool = pool.getFeature(NUM_GAUSSIANS_PER_STATE, -1); if (numInPool == -1) { pool.setFeature(NUM_GAUSSIANS_PER_STATE, numGaussiansPerState); } else { assert numInPool == numGaussiansPerState; } // TODO: allow any number for numStreams assert numStreams == 1; for (int i = 0; i < numStates; i++) { int state = stateID[i]; float[] logMixtureWeight = new float[numGaussiansPerState]; // Initialize the weights with the same value, e.g. floor floorData(logMixtureWeight, floor); // Normalize, so the numbers are not all too low normalize(logMixtureWeight); logMath.linearToLog(logMixtureWeight); pool.put(state, logMixtureWeight); } }
@BeforeSuite public void setupLogMath() { LogMath.setUseTable(true); }