Udostępnij za pośrednictwem


Czytnik BrainScript HTKMLF

Ostrzeżenie

HTKMLFReader jest przestarzały i jest zastępowany przez deserializatory HTK MLF i feature, cf. Understanding and Extending Czytelnicy. Użyj ich w sieciach.

HTKMLFReader to czytnik danych, który odczytuje pliki zwykle skojarzone z zadaniami rozpoznawania mowy, a konkretnie z zestawem narzędzi Hidden Markov Model Toolkit (HTK). Czytelnik może przyjąć jako dane wejściowe dwa typy plików, listę plików funkcji znanych w parlance HTK jako scp plik ("plik skryptu"), plik etykiety znany jako mlf plik ("plik etykiety modelu") i plik archiwum.

HTKMLFReader opiera się na zdefiniowanych formatach zestawów danych HTK, dlatego zalecamy zapoznanie się z podstawami HTK przy użyciu, np. HTK Book.

Ponieważ CNTK mogą służyć do tworzenia sieci z dowolną topologią, w tym sieci z wieloma wejściami i wyjściami, HTKMLFReader może przetwarzać jeden lub wiele scp plików iMLF. Typowy przykład użycia funkcji HTKMLFReader jest następujący:

    reader = [
        readerType = "HTKMLFReader"
        readMethod = "blockRandomize"
        miniBatchMode = "partial"
        randomize = "17280000"
        features = [
            dim = 792
            scpFile = "$ScpDir$\TIMIT.train.scp.fbank.fullpath"
        ]
        labels = [
            mlfFile = "$MlfDir$\TIMIT.train.align_cistate.mlf.cntk"
            labelDim = 183
            labelMappingFile = "$MlfDir$\TIMIT.statelist"
        ]
    ]

Element HTKMLFReader ma następujące parametry konfiguracji:

  • readMethod: metoda używana do odczytywania plików funkcji do pamięci na potrzeby przetwarzania podczas trenowania sieci. Ustawienie na readMethod wartość spowoduje blockRandomize podzielenie danych na duże bloki, a następnie losowanie kolejności bloków, a następnie kolejność danych w bloku. Dane w każdym bloku są odczytywane bezpośrednio z plików funkcji i zwalniane z pamięci RAM, gdy nie są już używane. Opcja blockRandomize wymaga pliku archiwum opisanego poniżej. Ponadto, jak opisano poniżej, w przypadku użycia w połączeniu blockRandomize z frameMode = "false" metodą odczytu losowe na wypowiedziach, ale nie ramek. Jest to odpowiednie do użycia z powtarzanymi architekturami w przypadku zachowania sekwencyjnego charakteru przykładów trenowania. Alternatywą jest , rollingWindow która odczytuje wszystkie pliki funkcji i przechowuje je na dysku w jednym dużym tymczasowym pliku binarnym. Dane są następnie losowe, uruchamiając duże okno przewracania danych w tym pliku i losując dane w oknie. Tej metody należy używać tylko wtedy, gdy plik archiwum jest niedostępny i działa tylko w trybie ramki. Domyślną metodą jest blockRandomize.

  • pageFilePath: określ miejsce przechowywania tymczasowego pliku stronicowania funkcji. Domyślnie będzie on używać pliku tymczasowego dostarczonego przez system.

  • randomize: Określa rozmiar okna randomizacji. CNTK używa okna kroczącego o tym rozmiarze danych do próbkowania. Tylko próbki wewnątrz tego okna operacyjnego są ładowane z dysku i przechowywane w pamięci RAM tylko tak długo, jak to konieczne. Zalecane ustawienie dla corpora mowy o rozmiarze produkcyjnym wynosi 48 godzin, tj. określ wartość 17280000. Parametr randomize rozumie również dwie specjalne wartości: auto lub none. none całkowicie wyłącza losowość, przydatną do oceny lub zapisywania danych wyjściowych. auto odczyta cały korpus do pamięci RAM, która zazwyczaj nie jest wykonalna lub pożądana w przypadku zestawów danych o rozmiarze produkcyjnym kilku tysięcy godzin mowy.

  • minibatchMode: partial lub full, ta opcja decyduje, jak obsłużyć ostatni minibatch, jeśli nie ma wystarczającej liczby ramek, aby utworzyć kompletny minibatch żądanego rozmiaru. Wartość domyślna to partial, która będzie używać pozostałych ramek w mniejszej końcowej minibatch epoki trenowania. Opcja full będzie przetwarzać tylko minibatches.

