📄 segment-nbest.cc
字号:
segmentHyp(nextHyp, context, lm, NOSscore, Sscore, NOSTATE);
//cerr << "j = " << j << " k = " << k << " context = " << (vocab.use(), context) << " : " << NOSscore << " " << Sscore << endl;
nbestTrellis->updateBack(NBEST_STATE(j, NOS),
NBEST_STATE(k, NOS),
nextHyp.acousticScore + lmw * NOSscore +
wtw * nextHyp.numWords);
if (bias > 0.0) {
nbestTrellis->updateBack(NBEST_STATE(j, NOS),
NBEST_STATE(k, S),
nextHyp.acousticScore + lmw * Sscore +
wtw * nextHyp.numWords);
/*
* Now the same for the case where the previous hyp's
* last word starts a sentence.
*/
if (hypLen == 0) {
context[0] = Vocab_None;
} else {
context[0] = hyp.words[hypLen - 1];
context[1] = vocab.ssIndex();
context[2] = Vocab_None;
}
segmentHyp(nextHyp, context, lm, NOSscore, Sscore, NOSTATE);
//cerr << "j = " << j << " k = " << k << " context = " << (vocab.use(), context) << " : " << NOSscore << " " << Sscore << endl;
nbestTrellis->updateBack(NBEST_STATE(j, S),
NBEST_STATE(k, NOS),
nextHyp.acousticScore + lmw * NOSscore +
wtw * nextHyp.numWords);
nbestTrellis->updateBack(NBEST_STATE(j, S),
NBEST_STATE(k, S),
nextHyp.acousticScore + lmw * Sscore +
wtw * nextHyp.numWords);
}
}
//cerr << "BACK:list " << i << " hyp " << j
// << " back " << nbestTrellis->getBackProb(NBEST_STATE(j, NOS))
// << " " << nbestTrellis->getBackProb(NBEST_STATE(j, S))
// << endl;
}
}
if (debug >= DEBUG_PROGRESS) {
cerr << endl;
}
/*
* Reset the LM scores in the nbest lists to reflect the posterior
* probabilities computes from alphas/betas.
* The posterior of a hyp is proportional to alpha(hyp) * beta(hyp).
* We divide by the hyp's acoustic score and wt penalty to get back
* a lm score.
*/
unsigned h;
for (h = 0; h < numLists ; h ++) {
for (unsigned j = 0;
j < nbestLists[h]->numHyps() &&
(maxRescore <= 0 || j < maxRescore);
j ++)
{
NBestHyp &hyp = nbestLists[h]->getHyp(j);
LogP2 posterior =
AddLogP(nbestTrellis->getLogP(NBEST_STATE(j, S), h) +
nbestTrellis->getBackLogP(NBEST_STATE(j, S), h),
nbestTrellis->getLogP(NBEST_STATE(j, NOS), h) +
nbestTrellis->getBackLogP(NBEST_STATE(j, NOS), h));
//cerr << "BACK:list " << h << " hyp " << j
// << " forw " << nbestTrellis->getLogP(NBEST_STATE(j, NOS), h)
// << " " << nbestTrellis->getLogP(NBEST_STATE(j, S), h)
// << " back " << nbestTrellis->getBackLogP(NBEST_STATE(j, NOS), h)
// << " " << nbestTrellis->getBackLogP(NBEST_STATE(j, S), h)
// << " post " << posterior << endl;
hyp.languageScore = (posterior -
hyp.acousticScore -
wtw * hyp.numWords) / lmw;
}
}
/*
* Dump out the new nbest scores
*/
for (h = 0; h < numLists; h ++) {
if (writeNbestDir) {
makeArray(char, outputName, strlen(writeNbestDir) + 2 + 256);
char *rootname = strrchr(nbestNames[h], '/');
if (rootname) {
rootname += 1;
} else {
rootname = nbestNames[h];
}
sprintf(outputName, "%s/%.255s", writeNbestDir, rootname);
File file(outputName, "w");
nbestLists[h]->write(file, false, maxRescore);
} else {
cout << "<nbestlist " << (h + 1) << ">\n";
File sout(stdout);
nbestLists[h]->write(sout, false, maxRescore);
}
}
delete nbestTrellis;
}
/*
* Viterbi on nbest trellis
*/
void
segmentNbest(Array<NBestList *> &nbestLists, unsigned numLists,
LM &lm, double lmw, double wtw)
{
Vocab &vocab = lm.vocab;
Trellis<unsigned> *nbestTrellis =
forwardNbest(nbestLists, numLists, lm, lmw, wtw);
makeArray(unsigned, bestStates, numLists);
if (nbestTrellis->viterbi(bestStates, numLists) != numLists) {
cerr << "nbestTrellis->viterbi failed\n";
delete nbestTrellis;
return;
}
if (debug >= DEBUG_TRANSITIONS) {
cerr << "Best hyps states: ";
for (unsigned i = 0; i < numLists; i++) {
cerr << NBEST_HYP(bestStates[i]) << "("
<< stateNames[NBEST_SEG(bestStates[i])] << ") " ;
}
cerr << endl;
}
if (debug >= DEBUG_PROGRESS) {
cerr << "Viterbi...0";
}
/*
* Do a viterbi traceback on the best hyps
*/
{
makeArray(VocabIndex, context, contextLength + 1);
/* word context from preceding nbest hyp */
LogP NOSscore, Sscore; /* dummies required by segmentHyp() */
context[0] = vocab.ssIndex();
context[1] = Vocab_None;
NBestHyp &hyp = nbestLists[0]->getHyp(NBEST_HYP(bestStates[0]));
SegmentState seg = NBEST_SEG(bestStates[0]);
segmentHyp(hyp, context, lm, NOSscore, Sscore, seg);
for (unsigned i = 1; i < numLists; i ++) {
NBestHyp &prevHyp =
nbestLists[i-1]->getHyp(NBEST_HYP(bestStates[i-1]));
unsigned prevLen = Vocab::length(prevHyp.words);
SegmentState prevSeg = NBEST_SEG(bestStates[i-1]);
NBestHyp &hyp = nbestLists[i]->getHyp(NBEST_HYP(bestStates[i]));
SegmentState seg = NBEST_SEG(bestStates[i]);
if (debug >= DEBUG_PROGRESS) {
cerr << "..." << i;
}
/*
* Set up the last two words from the previous hyp
* as context for this one.
*/
if (prevLen == 0) {
context[0] = Vocab_None;
} else {
if (prevSeg == S) {
context[0] = prevHyp.words[prevLen - 1];
context[1] = vocab.ssIndex();
context[2] = Vocab_None;
} else {
unsigned k;
for (k = 0; k < contextLength && k < prevLen; k ++) {
context[k] = prevHyp.words[prevLen - 1 - k];
}
context[k] = Vocab_None;
}
}
segmentHyp(hyp, context, lm, NOSscore, Sscore, seg);
}
if (debug >= DEBUG_PROGRESS) {
cerr << endl;
}
}
delete nbestTrellis;
}
void insertStartEndTags(NBestList &nb, VocabIndex first, VocabIndex last)
{
if (first == Vocab_None && last == Vocab_None) {
return;
}
for (unsigned h = 0; h < nb.numHyps(); h++) {
NBestHyp &hyp = nb.getHyp(h);
unsigned numWords = Vocab::length(hyp.words);
VocabIndex *newWords = new VocabIndex[numWords + 3];
assert(newWords != 0);
unsigned i = 0;
if (first != Vocab_None) {
newWords[i ++] = first;
}
for (unsigned j = 0; j < numWords; j ++) {
newWords[i ++] = hyp.words[j];
}
if (last != Vocab_None) {
newWords[i ++] = last;
}
newWords[i] = Vocab_None;
delete [] hyp.words;
hyp.words = newWords;
}
}
void
processNbestLists(const char *fileList, LM &lm, LM &oldLM,
VocabIndex firstTag, VocabIndex lastTag)
{
Vocab &vocab = lm.vocab;
Array<char *> nbestFileList;
unsigned numNbestLists = 0;
if (debug >= DEBUG_PROGRESS) {
cerr << "Processing file list " << fileList << endl;
}
/*
* Read list of nbest filenames
*/
{
File file(fileList, "r");
char *line;
while (line = file.getline()) {
char *fname = strtok(line, wordSeparators);
if (fname) {
nbestFileList[numNbestLists] = strdup(fname);
assert(nbestFileList[numNbestLists] != 0);
numNbestLists ++;
}
}
}
/*
* Read nbest lists
*/
Array<NBestList *> nbestListArray(0, numNbestLists);
unsigned i;
for (i = 0; i < numNbestLists; i ++) {
File file(nbestFileList[i], "r");
if (debug >= DEBUG_PROGRESS) {
cerr << "Reading " << nbestFileList[i] << endl;
}
nbestListArray[i] = new NBestList(vocab, maxNbest);
assert(nbestListArray[i] != 0);
nbestListArray[i]->read(file);
/*
* Compute acoustic-only scores from aggregate recognizer scores
*/
if (decipherLM) {
nbestListArray[i]->decipherFix(oldLM, decipherLMW, decipherWTW);
}
/*
* Reorder N-best hyps so -max-rescore can look at the top ones
*/
if (!noReorder) {
nbestListArray[i]->reweightHyps(rescoreLMW, rescoreWTW);
nbestListArray[i]->sortHyps();
}
/*
* Normalize acoustic scores to avoid exponent overflow in
* exponentiating logscores
*/
nbestListArray[i]->acousticNorm();
/*
* Remove noise and pauses which would disrupt the DP procedure
*/
nbestListArray[i]->removeNoise(lm);
/*
* Insert start/end tags
*/
insertStartEndTags(*nbestListArray[i], firstTag, lastTag);
}
if (fbRescore) {
forwardBackNbest(nbestListArray, nbestFileList, numNbestLists,
lm, rescoreLMW, rescoreWTW);
} else {
segmentNbest(nbestListArray, numNbestLists,
lm, rescoreLMW, rescoreWTW);
}
/*
* Free storage
*/
for (i = 0; i < numNbestLists; i ++) {
free(nbestFileList[i]);
delete nbestListArray[i];
}
}
int
main(int argc, char **argv)
{
setlocale(LC_CTYPE, "");
setlocale(LC_COLLATE, "");
Opt_Parse(argc, argv, options, Opt_Number(options), 0);
if (version) {
printVersion(RcsId);
exit(0);
}
/*
* Set length of N-gram context;
* use at least 2 to hold previous word and <s> tags
*/
contextLength = order - 1;
if (contextLength < 2) {
contextLength = 2;
}
/*
* Construct language model
*/
Vocab vocab;
LM *useLM;
if (!lmFile) {
cerr << "need a language model\n";
exit(1);
}
vocab.toLower() = toLower ? true : false;
VocabIndex startTagIndex, endTagIndex;
if (startTag) {
startTagIndex = vocab.addWord(startTag);
} else {
startTagIndex = Vocab_None;
}
if (endTag) {
endTagIndex = vocab.addWord(endTag);
} else {
endTagIndex = Vocab_None;
}
Ngram *ngramLM;
{
File file(lmFile, "r");
ngramLM = new Ngram(vocab, order);
assert(ngramLM != 0);
ngramLM->debugme(debug);
ngramLM->read(file);
}
if (bayesLength >= 0) {
/*
* create a Bayes mixture LM
*/
Ngram *lm1 = ngramLM;
Ngram *lm2 = new Ngram(vocab, order);
assert(lm2 != 0);
lm2->debugme(debug);
if (!mixFile) {
cerr << "no mix-lm file specified\n";
exit(1);
}
File file2(mixFile, "r");
if (!lm2->read(file2)) {
cerr << "format error in mix-lm file\n";
exit(1);
}
/*
* create a Bayes mixture from the two
*/
useLM = new BayesMix(vocab, *lm1, *lm2,
bayesLength, mixLambda, bayesScale);
assert(useLM != 0);
useLM->debugme(debug);
} else {
useLM = ngramLM;
}
if (!sTag) {
sTag = vocab.getWord(vocab.ssIndex());
if (!sTag) {
cerr << "couldn't find a segment tag in LM\n";
exit(1);
}
}
/*
* Skip noise tags in scoring
*/
if (noiseVocabFile) {
File file(noiseVocabFile, "r");
useLM->noiseVocab.read(file);
}
if (noiseTag) { /* backward compatibility */
useLM->noiseVocab.addWord(noiseTag);
}
/*
* Read recognizer LM
*/
DecipherNgram oldLM(vocab, 2);
if (decipherLM) {
oldLM.debugme(debug);
File file(decipherLM, "r");
if (!oldLM.read(file)) {
cerr << "format error in Decipher LM\n";
exit(1);
}
}
if (nbestFiles) {
processNbestLists(nbestFiles, *useLM, oldLM,
startTagIndex, endTagIndex);
}
/*
* Process all remaining args as nbest list lists.
* Print delimiter info
*/
for (unsigned i = 1; argv[i] != 0; i ++) {
if (!(fbRescore && writeNbestDir)) {
cout << "<nbestfile " << argv[i] << ">\n";
}
processNbestLists(argv[i], *useLM, oldLM, startTagIndex, endTagIndex);
}
#ifdef DEBUG
if (ngramLM != useLM) {
delete ngramLM;
}
delete useLM;
return 0;
#endif /* DEBUG */
exit(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -