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.