Dela via


BrainScript HTKMLF-läsare

Varning

HTKMLFReader är föråldrad och ersätts av HTK MLF och Feature deserializers, cf. Understanding and Extending Readers. Använd dessa för dina nätverk.

HTKMLFReader är en dataläsare som läser filer som vanligtvis är associerade med taligenkänningsuppgifter, och särskilt med verktygspaketet Hidden Markov Model Toolkit (HTK). Läsaren kan ta som indata två typer av filer, en lista över funktionsfiler som kallas för HTK-parlance som en scp fil ("skript"-fil), en etikettfil som mlf kallas fil ("modelletikettfil") och en arkivfil.

HTKMLFReader förlitar sig på HTK-definierade format för datauppsättningar, så vi rekommenderar att du bekantar dig med grunderna i HTK med hjälp av t.ex. HTK Book.

Eftersom CNTK kan användas för att skapa nätverk med godtycklig topologi, inklusive nätverk med flera indata och utdata, kan HTKMLFReader bearbeta en eller flera scp filer och MLF filer. Ett typiskt exempel på användning för HTKMLFReader är följande:

    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"
        ]
    ]

HTKMLFReader har följande konfigurationsparametrar:

  • readMethod: den metod som används för att läsa funktionsfilerna i minnet för bearbetning under nätverksträningen. Om du anger readMethod till blockRandomize delas data in i stora block och sedan slumpmässigt ordningen på blocken och sedan ordningen på data i blocket. Data i varje block läss direkt från funktionsfilerna och släpps från RAM-minnet när de inte längre används. Alternativet blockRandomize kräver en arkivfil som beskrivs nedan. Som beskrivs nedan, när den används tillsammans med frameMode = "false"blockRandomize läsmetoden slumpmässigt över yttranden, men inte ramar. Detta är lämpligt för användning med återkommande arkitekturer när du vill bevara träningsexemplens sekventiella karaktär. Ett alternativ är rollingWindow , som läser i alla funktionsfiler och lagrar dem på disk i en stor tillfällig binär fil. Data randomiseras sedan genom att köra ett stort rullande fönster över data i den här filen och randomisera data i fönstret. Den här metoden bör endast användas när en arkivfil inte är tillgänglig och endast fungerar i ramläge. Standardmetoden är blockRandomize.

  • pageFilePath: ange var den tillfälliga sidfilen för funktionerna ska lagras. Som standard används den temporära filen som tillhandahålls av systemet.

  • randomize: Detta anger storleken för randomiseringsfönstret. CNTK använder ett rullande fönster med den här storleken över de data som du vill prova från. Endast exemplen i det här rullande fönstret läses in från disken och lagras i RAM-minnet så länge som det behövs. Den rekommenderade inställningen för tal corpora i produktionsstorlek är 48 timmar, d.v.s. ange 17280000. Parametern randomize förstår också två specialvärden: auto eller none. none inaktiverar randomisering helt och hållet, användbart för utvärdering eller skrivning av utdata. auto läser in hela korpusen i RAM, vilket vanligtvis inte är möjligt eller önskvärt för datauppsättningar i produktionsstorlek med flera tusentals timmars tal.

  • minibatchMode: partial eller fullbestämmer det här alternativet hur den sista minibatchen ska hanteras om det inte finns tillräckligt med ramar för att skapa en fullständig minibatch av den begärda storleken. Standardvärdet är partial, som använder de återstående bildrutorna i en mindre sista minibatch av träningsepoken. Alternativet full bearbetar endast fullständiga minibatches.

Exemplet ovan har två datakällor som bearbetas av läsaren, funktioner, i form av en lista över HTK-funktionsfiler och etiketter, som är i form av en HTK MLF-fil. Både funktioner och etiketter motsvarar noder i beräkningsnätverket, i det här fallet indata- respektive utdatanoderna. Observera att features och labels är standardnamnen som används av SimpleNetworkBuilder, men om nätverket är utformat med hjälp av NDL (Network Description Language) kan alla namn användas, så länge de har en motsvarande nod i nätverket.

