BrainScript HTKMLF Reader
Waarschuwing
HTKMLFReader is verouderd en wordt vervangen door HTK MLF en Feature deserializers, cf. Understanding and Extending Readers. Gebruik deze voor uw netwerken.
HTKMLFReader is een gegevenslezer die bestanden leest die meestal zijn gekoppeld aan spraakherkenningstaken en met name met de htk-suite (Hidden Markov Model Toolkit). De lezer kan twee typen bestanden invoeren, een lijst met functiebestanden die bekend zijn in HTK-parlance als een scp
bestand ('script'-bestand), een labelbestand dat bekend staat als mlf
bestand ('modellabelbestand') en een archiefbestand.
HTKMLFReader is afhankelijk van HTK-gedefinieerde indelingen van gegevenssets, dus we raden u aan vertrouwd te raken met de basisbeginselen van HTK, bijvoorbeeld HTK Book.
Omdat CNTK kan worden gebruikt om netwerken te bouwen met willekeurige topologie, inclusief netwerken met meerdere invoer en uitvoer, kan de HTKMLFReader een of meer scp
MLF
bestanden verwerken. Een typisch voorbeeld van gebruik voor de HTKMLFReader is als volgt:
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"
]
]
De HTKMLFReader heeft de volgende configuratieparameters:
readMethod
: de methode die wordt gebruikt om de onderdelenbestanden te lezen in het geheugen voor verwerking tijdens de netwerktraining. Als ureadMethod
dit insteltblockRandomize
, worden de gegevens verdeeld in grote blokken en wordt vervolgens de volgorde van de blokken gerandomaliseerd en vervolgens de volgorde van de gegevens in het blok. De gegevens in elk blok worden rechtstreeks uit de functiebestanden gelezen en vrijgegeven vanuit ram-geheugen wanneer deze niet meer worden gebruikt. Voor deblockRandomize
optie is een archiefbestand vereist, zoals hieronder wordt beschreven. Zoals hieronder wordt beschreven, worden bij gebruik in combinatie metframeMode = "false"
deblockRandomize
leesmethode ook willekeurige uitingen, maar niet frames gerandomaliseerd. Dit is geschikt voor gebruik met terugkerende architecturen wanneer het behoud van de sequentiële aard van de trainingsvoorbeelden gewenst is. Een alternatief isrollingWindow
, dat alle functiebestanden leest en opslaat op schijf in één groot tijdelijk binair bestand. De gegevens worden vervolgens gerandomiseerd door een groot rolling venster uit te voeren over de gegevens in dit bestand en de gegevens in het venster willekeurig te maken. Deze methode mag alleen worden gebruikt wanneer een archiefbestand niet beschikbaar is en alleen werkt in de framemodus. De standaardmethode isblockRandomize
.pageFilePath
: geef op waar het tijdelijke paginabestand van de functies moet worden opgeslagen. Standaard wordt het door het systeem geleverde temp-bestand gebruikt.randomize
: Hiermee geeft u de grootte van willekeurige vensters op. CNTK gebruikt een doorlopend venster van deze grootte over de gegevens waaruit u een steekproef wilt nemen. Alleen de steekproeven in dit rolling venster worden geladen vanaf de schijf en worden alleen in het RAM-geheugen bewaard zolang dit nodig is. De aanbevolen instelling voor spraak corpora in productiegrootte is 48 uur, d.w. opgeven17280000
. Derandomize
parameter begrijpt ook twee speciale waarden:auto
ofnone
.none
schakelt randomisatie helemaal uit, handig voor evaluatie of het schrijven van uitvoergegevens.auto
zal het volledige corpus in RAM lezen, wat doorgaans niet haalbaar of wenselijk is voor gegevenssets van enkele duizenden uren spraak.minibatchMode
:partial
offull
, deze optie bepaalt hoe de laatste minibatch moet worden verwerkt als er onvoldoende frames zijn om een volledige minibatch van de aangevraagde grootte te vormen. De standaardwaarde ispartial
, die de resterende frames gebruikt in een kleinere laatste minibatch van het trainingstijdperk. Defull
optie verwerkt alleen volledige minibatches.
In het bovenstaande voorbeeld worden twee gegevensbronnen verwerkt door de lezer, functies, in de vorm van een lijst met HTK-functiebestanden en labels, die zich in de vorm van een HTK MLF-bestand bevinden. Zowel functies als labels komen overeen met knooppunten in het rekennetwerk, in dit geval respectievelijk de invoer- en uitvoerknooppunten. Houd er rekening mee dat features
en labels
de standaardnamen zijn die worden gebruikt door simpleNetworkBuilder, maar als het netwerk is ontworpen met behulp van de Network Description Language (NDL), kunnen alle namen worden gebruikt, zolang ze elk een corresponderend knooppunt in het netwerk hebben.
Als u functies met continue waarden wilt opgeven, zoals de coëfficiënten van MFCC of log mel filterbank, moeten de volgende parameters worden opgenomen in het configuratieblok:
scpFile
: een lijst met bestanden die moeten worden verwerkt. De bestanden moeten compatibele HTK-bestanden zijn en kunnen worden opgegeven in standaardindeling of archiefindeling. De details van het gebruik van een archief worden hieronder beschreven.dim
: een geheel getal dat de dimensie van de volledige functievector aangeeft met het gewenste contextvenster. Als u bijvoorbeeld 72 dimensionale kenmerken (24-dimensionale filterbankfuncties plus delta- en delta-deltacoëfficiënten) had en het netwerk is ontworpen om een contextvenster van 11 frames te verwerken, moet de opgegeven dimensie 792 zijn. Houd er rekening mee dat alleen symmetrische contextvensters worden ondersteund.
Als u de bijbehorende labels wilt opgeven, bijvoorbeeld foneme- of senonelabels, moet er een configuratieblok worden gebruikt dat de volgende parameters opgeeft:
mlfFile
: een HTK-bestandmlf
met de labels voor alle uitingen die in hetscp
bestand zijn opgegeven.labelDim
: de totale kardinaliteit van de labelset.labelMappingFile
: het pad naar een bestand met alle labels die in hetmlf
bestand worden weergegeven, één per regel.
Houd er rekening mee dat meerdere invoer en uitvoer kunnen worden opgegeven met behulp van extra lezerblokken voor functies die worden gelezen uit bestanden die in een scp
bestand worden gelezen of labels die uit een mlf
bestand worden gelezen. In een leerscenario met meerdere taken, waarbij het netwerk bijvoorbeeld zowel de sprekeridentiteit als het senone-label voorspelde, zou de gebruiker een extra blok opgeven dat een mlf
bestand bevat dat labels bevat die overeenkomen met de sprekeridentiteit. Op dezelfde manier zou voor een netwerk met meerdere invoerwaarden, bijvoorbeeld zowel MFCC- als PLP-functies, een extra functieblok worden gebruikt.
Voor terugkerende structuren, zoals een RNN of een LSTM, zijn er aanvullende configuratieopties in de HTKMLFReader
frameMode
:true
offalse
, of de lezer de gegevens willekeurig moet maken op frameniveau of het uitingsniveau.true
De instellingframeMode
is de standaardinstelling en is geschikt voor trainingsnetwerken zonder tijdelijke verbindingen. Voor netwerken die zijn ontworpen om sequentiële informatie te leren, bijvoorbeeld RNN,frameMode
moet worden ingesteldfalse
op , wat betekent dat utterances willekeurig zijn, maar dat de juiste volgorde wordt onderhouden binnen een utterance. Houd er rekening mee dat dit alleen werkt met deblockRandomize
leesmethode.nbruttsineachrecurrentiter
: geeft het aantal uitingen op dat samen moet worden verwerkt voor een efficiënte training van netwerken met terugkerende structuren. De standaardwaarde is1
, maar elke waarde lager dan 20 tot 30 leidt tot aanzienlijke efficiëntieverminderingen met GPU's.truncated
:true
offalse
. Hierdoor wordt afgekapte BPTT ingeschakeld.
Het is belangrijk te weten dat er enkele kleine verschillen zijn tussen de standaard scp
en mlf
bestanden die worden gebruikt in HTK en de bestanden die worden gebruikt in CNTK.
Het bestand moet met name mlf
de werkelijke symbolen bevatten die worden gebruikt voor classificatie. Voor continue spraakherkenning betekent dit meestal labels die overeenkomen met de senones (physicalHMMstates). HVite genereert echter doorgaans een mlf
tijdens geforceerde uitlijning die alleen de logische HMM-statusnamen bevat. Als u dit mlf
dus in CNTK wilt gebruiken, moet de mlf
logische statusnamen worden vervangen door de bijbehorende senone labels, of moet HVite worden gewijzigd, zodat de senone-labels rechtstreeks worden weggeschreven.
De scp
bestanden die door de HTKMLFReader worden verwerkt, kunnen een van de twee soorten zijn: ofwel de standaardindeling, waarbij elke regel overeenkomt met een fysiek functiebestand of de aliasindeling, waarbij elke regel een logische naam bevat en verwijst naar een segment van een mogelijk groter fysiek bestand, gedefinieerd door begin- en eindframes. De logische naam wordt gebruikt om de bijbehorende labels in het mlf
bestand te identificeren. Zelfs als de bestanden afzonderlijk worden opgeslagen, zoals in het eerste geval, moet de aliasindeling altijd worden gebruikt met de blockRandomize
leesmethode, omdat de informatie over de begin- en eindframes in het scp
bestand wordt gebruikt om de lengte van de uiting te bepalen zonder de bestanden zelf te hoeven openen. In dit geval moet het beginframe 0 zijn en moet het eindframe gelijk zijn aan de lengte van de uiting min 1. Bovendien moet voor meerdere invoer- en/of uitvoerwaarden ook de aliasindeling worden gebruikt, zodat alle scp
bestanden en mlf
bestanden hun logische namen gemeen hebben. Als de rollingWindow
leesmethode wordt gebruikt in plaats van blockRandomize
, kan de informatie over het begin- en eindframe worden weggelaten.
Hier volgen voorbeeldfragmenten van scp
en mlf
bestanden voor het TIMIT-corpus voor geschikt voor een netwerk met 2 functie-invoer (in dit geval MFCC- en PLP-functies) en 1 uitvoer die overeenkomt met telefoonstatussen.
Het scp
bestand bevat alle bestanden die u wilt verwerken, met behulp van deze syntaxis:
id=pathname
Een CNTK eigen extensie van deze indeling (die niet in de oorspronkelijke HTK is gevonden) is dat CNTK een handigere relatieve padnaamsyntaxis toestaat wanneer het scp
bestand zich naast de functies bevindt:
id=.../filename
waarbij ...
wordt verwezen naar de map van het scp
bestand.
Het scp
bestand voor de MFCC-functies bevat vermeldingen zoals deze.
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]
Het scp
bestand voor de PLP-functies is vergelijkbaar, maar verwijst naar verschillende fysieke bestanden. Houd er rekening mee dat de logische hoofdnaam in beide scp
bestanden hetzelfde is.
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]
Een mlf
bestand bevat de labels met behulp van deze syntaxis:
#!MLF!#
"id"
labelBegin1 labelEnd1 label1
labelBegin2 labelEnd2 label1
...
.
"id"
labelBegin1 labelEnd1 label1
labelBegin2 labelEnd2 label1
...
.
...
Hier is een sectie beëindigd met .
(punt) per invoerbestand en één regel per token in elke sectie. De labeltijden worden gegeven in een tijdbasis van 10e-7
en spraakframes zijn normaal 10e-2
, dus er zijn vijf nullen nodig om aan elke index toe te voegen.
Het is belangrijk op te merken dat CNTK slechts de eerste drie kolommen* leest in een sectie van een mlp
bestand en de rest negeert. In ons voorbeeldbestand mlf
wordt ook de logische naam gedeeld met beide ''scp'-bestanden. Dit is het codefragment:
#!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
Nu beschrijven we Archiefbestanden , die soms ook wel bestanden worden genoemd chunk
. CNTK maakt gebruik van een concept van chunk voor alle lezers, en het betekent een absoluut ander ding, dus om de verwarring te voorkomen dat we de term chunk gebruiken ten opzichte van de bestanden die hieronder worden beschreven, maar in plaats daarvan archieven noemen.
Archiefbestanden zijn in feite kolom-primaire matrices van float32
, met een koptekst van 12 bytes die de steekproefgrootte en het aantal steekproeven bevat. Over het algemeen zijn ze gemakkelijker te gebruiken, vooral als begin. De verwachte header van het bestand wordt gedefinieerd via de struct
onderstaande:
struct fileheader
{
int nsamples;
int sampperiod;
short sampsize;
short sampkind;
}
Hierbij
sampsize
is de grootte van een vector in bytes (=4 * feature dimension
);sampkind
is een numerieke id van het functietype (MFCC, PLP, enzovoort). CNTK negeert dit. Als uw bestanden niet door HTK worden gemaakt, kunt u dit gewoon instellen op 9 (USER). Andsampperiod
moet zijn100000
(CNTK negeert deze waarde meestal, met uitzondering van foutberichten).
Ten slotte is het belangrijk te weten dat in de meeste spraakherkenningstoepassingen de functies met continue waarden worden gebruikt als invoer, terwijl discrete categorische labels worden gebruikt als uitvoer. De HTKMLFReader koppelt echter alleen de gegevens aan de knooppuntnamen en is agnostisch over hoe deze gegevens worden gebruikt. Een geschikt mlf
bestand met sprekeridentiteitslabels kan bijvoorbeeld worden gebruikt om een one-hot vector van sprekeridentiteitsfuncties te genereren als invoer voor het netwerk.