Powyższy przykład zawiera dwa źródła danych przetwarzanych przez czytelnika, funkcje w postaci listy plików funkcji HTK i etykiety, które są w postaci pliku MLF zestawu HTK. Obie funkcje i etykiety odpowiadają węzłom w sieci obliczeniowej, w tym przypadku odpowiednio węzłom wejściowym i wyjściowym. Należy pamiętać, że features i labels są domyślnymi nazwami używanymi przez simpleNetworkBuilder, ale jeśli sieć została zaprojektowana przy użyciu języka opisu sieci (NDL), można użyć dowolnych nazw, o ile każda z nich ma odpowiedni węzeł w sieci.

Aby określić funkcje o stałej wartości, np. współczynniki filtru log mel MFCC, należy uwzględnić następujące parametry w bloku konfiguracji:

  • scpFile: lista plików do przetworzenia. Pliki powinny być plikami zgodnymi z zestawem HTK i można je określić w formacie standardowym lub "archiwum". Szczegóły korzystania z archiwum opisano poniżej.

  • dim: liczba całkowita określająca pełny wymiar wektora funkcji z żądanym oknem kontekstu. Jeśli na przykład masz 72-wymiarowe cechy (24-wymiarowe cechy filtru plus współczynniki różnicowe i różnicowe), a sieć jest przeznaczona do przetwarzania okna kontekstowego 11 ramek, określony wymiar powinien mieć wartość 792. Należy pamiętać, że obsługiwane są tylko okna kontekstowe symetryczne.

Aby określić odpowiednie etykiety, np. etykiety phoneme lub senone, należy użyć bloku konfiguracji, który określa następujące parametry:

  • mlfFile: plik w stylu mlf HTK zawierający etykiety dla wszystkich wypowiedzi określonych w scp pliku.

  • labelDim: całkowita kardynalność zestawu etykiet.

  • labelMappingFile: ścieżka do pliku, który zawiera listę wszystkich etykiet widocznych w mlf pliku, po jednym na wiersz.

Należy pamiętać, że można określić wiele danych wejściowych i wyjściowych przy użyciu dodatkowych bloków czytnika dla funkcji odczytywanych z plików wymienionych w scp pliku lub etykietach odczytanych mlf z pliku. Na przykład w scenariuszu uczenia wielodaniowego, w którym sieć przewidziała zarówno tożsamość osoby mówiącej, jak i etykietę senone, użytkownik określi dodatkowy blok zawierający mlf plik zawierający etykiety odpowiadające tożsamości osoby mówiącej. Podobnie w przypadku sieci z wieloma danymi wejściowymi, np. funkcjami MFCC i PLP, zostanie użyty dodatkowy blok funkcji.

W przypadku cyklicznych struktur, takich jak RNN lub LSTM, istnieją dodatkowe opcje konfiguracji w HTKMLFReader

  • frameMode: true lub false, czy czytelnik powinien losować dane na poziomie ramki, czy na poziomie wypowiedzi. Ustawienie wartości frameModetrue jest ustawieniem domyślnym i jest odpowiednie dla sieci szkoleniowych bez żadnych połączeń czasowych. W przypadku sieci przeznaczonych do uczenia się informacji sekwencyjnych, np. sieci RNN, należy ustawić wartość false, co oznacza, że wypowiedzi są losowe, frameMode ale właściwa sekwencja jest utrzymywana w wypowiedzi. Należy pamiętać, że ta metoda działa tylko z blockRandomize metodą read.

  • nbruttsineachrecurrentiter: określa liczbę wypowiedzi, które mają być przetwarzane razem w celu wydajnego trenowania sieci za pomocą cyklicznych struktur. Wartość domyślna to 1, ale każda wartość poniżej 20 do 30 doprowadzi do znacznego obniżenia wydajności z procesorami GPU.

  • truncated: true lub false. Umożliwia to obcięcie narzędzia BPTT.

