~ubuntu-branches/ubuntu/raring/sphinxtrain/raring-proposed

« back to all changes in this revision

Viewing changes to src/programs/bw/train_cmd_ln.c

  • Committer: Package Import Robot
  • Author(s): Samuel Thibault
  • Date: 2013-01-02 04:10:21 UTC
  • Revision ID: package-import@ubuntu.com-20130102041021-ynsizmz33fx02hea
Tags: upstream-1.0.8
ImportĀ upstreamĀ versionĀ 1.0.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ====================================================================
 
2
 * Copyright (c) 1994-2000 Carnegie Mellon University.  All rights 
 
3
 * reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 *
 
9
 * 1. Redistributions of source code must retain the above copyright
 
10
 *    notice, this list of conditions and the following disclaimer. 
 
11
 *
 
12
 * 2. Redistributions in binary form must reproduce the above copyright
 
13
 *    notice, this list of conditions and the following disclaimer in
 
14
 *    the documentation and/or other materials provided with the
 
15
 *    distribution.
 
16
 *
 
17
 * This work was supported in part by funding from the Defense Advanced 
 
18
 * Research Projects Agency and the National Science Foundation of the 
 
19
 * United States of America, and the CMU Sphinx Speech Consortium.
 
20
 *
 
21
 * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 
 
22
 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
 
23
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
24
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
 
25
 * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
26
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 
27
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
 
28
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
 
29
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 
30
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 
31
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
32
 *
 
33
 * ====================================================================
 
34
 *
 
35
 */
 
36
/*********************************************************************
 
37
 *
 
38
 * File: train_cmd_ln.c
 
39
 * 
 
40
 * Description: 
 
41
 * 
 
42
 * Author: 
 
43
 *      Eric H. Thayer (eht@cs.cmu.edu)
 
44
 *********************************************************************/
 
45
 
 
46
#include "train_cmd_ln.h"
 
47
 
 
48
#include <sphinxbase/cmd_ln.h>
 
49
#include <sphinxbase/feat.h>
 
50
#include <sphinxbase/err.h>
 
51
 
 
52
#include <s3/s3.h>
 
53
#include <sys_compat/file.h>
 
54
 
 
55
#include <stdio.h>
 
56
#include <stdlib.h>
 
57
#include <string.h>
 
58
#include <sys/types.h>
 
59
#include <assert.h>
 
60
 
 
61
int
 
62
validate_writeable_dir(char *switch_name, void *arg)
 
63
{
 
64
#ifndef WIN32
 
65
    char *path = arg;
 
66
    struct stat s;
 
67
 
 
68
    if (path == NULL) {
 
69
        E_ERROR("%s is a necessary switch\n", switch_name);
 
70
 
 
71
        return FALSE;
 
72
    }
 
73
 
 
74
    if (stat(path, &s) < 0) {
 
75
        E_ERROR("%s %s does not exist or is inaccessible\n", switch_name, path);
 
76
 
 
77
        return FALSE;
 
78
    }
 
79
 
 
80
    if (!S_ISDIR(s.st_mode)) {
 
81
        E_ERROR("%s %s is not a directory\n", switch_name, path);
 
82
 
 
83
        return FALSE;
 
84
    }   
 
85
 
 
86
    if ((s.st_mode && S_IWOTH) ||
 
87
        ((s.st_uid == getuid()) && (s.st_mode && S_IWUSR)) ||
 
88
        ((s.st_gid == getgid()) && (s.st_mode && S_IWGRP))) {
 
89
        return TRUE;
 
90
    }
 
91
    else {
 
92
        E_ERROR("%s %s is not writeable\n", switch_name, path);
 
93
 
 
94
        return FALSE;
 
95
    }
 
96
#else
 
97
    /* WIN32 */
 
98
 
 
99
    /* Do no validation for now.  Need to figure out WIN32 compatible way */
 
100
 
 
101
    return TRUE;
 
102
#endif
 
103
}
 
104
int
 
105
validate_opt_writeable_dir(char *switch_name, void *arg)
 
