#!/usr/bin/perl -w # ./mkmodel.pl train_data use strict; use File::Basename; my $proto2hmmdefs = check_prog("proto2hmmdefs"); my $makespmodel = check_prog("makespmodel.pl"); if (@ARGV != 1) { print STDERR "Usage: mkmodel.pl \n"; exit 2; } my ($train_data) = @ARGV; if (! -d $train_data) { print STDERR "Training data directory '$train_data' not found\n"; exit 2; } print "Clearing old results...\n"; my $tmpdir = "tmp"; run("rm -rf '$tmpdir'"); mkdir $tmpdir; my $outdir = "final"; run("rm -rf '$outdir'"); mkdir $outdir; my $current_hmm = 0; # Figure out which label and sound files to use print "Figuring out which sound files are transcribed...\n"; my @labelfiles = glob "$train_data/*.lab"; my @allsoundfiles = glob "$train_data/*.wav"; my @soundfiles = (); foreach (@allsoundfiles) { (my $l = $_) =~ s/\.wav$/.lab/; if (! -f $l) { print STDERR "No transcription for $_, skipping.\n"; } elsif ((stat($l))[7] == 0) { print STDERR "Transcription for $_ is empty, skipping.\n"; } else { push @soundfiles, $_; } } printf("Using %d out of %d files.\n", scalar(@soundfiles), scalar(@allsoundfiles)); # Create a list of all the phones used in the training data. print "Creating monophone list from training data...\n"; my %monophones = (); foreach my $labf (@labelfiles) { open LABF, $labf; while () { chomp; s/^\d+\s+\d+\s+(\S+).*$/$1/; $monophones{$_} = 1; } close LABF; } open MONO, ">$tmpdir/monophones1"; foreach (sort (keys %monophones)) { print MONO "$_\n"; } close MONO; # Create a monophone list without the short pause model run("grep -v '^sp\$' '$tmpdir/monophones1' > '$tmpdir/monophones0'"); # Decide on a parametrization configuration. Currently this # uses the fixed configuration recommended in the HTK tutorial. print "Parametrizing training data...\n"; open PARAM_CONFIG, ">$tmpdir/param_config"; print PARAM_CONFIG<$tmpdir/codetr.scp"; open TRAIN, ">$tmpdir/train.scp"; foreach my $u (@soundfiles) { my ($f,$dir,$ext) = fileparse($u, qr/\.[^.]*/); my $mfc = "$tmpdir/train_param/$f.mfc"; print CODETR "$u $mfc\n"; print TRAIN "$mfc\n"; } close TRAIN; close CODETR; run("HCopy32 -C $tmpdir/param_config -S $tmpdir/codetr.scp"); # Create a simple prototype model to start each model from. print "Creating prototype model...\n"; open PROTO, ">$tmpdir/proto"; print PROTO< 39 ~h "proto" 5 2 39 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 39 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 3 39 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 39 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 4 39 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 39 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 5 0.0 1.0 0.0 0.0 0.0 0.0 0.6 0.4 0.0 0.0 0.0 0.0 0.6 0.4 0.0 0.0 0.0 0.0 0.7 0.3 0.0 0.0 0.0 0.0 0.0 END close PROTO; open PARAM_CONFIG, "$tmpdir/param_config"; open TRAIN_CONFIG, ">$tmpdir/train_config"; while () { if (/^TARGETKIND/) { print TRAIN_CONFIG "TARGETKIND = MFCC_0_D_A\n"; } elsif (!/^SOURCEFORMAT/) { print TRAIN_CONFIG; } } close TRAIN_CONFIG; close PARAM_CONFIG; # Set the mean and variance of the prototype to be the # mean and variance of the whole data set. my $outdir0 = current_hmm_dir(); mkdir $outdir0; run("HCompV32 -C $tmpdir/train_config -f 0.01 -m -S $tmpdir/train.scp -M '$outdir0' $tmpdir/proto"); open MACROS, ">$tmpdir/hmm0/macros"; print MACROS "~o 39 \n"; open VFLOORS, "$tmpdir/hmm0/vFloors"; while () { print MACROS; } close VFLOORS; close MACROS; # Make a copy of the prototype model for each of the phones # in the dictionary. print "Creating initial models...\n"; run("$proto2hmmdefs $tmpdir/hmm0/proto $tmpdir/monophones0 > $tmpdir/hmm0/hmmdefs"); # Re-estimate the models three times using the training data. reestimate("$tmpdir/train.scp", "$tmpdir/monophones0"); reestimate("$tmpdir/train.scp", "$tmpdir/monophones0"); reestimate("$tmpdir/train.scp", "$tmpdir/monophones0"); # Fix the silence model by introducing a new short pause # model tied to the existing silence model, and making the existing # silence model more robust by adding backwards transitions to it. print "Fixing the silence model...\n"; my ($indir1, $outdir1) = new_hmm(); run("cp '$indir1/macros' '$outdir1/macros'"); run("$makespmodel < '$indir1/hmmdefs' > '$outdir1/hmmdefs'"); open SIL_HED, ">$tmpdir/sil.hed"; print SIL_HED<