Należy pamiętać, że istnieją niewielkie różnice między standardem scp a mlf plikami używanymi w HTK i używanymi w CNTK.

W szczególności mlf plik musi zawierać rzeczywiste symbole używane do klasyfikacji. W przypadku ciągłego rozpoznawania mowy zazwyczaj oznacza to etykiety odpowiadające senones (physicalHMMstates). Jednak usługa HVite zwykle generuje podczas wymuszonego mlf wyrównania, które zawiera tylko logiczne nazwy stanów HMM. W związku z tym, aby można było go mlf użyć w CNTK, należy przetworzyć po przetworzeniu w mlf celu zastąpienia nazw stanów logicznych odpowiednimi etykietami senone lub HVite należy zmodyfikować tak, aby bezpośrednio zapisywały etykiety senone.

scp Pliki przetwarzane przez HTKMLFReader mogą być jedną z dwóch odmian: standardowy format, w którym każdy wiersz odpowiada fizycznemu plikowi funkcji lub formatowi aliasu, gdzie każdy wiersz zawiera nazwę logiczną i odwołuje się do segmentu prawdopodobnie większego pliku fizycznego zdefiniowanego przez ramki początkowe i końcowe. Nazwa logiczna służy do identyfikowania odpowiednich etykiet w mlf pliku. Nawet jeśli pliki są przechowywane indywidualnie, jak w pierwszym przypadku, aliasowany format musi być zawsze używany z blockRandomize metodą read, ponieważ używa informacji o ramkach początkowych i końcowych w pliku w scp celu określenia długości wypowiedzi bez konieczności otwierania samych plików. W takim przypadku ramka początkowa powinna wynosić 0, a ramka końcowa powinna być równa długości wypowiedzi minus 1. Ponadto w przypadku wielu danych wejściowych i/lub wyjściowych należy również używać formatu aliasu, aby wszystkie scp pliki i mlf pliki miały wspólne nazwy logiczne. rollingWindow Jeśli metoda read jest używana zamiast , informacje o ramce początkowej blockRandomizei końcowej mogą zostać pominięte.

Poniżej przedstawiono przykładowe scp fragmenty kodu i mlf pliki dla korpusu TIMIT odpowiednie dla sieci z 2 wejściami funkcji (w tym przypadku funkcjami MFCC i PLP) oraz 1 danymi wyjściowymi odpowiadającymi stanom fonemu.

Plik scp zawiera listę wszystkich plików do przetworzenia przy użyciu następującej składni:

id=pathname

CNTK zastrzeżone rozszerzenie tego formatu (który nie znajduje się w oryginalnym zestawie HTK) jest to, że CNTK umożliwia wygodniejsze składnię nazwy ścieżki względnej, gdy scp plik znajduje się obok funkcji:

id=.../filename

gdzie ... odwołuje się do katalogu scp pliku.

Plik scp funkcji MFCC zawiera takie wpisy.

train-dr1-fcjf0-si1027.mfc=//hostname/data/TIMIT/mfc/train/dr1/fcjf0/train-dr1-fcjf0-si1027.mfc[0,306]

train-dr1-fcjf0-si1657.mfc=//hostname/data/TIMIT/mfc/train/dr1/fcjf0/train-dr1-fcjf0-si1657.mfc[0,281]

train-dr1-fcjf0-si648.mfc=//hostname/data/TIMIT/mfc/train/dr1/fcjf0/train-dr1-fcjf0-si648.mfc[0,359]

Plik scp funkcji PLP jest podobny, ale wskazuje na różne pliki fizyczne. Pamiętaj, że nazwa katalogu głównego logicznego w obu scp plikach jest taka sama.

