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 nareadMethod
wartość spowodujeblockRandomize
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. OpcjablockRandomize
wymaga pliku archiwum opisanego poniżej. Ponadto, jak opisano poniżej, w przypadku użycia w połączeniublockRandomize
zframeMode = "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ą jestblockRandomize
.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
. Parametrrandomize
rozumie również dwie specjalne wartości:auto
lubnone
.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
lubfull
, 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 topartial
, która będzie używać pozostałych ramek w mniejszej końcowej minibatch epoki trenowania. Opcjafull
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 stylumlf
HTK zawierający etykiety dla wszystkich wypowiedzi określonych wscp
pliku.labelDim
: całkowita kardynalność zestawu etykiet.labelMappingFile
: ścieżka do pliku, który zawiera listę wszystkich etykiet widocznych wmlf
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
lubfalse
, czy czytelnik powinien losować dane na poziomie ramki, czy na poziomie wypowiedzi. Ustawienie wartościframeMode
true
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 zblockRandomize
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 to1
, ale każda wartość poniżej 20 do 30 doprowadzi do znacznego obniżenia wydajności z procesorami GPU.truncated
:true
lubfalse
. 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 blockRandomize
i 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-7
ramek 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 float32
głó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). Andsampperiod
powinna 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.