Poradnik HTK

Transkrypt

Poradnik HTK
Poradnik HTK
Adrian Sekuła
Wstęp
Poradnik wykonano do przedmiotu Technologia Mowy, prowadzonego przez dr inż. Bartosza Ziółko i dr inż.
Jakuba Gałkę na studiach Inżynieria Akustyczna na AGH w Krakowie. Na początku pracy z HTK dobrze jest
odpowiednio przygotować wszystko do pracy – zmniejszy to ewentualne problemy w dalszych etapach.
Wszystkie dane najlepiej zapisywać w jednym folderze, czyli tworzymy folder w stylu ‘Projekt’, ‘HTK’, albo
dowolnie inaczej i wrzucamy do niego: wszystkie pliki .exe z HTK; tworzymy foldery od hmm0 do hmm10.
To są rzeczy, które będą potem niezbędne i warto o nie zadbać już na samym początku.
Należy pamiętać:
HTK nie współdziała z polskimi znakami, tak więc polskie znaki zapisujemy jako duże litery, zaś frazy
dwuczłonowe oddzielami podkreśleniem (możemy to zrobić oczywiście dowolnie, lecz ten sposób wydaje
się być intuicyjny). Wybór alfabetu do transkrypcji fonetycznej również jest dowolny, lecz zalecany jest
Corpora Grocholewski. Można wesprzeć się Ortfonem AGH, aby tą transkrypcję wykonać. Komendy
wpisujemy z poziomu Command Windows w Windowsie (Start -> Uruchom -> cmd), należy zawsze przejść
do katalogu w którym działamy (przykładowo cd D:\...\HTK).
Przydatne linki/narzędzia:
ORTFON AGH - http://www.dsp.agh.edu.pl/doku.php?id=pl:resources:ortfon
Objaśnienie większości błędów występujących podczas pracy z HTK - http://www.ling.ohiostate.edu/~bromberg/htk_problems.html
Htkbook – oficjalna dokumentacja HTK, po zarejestrowaniu się możemy ściągnąć z tej strony:
http://htk.eng.cam.ac.uk/docs/docs.shtml
1. Zaprojektowanie gramatyki
Pierwszym punktem pracy z HTK jest wykonanie pliku tekstowego gram.txt (najwygodniej jest później
usunąć rozszerzenie .txt, ponieważ ułatwi to pracę oraz skróci wpisywanie komend). W pliku tym
definiujemy nasz bank słów oraz zdania, którymi będziemy się posługiwać podczas pracy z naszym
systemem rozpoznawania mowy.
Przykładowa zawartość plików gram:
Zdjęcie 1. – przykładowy plik gram nr 1
Zdjęcie 2. – przykładowy plik gram nr 2
Znak ‘|’ jest używany jako ‘lub’.
W zapisie typu [STEVE] YOUNG element w nawiasie kwadratowym [] jest elementem opcjonalnym, czyli
zmienna może przyjąć zarówno wartość STEVE, jak i STEVE YOUNG.
SENT-START oraz SENT-END to komendy startujące/kończące.
Słowo/fraza w nawiasie () oznacza możliwość dowolnej ilości wystąpień (np. pisząc ‘(kolorowe)’ możemy
uzyskać słowo kolorowe dowolną ilość razy w rozpoznaniu).
2. Kompilacja gramatyki
Powyższy opis gramatyki służy wygodzie użytkowania, HTK używa jedynie pliku wdnet, który uzyskujemy na
podstawie naszego pliku gram, przy pomocy komendy HParse wpisując następującą komendę w command
window:
HParse gram wdnet
Po wpisaniu powyższej komendy powinniśmy mieć w naszym głównym folderze HTK plik słowosieci wdnet.
3. Słownik
Następnym krok to stworzenie słownika (plik dict), w którym będą zawierać się wszystkie słowa jakich
użyjemy w naszym systemie oraz ich zapis fonetyczny. Przykładowe pliki dict:
Zdjęcie 3. – przykładowy plik dict nr 1
Zdjęcie 4. – przykładowy plik dict nr 2
Forma zapisu jest następująca: słowo - tabulator - zapis fonetyczny. Słowa zapisujemy tak jak w naszym
pliku z gramatyką, czyli znaki polskie zastępujemy wielkimi literami, w wypadku frazy możemy oddzielić
kolejne słowa podkreśleniem, lub po prostu zapisać je łącznie. Jak widać występują tu również ‘sp’ na
końcu każdego zapisu fonetycznego, jest to znak ciszy między słowami, który może zwiększyć nasze
rozpoznanie końcowe. Tak samo z ‘sil’ – jest to modelowanie ciszy na początku i na końcu naszego
nagrania, zapisujemy je w taki sposób jak na powyższych zdjęciach.
4. Nagranie treningowe
Kolejnym krokiem jest utworzenie nagrania (lub nagrań, lecz prostsza i wygodniejsza jest forma nagrania w
jednym pliku) treningowego. Czas trwania nagrania to ok. 3min, format .wav, parametry to mono, 16bit,
częstotliwość próbkowania 16kHz. Ścieżkę tworzymy w oparciu o plik gram, mogą to być zdania oraz
pojedyncze słowa. Ważne jest, aby każde słowo, którego używamy w dict było użyte kilka razy (najlepiej
więcej niż 2, oszczędzi to warningów podczas dalszej pracy).
5. Anotacja
Anotacja na poziomie słów jest możliwa dzięki powstałemu na AGH programowi Anotator (Audio
Descriptor). Operujemy na dwóch oknach – jedno z nich zawiera cały tekst naszego nagrania testowego,
słowa zapisujemy tam tak jak w pliku dict i gram, czyli wielkie litery zamiast polskich znaków i ewentualne
łączenia fraz. W drugim oknie mamy przebieg czasowy naszego nagrania, gdzie zaznaczamy odpowiednio
lewym przyciskiem myszki początek danego słowa/frazy, prawym przyciskiem myszki jego koniec,
następnie możemy sobie ten fragment odsłuchać i porównać słowo jakie słyszymy z zapisem w drugim
oknie – jeśli się zgadza to przechodzimy do kolejnego słowa i tak do końca.
Anotacja na poziomie fonemów jest możliwa w programie Anotator 2, czyli nowszej wersji Anotatora AGH.
Mamy tam możliwość automatycznego podziału na fonemy, lecz nie zawsze jest ono zgodne i warto to
później odpowiednio skorygować, żeby uniknąć późniejszych problemów.
6. Kodowanie nagrania
Kodowanie odbywa się przy obecności pliku config. Należy zwrócić uwagę na pierwszą linijkę – powinniśmy
mieć ‘TARGETKIND = MFCC_0_D_A’, a nie jak w htkbook ‘TARGETKIND = MFCC_0’, aby uzyskać pełny 39elementowy wektor MFCC. Bardzo ważne jest również dopisanie dodatkowej linijki ‘SOURCEFORMAT =
WAV’, umożliwi nam to pracę na naszym pliku nagraniowym w formacie .wav. Config powinien więc
wyglądać w sposób następujący:
Zdjęcie 5. – plik config
Musimy również utworzyć plik codetr.scp, w którym zawierać się będzie ścieżka do pliku z nagraniami, oraz
taka sama ścieżka, lecz z rozszerzeniem .mfc. Przykładowo:
D:\...\HTK\nagranie.wav D:\...\HTK\nagranie.mfc
Niezbędne może być także utworzenie pliku o nazwie takiej jak nasze nagranie treningowe, z
rozszerzeniem .lab (np. nagranie.lab), w którym znajdować się będą wszystkie fonemy w takiej kolejności
jak w naszym nagraniu treningowym (jeśli modelujemy ciszę – z uwzględnieniem sil oraz sp).
Mając potrzebne pliki używamy następującej komendy:
HCopy –T 1 –C config –S codetr.scp
7. Utworzenie prototypowego modelu HMM
Potrzebujemy utworzyć prototypowy model HMM. Do tego celu niezbędny będzie plik proto, który
powinien wyglądać tak:
Zdjęcie 6. – plik proto
Po utworzeniu pliku proto potrzebujemy jeszcze train.scp, w którym zapisana będzie ścieżka do naszego
nagrania treningowego, podobnie jak w codetr.scp z tą jednak rożnicą, że bez drugiej ścieżki do pliku .mfc.
Należy pamiętać, żeby wcześniej utworzony był folder hmm0, a nawet wszystkie foldery od hmm0 do
hmm10, gdyż HTK nie potrafi tworzyć folderów.
Wywołujemy teraz komendę:
HCompV –C config –f 0.01 –m –S train.scp –M hmm0 proto
Powinniśmy dostać dwa pliki w folderze hmm0 – vFloors oraz proto. Musimy teraz utworzyć dwa nowe pliki
w tym samym folderze – macros i hmmdefs. Zawartość pliku macros to nagłówek w postaci:
~o
<VecSize> 39
<MFCC_0_D_A>
Pozostałą część tego pliku uzyskujemy kopiując zawartość vFloors. Powinno to wyglądać mniej więcej
tak:
Zdjęcie 7. – plik macros
W pliku hmmdefs tworzymy modele HMM dla każdego fonemu występującego w naszym słowniku,
łącznie z sp oraz sil (jeśli modelujemy ciszę pomiędzy słowami oraz na początku i końcu). Dane
pomiędzy <BeginHMM>, a <EndHMM> kopiujemy (z pliku proto w katalogu hmm0) jednakowo dla
każdego fonemu. Początek powinien wyglądać w taki sposób:
[...]
[...]
Analogicznie dla wszystkich fonemów, które występują w naszym słowniku, oczywiście z dalszą
częścią skopiowaną z pliku proto, aż do <EndHMM>.
8. Reestymacja modeli
Na podstawie danych treningowych, anotacji na poziomie fonemów (np. segmentacja.mlf), listy
fonemów zawartej w pliku monophones0 (tworzymy plik monophones0, w którym wypisujemy
wszystkie fonemy z naszego słownika z góry na dół, same fonemy), oraz modeli z folderu hmm0
wyliczamy modele do folderu hmm1 (folder ten musi być uprzednio utworzony, HTK nie potrafi
tworzyć folderów). Wykonujemy to przy pomocy komendy (można ją znaleźć na stronie 34 w
htkbook):
HERest -C config -I segmentacja.mlf -t 250.0 150.0 1000.0 -S train.scp -H hmm0/macros -H
hmm0/hmmdefs -M hmm1 monophones0
Następnie powtarzamy tę czynność w zależności od ilości reestymacji – 10 jest optymalną liczbą.
Komendy dla kolejnych reestymacji będą wyglądać w następujący sposób:
HERest -C config -I segmentacja.mlf -t 250.0 150.0 1000.0 -S train.scp -H hmm1/macros -H
hmm1/hmmdefs -M hmm2 monophones0
HERest -C config -I segmentacja.mlf -t 250.0 150.0 1000.0 -S train.scp -H hmm2/macros -H
hmm2/hmmdefs -M hmm3 monophones0
I tak dalej, aż do hmm10 (lub więcej/mniej, jeśli chcemy mieć więcej/mniej reestymacji).
9. Testowanie systemu
Pierwszą rzeczą, którą musimy przygotować to nagrania testowe – ok. 10 plików .wav, nagranych w
mono, 16bit, 16kHz, w każdym z tych plików po jednym zdaniu, które chcemy, aby nasz system
rozpoznał. Następnie tworzymy plik test.scp, w którym powinny być ścieżki do wszystkich plików
testowych. Teraz wystarczy wywołać komendę, jej efektem będzie plik recout.mlf zawierający
zdania/kolejne słowa jakie HTK udało się rozpoznać dla każdego pliku testowego. Ważny jest również
numer reestymacji, gdyż rozpoznanie będzie dla każdego różne, więc wykonujemy go dla wszystkich
folderów od hmm1 do hmm10.
Komenda dla hmm1:
HVite -H hmm1/macros -H hmm1/hmmdefs -S test.scp -i recout1.mlf -C config -w wdnet -p 0.0 -s 5.0 dict
monophones0
Komenda dla hmm10:
HVite -H hmm10/macros -H hmm10/hmmdefs -S test.scp -i recout10.mlf -C config -w wdnet -p 0.0 -s 5.0
dict monophones0
10. Opracowanie statystyczne wyników
Jest to ostatni krok pracy z HTK. Dowiemy się teraz jakie jest procentowe rozpoznanie naszych zdań oraz
procentowe rozpoznanie słów. Przed wpisaniem komendy musimy jednak utworzyć dwie rzeczy. Pierwsza z
nich to dla każdego nagrania testowego plik .lab o takiej samej nazwie jak plik z nagraniem. Plik ten
zawierać powinien kolejne fonemy lub słowa w zapisie ortograficznym (jak w słowniku), tak samo jak w
naszym nagraniu. Druga rzecz to plik testref.mlf, w którym wypisane będą kolejne słowa ze wszystkich
nagrań. Powinien wyglądać mniej więcej tak:
Zdjęcie 6. – plik testref.mlf
‘1.lab’, ‘2.lab’ etc. to w tym wypadku pliki, które tworzyliśmy przed chwilą na podstawie naszych nagrań
testowych.
Gdy wykonamy wszystkie powyższe podpunkty nie pozostaje nic innego jak wprowadzić komendę:
HResults -I testref.mlf monophones recout.mlf
Wynikiem tej komendy powinno być procentowe rozpoznanie. Możemy to wykonać dla wszystkich
reestymacji, ponieważ wyniki będą różne. Przykładowo:
Zdjęcie 9. – przykładowe rozpoznania dla kilku różnych reestymacji
Częste błędy podczas pracy z HTK
1.
Błąd ten występuje, gdy program napotka w którymś z plików przez nas utworzonych coś w rodzaju
‘białego znaku’. Możemy to łatwo zniwelować – zmieniając kodowanie plików, których używamy w tej
komendzie na ANSI.
2.
W tym wypadku spotykamy się z brakiem modelu dla ‘sp’ w którymś z plików. Równie dobrze mógłby to
być zamiast ‘sp’ problem z jakimkolwiek fonemem. Rozwiązanie jest dość proste – każdy fonem musi się
znaleźć we WSZYSTKICH plikach tj. – monophones0, hmmdefs oraz dict.
3.
Ten błąd przytrafiał się dość często, choć jest trywialny. Chodzi tu o błędne zapisanie komendy – jak widać
na screenie jest tu zapisane ‘-1’ (słownie: jeden), zdarza się też zapisanie jako ‘–I’ (duże i), a powinno być ‘-l’
(czyli małe L). Wynika to podobieństwa tych liter, ale jednak jest to błąd.
4.
Te dwa błędy są nieco podobne do poprzedniego, lecz nie chodzi tu o złe zapisanie komendy, lecz o brak
jakiegoś fragmentu. W pierwszym wypadku brakuje nam ‘-H’ przed ‘hmm0’, w miejscu oznaczonym
czerwonym kolorem; w drugim przypadku brakuje ‘–C’ przed ‘config.txt’. Zawsze przy wystąpieniu błędu
należy najpierw zwrócić uwagę na przepisaną komendę – czy nie brakuje czegoś, czy nie ma błędów,
ponieważ takie problemy są najprostsze do usunięcia, a występują stosunkowo często.
5.
Te warningi występujące przy HERest nie są co prawda poważnym błędem, lecz mogą obniżyć procent
rozpoznania na końcu. W tym wypadku stworzone zostały modele HMM dla ‘z’, ‘sp’ i ‘sil’, ale nie były użyte
w segmentacji/pliki dict. Może to wynikać z tego, że nie używamy zupełnie danego fonemu, a go
wpisaliśmy, lub może to być zbyt mała liczba użyć tego fonemu (przykładowo w nagraniu tylko raz mówimy
słowo ‘zamek’ i w żadnym innym słowie nie występuje fonem ‘z’, wtedy mamy tylko jedno jego
wystąpienie. Jeśli chodzi o modelowanie ciszy to po prostu musimy zdecydować, czy będziemy to
praktykować, czy nie i na podstawie tego albo wszędzie zamieszczamy modele ciszy, albo nigdzie, aby
wyzbyć się tego typu błędów.
6. input file is not RIFF format, OpenWaveInput: Get[format]HeaderInfo failed, OpenAsChannel:
OpenWaveInput failed, OpenBuffer: OpenAsChannel failed, HBF: config parameters invalid
Ten błąd występuje często w różnych momentach pracy z HTK. Rozwiązaniem jest zazwyczaj dopisanie w
pliku config dodatkowej linii ‘SOURCEFORMAT = WAV’.
7. HERest -C config -I phones0.mlf -t 250.0 150.0 1000.0 \ -S train.scp -H hmm0/macros -H
hmm0/hmmdefs -M hmm1 monophones0
ERROR [+5010] InitSource: Cannot open source file -S
ERROR [+7010] InitHMMSet: Can't open list file -S
ERROR [+2321] Initialise: MakeHMMSet failed
Przepisując komendę HERest wprost z htkbook możemy przypadkiem przepisać ją ze znakiem ‘\’ – w HTK
jest to po prostu znak nowej linii i pomijamy go. Komenda powinna więc wyglądać tak:
HERest –C config –l phones0.mlf –t 250.0 150.0 1000.0 –S train.scp –H hmm0/macros –H hmm0/hmmdefs
–M hmm1 monophones0
8. ERROR [+7036] CreateHMM: multiple use of logical HMM name b
ERROR [+7060] InitHMMSet: Error in CreateHMM
ERROR [+2321] Initialise: MakeHMMSet failed
Ten błąd mówi nam, że użyliśmy modelu HMM ‘b’ więcej niż jeden raz. Wystarczy, że w hmmdefs
zidentyfikujemy dwa użycia modelu ‘b’ i jedno z nich usuniemy.