Om du vill ange funktioner för kontinuerliga värden, t.ex. MFCC: s eller log mel filterbankskoefficienter, ska följande parametrar inkluderas i ett konfigurationsblock:

  • scpFile: en lista över filer som ska bearbetas. Filerna ska vara HTK-kompatibla filer och kan anges i standardformat eller arkivformat. Informationen om hur du använder ett arkiv beskrivs nedan.

  • dim: ett heltal som anger den fullständiga funktionsvektordimensionen med önskat kontextfönster. Om du till exempel har 72-dimensionella funktioner (24-dimensionella filterbanksfunktioner plus delta- och deltadelkoefficienter) och nätverket är utformat för att bearbeta ett kontextfönster på 11 bildrutor, ska den angivna dimensionen vara 792. Observera att endast fönster med symmetrisk kontext stöds.

Om du vill ange motsvarande etiketter, t.ex. phoneme- eller senonetiketter, ska ett konfigurationsblock användas som anger följande parametrar:

  • mlfFile: en HTK-fil mlf som innehåller etiketterna för alla yttranden som anges i scp filen.

  • labelDim: etikettuppsättningens totala kardinalitet.

  • labelMappingFile: sökvägen till en fil som visar alla etiketter som visas i mlf filen, en per rad.

Observera att flera indata och utdata kan anges med hjälp av ytterligare läsarblock för antingen funktioner som lästs från filer som anges i en scp fil eller etiketter som lästs från en mlf fil. I ett multiaktivitetsinlärningsscenario där nätverket förutsäger både talaridentitet och senonetikett skulle användaren till exempel ange ytterligare ett block som innehåller en mlf fil som innehåller etiketter som motsvarar talaridentiteten. På samma sätt skulle ytterligare ett funktionsblock användas för ett nätverk med flera indata, t.ex. både MFCC- och PLP-funktioner.

För återkommande strukturer, till exempel ett RNN eller en LSTM, finns det ytterligare konfigurationsalternativ i HTKMLFReader

  • frameMode: true eller false, om läsaren ska randomisera data på ramnivå eller talindatanivå. Inställningen frameMode till true är standard och är lämplig för träningsnätverk utan tidsmässiga anslutningar. För nätverk som är utformade för att lära sig sekventiell information, t.ex. RNN, frameMode ska anges till false, vilket innebär att yttranden är slumpmässiga men korrekt sekvens upprätthålls inom ett yttrande. Observera att detta endast fungerar med blockRandomize läsmetoden.

  • nbruttsineachrecurrentiter: anger antalet yttranden som ska bearbetas tillsammans för effektiv träning av nätverk med återkommande strukturer. Standardvärdet är 1, men ett värde under 20 till 30 leder till betydande effektivitetsförsämringar med GPU:er.

  • truncated: true eller false. Detta möjliggör trunkerad BPTT.

Det är viktigt att notera att det finns några små skillnader mellan standarden scp och mlf filerna som används i HTK och de som används i CNTK.

Framför allt mlf måste filen innehålla de faktiska symboler som används för klassificering. För kontinuerlig taligenkänning innebär detta vanligtvis etiketter som motsvarar senonerna (physicalHMMstates). HVite genererar dock vanligtvis en mlf under framtvingad justering som endast innehåller de logiska HMM-tillståndsnamnen. För att kunna använda detta mlf i CNTK måste antingen mlf postbearbetas för att ersätta de logiska tillståndsnamnen med motsvarande senonetiketter, eller så måste HVite ändras så att den skriver senonetiketterna direkt.