106
{
 
107
#ifndef WIN32
 
108
    char *path = arg;
 
109
    struct stat s;
 
110
 
 
111
    if (path == NULL) {
 
112
        return TRUE;
 
113
    }
 
114
 
 
115
    if (stat(path, &s) < 0) {
 
116
        E_ERROR("%s %s does not exist or is inaccessible\n", switch_name, path);
 
117
 
 
118
        return FALSE;
 
119
    }
 
120
 
 
121
    if (!S_ISDIR(s.st_mode)) {
 
122
        E_ERROR("%s %s is not a directory\n", switch_name, path);
 
123
 
 
124
        return FALSE;
 
125
    }   
 
126
 
 
127
    if ((s.st_mode && S_IWOTH) ||
 
128
        ((s.st_uid == getuid()) && (s.st_mode && S_IWUSR)) ||
 
129
        ((s.st_gid == getgid()) && (s.st_mode && S_IWGRP))) {
 
130
        return TRUE;
 
131
    }
 
132
    else {
 
133
        E_ERROR("%s %s is not writeable\n", switch_name, path);
 
134
 
 
135
        return FALSE;
 
136
    }
 
137
#else
 
138
    /* WIN32 */
 
139
 
 
140
    /* Do no validation for now.  Need to figure out WIN32 compatible way */
 
141
 
 
142
    return TRUE;
 
143
#endif
 
144
}
 
145
 
 
146
int
 
147
validate_readable_dir(char *switch_name, void *arg)
 
148
{
 
149
#ifndef WIN32
 
150
    char *path = arg;
 
151
    struct stat s;
 
152
 
 
153
    if (path == NULL) {
 
154
        E_ERROR("%s is a necessary switch\n", switch_name);
 
155
 
 
156
        return FALSE;
 
157
    }
 
158
 
 
159
    if (stat(path, &s) < 0) {
 
160
        E_ERROR("%s %s does not exist or is inaccessible\n", switch_name, path);
 
161
 
 
162
        return FALSE;
 
163
    }
 
164
 
 
165
    if (!S_ISDIR(s.st_mode)) {
 
166
        E_ERROR("%s %s is not a directory\n", switch_name, path);
 
167
 
 
168
        return FALSE;
 
169
    }   
 
170
 
 
171
    if ((s.st_mode && S_IROTH) ||
 
172
        ((s.st_uid == getuid()) && (s.st_mode && S_IRUSR)) ||
 
173
        ((s.st_gid == getgid()) && (s.st_mode && S_IRGRP))) {
 
174
        return TRUE;
 
175
    }
 
176
    else {
 
177
        E_ERROR("%s %s is not readable\n", switch_name, path);
 
178
 
 
179
        return FALSE;
 
180
    }
 
181
#else
 
182
    /* WIN32 */
 
183
 
 
184
    /* Do no validation for now.  Need to figure out a WIN32 compatible
 
185
       way */
 
186
 
 
187
    return TRUE;
 
188
#endif
 
189
}
 
190
 
 
191
int
 
192
validate_agc(char *switch_name, void *arg)
 
193
{
 
194
    if ((strcmp(arg, "max") == 0) || (strcmp(arg, "emax") == 0) || (strcmp(arg, "none") == 0)) {
 
195
        return TRUE;
 
196
    }
 
197
    else {
 
198
        E_ERROR("Unknown agc type %s %s\n", switch_name, arg);
 
199
 
 
200
        return FALSE;
 
201
    }
 
202
 
 
203
    assert(FALSE);
 
204
}
 
205
 
 
206
int
 
207
validate_cmn(char *switch_name, void *arg)
 
208
{
 
209
 
 
210
    if ((strcmp(arg, "current") == 0) ||
 
211
        (strcmp(arg, "none") == 0) ||
 
212
        (strcmp(arg, "prior") == 0)) {
 
213
        return TRUE;
 
214
    }
 
215
    else {
 
216
        E_ERROR("Unknown CMN type %s %s\n", switch_name, arg);
 
217
    }
 
218
    return TRUE;
 
219
}
 
220
 
 
221
 
 
222
/* defines, parses and (partially) validates the arguments
 
223
   given on the command line */
 
224
 
 
225
int
 
226
train_cmd_ln_parse(int argc, char *argv[])
 
