Viterbiho algoritmus pro rozpoznávání izolovaných slov - instrukce k laboratořím 10 a 11 a k projektu 4. Lukáš Burget a Jan Černocký, Thu Apr 29 18:06:24 CEST 2004 LB a JČ, verze 2. Fri Apr 30 15:26:32 CEST 2004 ==================================================================== Úkolem tohoto cvičení a následujícího projektu je napsat Viterbiho algoritmus pomocí "token passing" (pivo passing) a vytvořit jednoduchý rozpoznávač izolovaných slov ano/ne. Co máte k disposici: - modely natrénované pomocí HTK. - detektor slov založený na energii, který má na výstupu "vykousnutá" jenotlivá slova. Jako test ale použijte slova předem uložená v souborech (např. z laboratoře HTK ano/ne). - HTK toolkit. - pomocné funkce pro načtení souboru s příznaky a pro vypočet hodnoty hustoty gaussovské rozložení - viz soubor README_VITERBI.txt Struktura rozpoznávače: 1. Příprava modelů: modely jednotlivých slov uložíme do textových souborů s touto strukturou: 5 39 mean ..... mean mean ..... mean mean ..... mean mean ..... mean mean ..... mean var ... var var ... var var ... var var ... var var ... var matice prechod pravdepodobnosti .... (všimněte si, že se prakticky jedná o HTK soubory s vymazanými klíčovými slovy). Tento převod za Vás může zařídit Perlový skript: htk2lukas_5states.pl ~/HTK/ANO_NE/hmm1/ANO > ano htk2lukas_5states.pl ~/HTK/ANO_NE/hmm1/NE > ne 2. Práce se zvukovými soubory a soubory s parametry - na vstupu je signál ze zvukovky, a detektor aktivity, který produkuje soubory *.raw (8 kHz, 16 bitů), případně předem uložené soubory. - provedete parametrizaci pomocí HCopy s konfiguračním souborem tool.conf (12 MFCC koeficientů + energie, delta, deltadelta). HCopy -C tool.conf soubor.raw soubor.mfc tento soubor bude vstupem pro Viterbiho. 3. Viterbi - napsat ho bude Vaším úkolem. - bude se volat následujícím způsobem: viterbi model soubor.mfc - na standardním výstupu vypíše Viterbiho log-pravděpodobnost. Popis užitečných funkcí v README_VITERBI.txt: int ReadHTKHeader (FILE * fp_in, HTK_Header * header, int Swap) načtení HTK hlavičky ze souboru s parametry (mfc) - fp_in - pointer na soubor s parametry, který musí být otevřený pro čtení. - HTK_Header - struktura hlavičky HTK souboru - z ní Vás zajímá jen nSample - počet vektorů - rámců sampSize - délka vektoru v Byte (39*4), abyste dostali počet koeficientů příznakového vektoru musíte dělit 4=sizeof(float). Podle techto informaci budete muset naalokovat pole pro parametry. - swap - jestli chceme přehazovat pořadí Byte - HTK default jsou jiné architektury než PC, takže CHCEME. Při volání nastavit na 1.. výstupní hodnota: 0 pokud ok, -1 pokud chyba. int ReadHTKFeature(FILE * fp_in, float *in, size_t fea_len, int swap) načtení jednoho či více příznakových vektorů parametrů - fp_in - pointer na soubor s parametry, který musí být otevřený pro čtení. - in - vektor, kam budeme parametry ukládat, musí být naalokovaný na fea_len floatů (to bude 4*39*pocet_rámců bajtů). - fea_len - počet načítaných keficientů (39*pocet_rámců) - swap - Opět při volání nastavit na 1. výstupní hodnota: 0 pokud ok, -1 pokud chyba. float LogGaussPDF(float *observation, float *means, float *variances, int size) Výpočet LOG hodnoty hustoty pravděpodobnosti (neboli log vysílací pravděpodobnosti vektoru stavem). - observation - vektor parametrů (39 floatů) - means - vektor středích hodnot (39 floatů) - variances - vektor rozpytlů (39 floatů) (pamatujeme si, že pokud pracujeme s diagonálními kovar. maticemi, ukládáme jen rozptyly, které jsou na diagonále). - size - velikost všech vektorů (39). výstupní hodnota: logaritmus "vysílací pravděpodobnosti" - praktické poznámky k Viterbimu: - je vhodné si definovat dva vektory, každý bude mít tolik buněk, kolik je v HMM stavů. V jednom budou hodnoty žetonů (piv) TEĎ, ve druhém hodnoty žetonů po posunu z času t do času t+1: POTOM Posun: - vektor POTOM nastavíte na velmi záporné hodnoty (pozor, ne na nuly,logaritmy mohou být běžně záporné !) - každý žeton podle potřeby naklonujete (více připojených stavů), a "dolejete" příslušené logaritmy vysílací a přechodové pravděpodobnosti. - umístíte na správné místo v POTOM, ale díváte se, zda už na tom místě něco není, pokud ano a je to větší, necháte tuto větší hodnotu. To je ekvivalentní "hubení méně plných piv". Když jste s posunem hotoví, překopírujete POTOM do TEĎ. Inicializace a ukončení algoritmu viz přednáška. 4. Vlastní rozpoznání musíte srovnat Viterbiho pravděpodobnosti ze dvou modelů - podobně jako u DTW to můžete udělat v jednom programu (bude načítat dva modely), nebo v externím programu nebo skriptu.