train-dr1-fcjf0-si1027.plp=//hostname/data/TIMIT/plp/train/dr1/fcjf0/train-dr1-fcjf0-si1027. plp[0,306]

train-dr1-fcjf0-si1657.plp=//hostname/data/TIMIT/plp/train/dr1/fcjf0/train-dr1-fcjf0-si1657. plp[0,281]

train-dr1-fcjf0-si648.plp=//hostname/data/TIMIT/plp/train/dr1/fcjf0/train-dr1-fcjf0-si648.plp [0,359]

Plik mlf wyświetla listę etykiet, używając następującej składni:

#!MLF!#
"id"
labelBegin1 labelEnd1 label1
labelBegin2 labelEnd2 label1

...

.
"id"
labelBegin1 labelEnd1 label1
labelBegin2 labelEnd2 label1

...

.

...

W tym miejscu mamy sekcję zakończoną kropką . (kropką) dla każdego pliku wejściowego i jeden wiersz na token w każdej sekcji. Czasy etykiet są podane w bazie czasowej 10e-7ramek mowy, a ramki mowy są zwykle 10e-2, więc 5 zer jest wymaganych do dołączania do każdego indeksu czasu.

Należy zauważyć, że CNTK odczytuje tylko pierwsze trzy kolumny* w sekcji mlp pliku i ignoruje resztę. W naszym przykładowym mlf pliku współudzieli również nazwę logiczną z plikami ""scp". Oto fragment kodu:

#!MLF!#
"train-dr1-fcjf0-si1027.rec"
0 200000 h#_s2 -136.655975 h# -589.680481 h#
200000 400000 h#_s3 -145.780716
400000 800000 h#_s4 -307.243774
800000 1200000 q_s2 -349.529327 q -897.429504 q
1200000 1500000 q_s3 -280.568817
1500000 1800000 q_s4 -267.331390
1800000 1900000 iy_s2 -76.825096 iy -673.892883 iy
1900000 2400000 iy_s3 -305.832458
2400000 2800000 iy_s4 -291.235352

Teraz opiszemy pliki archiwum , które są czasami nazywane chunk również plikami. CNTK używa pojęcia fragmentu dla wszystkich jego czytelników i oznacza to absolutnie inną rzecz, więc aby uniknąć pomyłek, nie używamy terminu fragment w odniesieniu do plików opisanych poniżej, ale raczej nazywają je Archiwami.

Pliki archiwum to w zasadzie macierze float32główne kolumny z nagłówkiem 12-bajtowym zawierającym rozmiar próbki i liczbę próbek. Ogólnie rzecz biorąc, są one łatwiejsze do użycia, zwłaszcza jako początek. Oczekiwany nagłówek pliku jest definiowany za pośrednictwem poniższych struct elementów:

struct fileheader
{
    int nsamples;
    int sampperiod;
    short sampsize;
    short sampkind;
}

gdzie:

  • sampsize to rozmiar wektora w bajtach (=4 * feature dimension);
  • sampkind jest identyfikatorem liczbowym typu funkcji (MFCC, PLP itp.). CNTK to ignoruje. Jeśli pliki nie są tworzone przez element HTK, możesz po prostu ustawić tę wartość na 9 (UŻYTKOWNIK). And
  • sampperiodpowinna być 100000 (CNTK przeważnie ignoruje tę wartość, z wyjątkiem komunikatów o błędach).

Na koniec należy pamiętać, że w większości aplikacji rozpoznawania mowy funkcje o ciągłej wartości są używane jako dane wejściowe, podczas gdy dyskretne etykiety podzielone na kategorie są używane jako dane wyjściowe. Jednak HTKMLFReader po prostu kojarzy dane z nazwami węzłów i jest niezależne od sposobu użycia tych danych. Na przykład odpowiedni mlf plik etykiet tożsamości osoby mówiącej może służyć do generowania jednorazowego wektora funkcji tożsamości osoby mówiącej jako danych wejściowych w sieci.