Filerna scp som bearbetas av HTKMLFReader kan vara en av två sorter: antingen standardformatet, där varje rad motsvarar en fysisk funktionsfil eller det aliasformat där varje rad innehåller ett logiskt namn och refererar till ett segment av en eventuellt större fysisk fil, definierad av start- och slutramar. Det logiska namnet används för att identifiera motsvarande etiketter i mlf filen. Även om filerna lagras individuellt, som i det första fallet, måste det aliaserade formatet alltid användas med blockRandomize läsmetoden, eftersom det använder informationen om start- och slutramarna i scp filen för att fastställa yttrandelängderna utan att behöva öppna själva filerna. I det här fallet ska startramen vara 0 och slutramen ska vara lika med längden på yttrandet minus 1. För flera indata och/eller utdata bör dessutom det aliaserade formatet också användas så att alla scp filer och mlf filer har gemensamma logiska namn. rollingWindow Om läsmetoden används i stället för blockRandomizekan informationen om start- och slutram utelämnas.

Här är exempelfragment av scp filer och mlf för TIMIT-corpus för ett nätverk med 2 funktionsindata (i det här fallet MFCC- och PLP-funktioner) och 1 utdata som motsvarar fonetiktillstånd.

Filen scp visar alla filer som du ska bearbeta med hjälp av den här syntaxen:

id=pathname

Ett CNTK-patentskyddad filnamnstillägg för det här formatet (som inte finns i den ursprungliga HTK:en) är att CNTK tillåter en bekvämare relativ sökvägsnamnssyntax när scp filen finns bredvid funktionerna:

id=.../filename

där ... refererar till filens scp katalog.

Filen scp för MFCC-funktionerna innehåller poster som dessa.

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]

Filen scp för PLP-funktionerna liknar den men pekar på olika fysiska filer. Observera att det logiska rotnamnet i båda scp filerna är detsamma.

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]

En mlf fil listar etiketterna med hjälp av den här syntaxen:

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

...

.
"id"
labelBegin1 labelEnd1 label1
labelBegin2 labelEnd2 label1

...

.

...

Här har vi ett avsnitt som avslutas med . (punkt) per indatafil och en rad per token i varje avsnitt. Etiketttiderna anges i en tidsbas av 10e-7, och talramar är normalt 10e-2, så 5 nolla krävs för att lägga till varje tidsindex.

Observera att CNTK endast läser de tre första kolumnerna* i ett avsnitt i en mlp fil och ignorerar resten. I vår exempelfil mlf delar även det logiska namnet med båda '''scp''-filerna. Här är kodfragmentet:

#!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 ska vi beskriva Arkivfiler , som ibland även kallas chunk filer. CNTK använder ett segmentbegrepp för alla sina läsare, och det betyder en helt annan sak, så för att undvika förvirringen använder vi inte termen segment i förhållande till de filer som beskrivs nedan, utan snarare kallar dem Arkiv.

Arkivfiler är i princip kolumnmajormatriser för float32, med en rubrik på 12 byte som innehåller urvalsstorleken och antalet exempel. I allmänhet är de enklare att använda, särskilt som en början. Den förväntade rubriken för filen definieras via struct nedanstående:

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

där:

  • sampsize är storleken på en vektor i byte (=4 * feature dimension);
  • sampkind är en numerisk identifierare för funktionstypen (MFCC, PLP osv.). CNTK ignorerar detta. Om dina filer inte skapas av HTK kan du bara ange detta till 9 (USER). Och
  • sampperiodbör vara 100000 (CNTK ignorerar oftast det här värdet, förutom eventuellt för felmeddelanden).

Slutligen är det viktigt att notera att i de flesta taligenkänningsprogram används de kontinuerliga funktionerna som indata medan diskreta kategorietiketter används som utdata. HTKMLFReader associerar dock bara data med nodnamnen och är oberoende av hur dessa data används. Till exempel kan en lämplig mlf fil med talaridentitetsetiketter användas för att generera en one-hot-vektor med funktioner för talaridentitet som indata till nätverket.