227
{
 
228
  uint32      isHelp;
 
229
  uint32      isExample;
 
230
 
 
231
  const char helpstr[] =
 
232
"Description:\n\
 
233
Strictly speaking,  bw only implements the first-part of the Baum-Welch \n\
 
234
algorithm.  That is it go through forward and backward algortihm and\n\
 
235
collect the necessary statistics for parameter estimation.\n\
 
236
\n\
 
237
The advantage of this architecture is that researcher can easily write \n\
 
238
programs to do parameter estimation and they have no need to tweak the \n\
 
239
huge and usually difficult Baum-Welch algorithm. \n\
 
240
\n\
 
241
In terms of functionality, one important thing you need to know is option \n\
 
242
-part and -npart.  They can allow you to split the training into N equal parts\n\
 
243
Say, if there are M utterances in your control file, then this \n\
 
244
will enable you to run the training separately on each (M/N)th \n\
 
245
part. This flag may be set to specify which of these parts you want to \n\
 
246
currently train on. As an example, if your total number of parts (-npart) is 3, \n\
 
247
-part can take one of the values 1,2 or 3.  \n\
 
248
\n\
 
249
To control the speed of the training, -abeam (control alpha search) \n\
 
250
and -bbeam (control beta search) can be used to control the searching \n\
 
251
time.  Notice that if the beams are too small, the path may not reach \n\
 
252
the end of the search and results in estimation error \n\
 
253
Too many lost path may also cause training set likelihood not unable to increase \n\
 
254
\n\
 
255
Several options allow the user to control the behaviour of bw such \n\
 
256
that silence or pauses can be taken care\n\
 
257
\n\
 
258
Finally, one can use the viterbi training mode of the code.  Notice \n\
 
259
though, the code is not always tested by CMU's researcher \n\
 
260
\n\
 
261
I also included the following paragraph from Rita's web page. ";
 
262
 
 
263
  const char examplestr[]=
 
264
"Example: \n\
 
265
Command used to train continuous HMM \n\
 
266
(Beware, this only illustrates how to use this command, for detail on \n\
 
267
how to tune it, please consult the manual. ) \n\
 
268
bw \n\
 
269
-moddeffn mdef -ts2cbfn .cont.\n\
 
270
-mixwfn mixw -tmatfn tmatn -meanfn mean -varfn var\n\
 
271
-dictfn dict -fdictfn fillerdict \n\
 
272
-ctlfn control_files \n\
 
273
-part 1 -npart 1 \n\
 
274
-cepdir feature_dir -cepext mfc \n\
 
275
-lsnfn transcription \n\
 
276
-accumdir accumdir \n\
 
277
-abeam 1e-200 -bbeam 1e-200 \n\
 
278
-meanreest yes -varreest yes \n\
 
279
-tmatreest yes -feat 1s_12c_12d_3p_12dd \n\
 
280
-ceplen 13 \n\
 
281
\n\
 
282
If yo want to do parallel training for N machines. Run N trainers with \n\
 
283
-part 1 -npart N \n\
 
284
-part 2 -npart N \n\
 
285
.\n\
 
286
.\n\
 
287
-part N -npart N ";
 
288
 
 
289
    static arg_t defn[] = {
 
290
        { "-help",
 
291
          ARG_BOOLEAN,
 
292
          "no",
 
293
          "Shows the usage of the tool"},
 
294
 
 
295
        { "-example",
 
296
          ARG_BOOLEAN,
 
297
          "no",
 
298
          "Shows example of how to use the tool"},
 
299
 
 
300
        { "-hmmdir",
 
301
          ARG_STRING,
 
302
          NULL,
 
303
          "Default directory for acoustic model files (mdef, means, variances, transition_matrices, noisedict)" },
 
304
 
 
305
        { "-moddeffn",
 
306
          ARG_STRING,
 
307
          NULL,
 
308
          "The model definition file for the model inventory to train" },
 
309
 
 
310
        { "-tmatfn",
 
311
          ARG_STRING,
 
312
          NULL,
 
313
          "The transition matrix parameter file name"},
 
314
 
 
315
        { "-mixwfn",
 
316
          ARG_STRING,
 
317
          NULL,
 
318
          "The mixture weight parameter file name"},
 
319
 
 
320
        { "-meanfn",
 
321
          ARG_STRING,
 
322
          NULL,
 
323
          "The mean parameter file name"},
 
324
 
 
325
        { "-varfn",
 
326
          ARG_STRING,
 
327
          NULL,
 
328
          "The var parameter file name"},
 
329
 
 
330
        { "-fullvar",
 
331
          ARG_BOOLEAN,
 
332
          "no",
 
333
          "Variances are full covariance matrices"},
 
334
 
 
335
        { "-diagfull",
 
336
          ARG_BOOLEAN,
 
337
          "no",
 
338
          "Evaluate Gaussian densities using diagonals only"},
 
339
 
 
340
        { "-mwfloor",
 
341
          ARG_FLOAT32,
 
342
          "0.00001",
 
343
          "Mixing weight smoothing floor" },
 
344
 
 
345
        { "-tpfloor",
 
346
          ARG_FLOAT32,
 
347
          "0.0001",
 
348
          "Transition probability smoothing floor" },
 
349
 
 
350
        { "-varfloor",
 
351
          ARG_FLOAT32,
 
352
          "0.00001",
 
353
          "The minimum variance"},
 
354
        
 
355
        { "-topn",
 
356
          ARG_INT32,
 
357
          "4",
 
358
          "Compute output probabilities based this number of top scoring densities."},
 
359
 
 
360
        { "-dictfn",
 
361
          ARG_STRING,
 
362
          NULL,
 
363
          "The content word dictionary" },
 
364
 
 
365
        { "-fdictfn",
 
366
          ARG_STRING,
 
367
          NULL,
 
368
          "The filler word dictionary (e.g. SIL, SILb, ++COUGH++)" },
 
369
 
 
370
        { "-ctlfn",
 
371
          ARG_STRING,
 
372
          NULL,
 
373
          "The training corpus control file" },
 
374
 
 
375
        { "-nskip",
 
376
          ARG_INT32,
 
377
          NULL,
 
378
          "The number of utterances to skip at the beginning of a control file" },
 
379
 
 
380
        { "-runlen",
 
381
          ARG_INT32,
 
382
          "-1", /* until eof */
 
383
          "The number of utterances to process in the (skipped) control file" },
 
384
 
 
385
        { "-part",
 
386
          ARG_INT32,
 
387
          NULL,
 
388
          "Identifies the corpus part number (range 1..NPART)" },
 
389
 
 
390
        { "-npart",
 
391
          ARG_INT32,
 
392
          NULL,
 
393
          "Partition the corpus into this many equal sized subsets" },
 
394
 
 
395
        { "-cepext",
 
396
          ARG_STRING,
 
397
          "mfc",
 
398
          "The cepstrum file extension" },
 
399
 
 
400
        { "-cepdir",
 
401
          ARG_STRING,
 
402
          NULL,
 
403
          "The cepstrum data root directory" },
 
404
 
 
405
        { "-phsegext",
 
406
          ARG_STRING,
 
407
          "phseg",
 
408
          "Phone segmentation file extension" },
 
409
 
 
410
        { "-phsegdir",
 
411
          ARG_STRING,
 
412
          NULL,
 
413
          "Phone segmentation file root directory" },
 
414
 
 
415
        { "-outphsegdir",
 
416
          ARG_STRING,
 
417
          NULL,
 
418
          "Phone segmentation file output root directory" },
 
419
 
 
420
        { "-sentdir",
 
421
          ARG_STRING,
 
422
          NULL,
 
423
          "The sentence transcript file directory"},
 
424
 
 
425
        { "-sentext",
 
426
          ARG_STRING,
 
427
          "sent",
 
428
          "The sentence transcript file extension"},
 
429
 
 
430
        { "-lsnfn",
 
431
          ARG_STRING,
 
432
          NULL,
 
433
          "The corpus word transcript file"},
 
434
 
 
435
        { "-accumdir",
 
436
          ARG_STRING,
 
437
          NULL,
 
438
          "A path where accumulated counts are to be written." },
 
439
 
 
440
        { "-abeam",
 
441
          ARG_FLOAT64,
 
442
          "1e-100",
 
443
          "Evaluate alpha values subject to this beam"},
 
444
 
 
445
        { "-bbeam",
 
446
          ARG_FLOAT64,
 
447
          "1e-100",
 
448
          "Evaluate beta values (update reestimation sums) subject to this beam"},
 
449
 
 
450
        { "-varreest",
 
451
          ARG_BOOLEAN,
 
452
          "yes",
 
453
          "Reestimate variances"},
 
454
 
 
455
        { "-meanreest",
 
456
          ARG_BOOLEAN,
 
457
          "yes",
 
458
          "Reestimate means"},
 
459
 
 
460
        { "-mixwreest",
 
461
          ARG_BOOLEAN,
 
462
          "yes",
 
463
          "Reestimate mixing weights"},
 
464
 
 
465
        { "-tmatreest",
 
466
          ARG_BOOLEAN,
 
467
          "yes",
 
468
          "Reestimate transition probability matrices"},
 
469
 
 
470
        { "-mllrmat",
 
471
          ARG_STRING,
 
472
          NULL,
 
473
          "An MLLR transformation file to apply to the means of the model"},
 
474
 
 
475
        { "-cb2mllrfn",
 
476
          ARG_STRING,
 
477
          ".1cls.",
 
478
          "Codebook-to-MLLR-class mapping file name" },
 
479
 
 
480
        { "-ts2cbfn",
 
481
          ARG_STRING,
 
482
          NULL,
 
483
          "Tied-state-to-codebook mapping file name" },
 
484
 
 
485
        { "-timing",
 
486
          ARG_BOOLEAN,
 
487
          "yes",
 
488
          "Controls whether profiling information is displayed"},
 
489
        
 
490
        { "-viterbi",
 
491
          ARG_BOOLEAN,
 
492
          "no",
 
493
          "Controls whether Viterbi training is done"},
 
494
        
 
495
        { "-2passvar",
 
496
          ARG_BOOLEAN,
 
497
          "no",
 
498
          "Reestimate variances based on prior means"},
 
499
 
 
500
        { "-spthresh",
 
501
          ARG_FLOAT32,
 
502
          "0.0",
 
503
          "State posterior probability floor for reestimation.  States below this are not counted"},
 
504
        
 
505
        { "-maxuttlen",
 
506
          ARG_INT32,
 
507
          "0",
 
508
          "Maximum # of frames for an utt ( 0 => no fixed limit )"},
 
509
        
 
510
        { "-ckptintv",
 
511
          ARG_INT32,
 
512
          NULL,
 
513
          "Checkpoint the reestimation sums every -chkptintv utts" },
 
514
        
 
515
        { "-outputfullpath",
 
516
          ARG_BOOLEAN,
 
517
          "no",
 
518
          "Output full path of utterance to bw log output" },
 
519
        
 
520
        { "-fullsuffixmatch",
 
521
          ARG_BOOLEAN,
 
522
          "no",
 
523
          "Expect utterance id in transcript to be a suffix of the partial path in the control file" },
 
524
 
 
525
        { "-ldaaccum",
 
526
          ARG_BOOLEAN,
 
527
          "no",
 
528
          "Apply LDA in accumulation of statistics only (NOTE: no dimensionality reduction will be done)."},
 
529
 
 
530
        { "-pdumpdir",
 
531
          ARG_STRING,
 
532
          NULL,
 
533
          "Dump state/mixture posterior probabilities to files in this directory" },
 
534
 
 
535
        { "-latdir",
 
536
          ARG_STRING,
 
537
          NULL,
 
538
          "Directory that contains lattice files" },
 
539
 
 
540
        { "-mmie",
 
541
          ARG_BOOLEAN,
 
542
          "no",
 
543
          "Whether to do MMIE training or not" },
 
544
 
 
545
        { "-mmie_type",
 
546
          ARG_STRING,
 
547
          "rand",
 
548
          "how to get different context for Viterbi run on lattice, such as rand, best or ci. \n\
 
549
           \t\t\trand: randomly take the left and right context \n\
 
550
           \t\t\tbest: take the left and right context with the best acoustic score \n\
 
551
           \t\t\tci:   use context-independent hmm for word boundary models" },
 
552
 
 
553
        { "-latext",
 
554
          ARG_STRING,
 
555
          NULL,
 
556
          "Denominator or Numerator lattice. Use denlat or numlat" },
 
557
 
 
558
        { "-lw",
 
559
          ARG_FLOAT32,
 
560
          "11.5",
 
561
          "Language model weight" },
 
562
        /* end */
 
563
        
 
564
        cepstral_to_feature_command_line_macro(),
 
565
        {NULL, 0, NULL, NULL}
 
566
    };
 
567
 
 
568
    cmd_ln_parse(defn, argc, argv, 1);
 
569
 
 
570
 
 
571
    isHelp    = cmd_ln_int32("-help");
 
572
    isExample    = cmd_ln_int32("-example");
 
573
 
 
574
    if(isHelp){
 
575
      printf("%s\n\n",helpstr);
 
576
    }
 
577
 
 
578
    if(isExample){
 
579
      printf("%s\n\n",examplestr);
 
580
    }
 
581
 
 
582
    if(isHelp || isExample){
 
583
      E_INFO("User asked for help or example.\n");
 
584
      exit(0);
 
585
    }
 
586
 
 
587
    return 0;
 
588
}
 
589