BrainScript en Python: Lezers begrijpen en uitbreiden
Vanaf versie 1.5 stapt CNTK weg van het monolithische lezerontwerp naar een meer samenstelbaar model waarmee u invoergegevens van verschillende indelingen kunt opgeven en opstellen.
Voorheen was elke lezer verantwoordelijk voor verschillende aspecten van het lezen van gegevens, waaronder maar niet beperkt tot:
- Deserialisatie van de gegevens uit externe opslag in in-memory weergave
- Randomisatie van het hele corpus
- Verschillende transformaties van invoerreeksen/voorbeelden (bijvoorbeeld bijsnijden of schalen van afbeeldingen)
- Het maken van minibatches voor verschillende modi (bijvoorbeeld frame, reeks of afgekapte BPTT) met een indeling die kan worden gebruikt door GPU
- Prefetch op het niveau van minibatches en IO-segmenten
In versie 1.5 zijn de belangrijkste onderdelen van de bovenstaande functionaliteit uitgelicht en verplaatst naar de cntk van de kern om te worden gedeeld tussen verschillende lezers. Deze versie introduceert ook twee hoofdabstracties die kunnen worden uitgebreid om nieuwe gegevensindelingen te ondersteunen:
- deserializer - het is verantwoordelijk voor deserialisatie van invoer van externe opslag in in-memory reeksen
- transformeren : hiermee wordt een invoerreeks omgezet in een uitvoerreeks
In de volgende secties bespreken we deze abstracties in meer detail.
Een lezer (minibatchbron) configureren in Python
Deze sectie bevat verschillende voorbeelden van hoe een samengestelde lezer (ook wel MinibatchSource genoemd) kan worden geconfigureerd in Python.
Het volgende voorbeeld is aangepast van AlexNet_ImageNet_Distributed.py. Het toont het Python-equivalent van de AlexNet-lezer uit de sectie Transforms .
import cntk.io
mean_file = ...
map_file = ...
# model dimensions
image_height = 227
image_width = 227
num_channels = 3 # RGB
num_classes = 1000
transforms = [
ImageDeserializer.crop(crop_type='randomside',
side_ratio=0.88671875,
jitter_type='uniratio'),
ImageDeserializer.scale(width=image_width,
height=image_height,
channels=num_channels,
interpolations='linear'),
ImageDeserializer.mean(mean_file)
]
reader = MinibatchSource(
ImageDeserializer(map_file, StreamDefs(
# first column in map file is referred to as 'image'
features = StreamDef(field='image', transforms=transforms),
# and second as 'label'
labels = StreamDef(field='label', shape=num_classes))))
In het volgende voorbeeld (aangepast van A2_RunCntk_py3.py) ziet u hoe verschillende deserializers samen kunnen worden gecombineerd.
n_rois = 100
n_classes = 17
rois_dim = 4 * n_rois
label_dim = n_classes * n_rois
map_file = ...
roi_file = ...
label_file = ...
# read images
scale = ImageDeserializer.scale(width=1000,
height=1000,
channels=3,
scale_mode="pad",
pad_value=114,
interpolations='linear')
image_source = ImageDeserializer(map_file)
image_source.ignore_labels()
image_source.map_features('features', [scale])
# read rois and labels
roi_source = CTFDeserializer(roi_file)
roi_source.map_input('rois', dim=rois_dim, format="dense")
label_source = CTFDeserializer(label_file)
label_source.map_input('roiLabels', dim=label_dim, format="dense")
# define a composite reader
reader = MinibatchSource([image_source, roi_source, label_source])
...
# define mapping from reader streams to network inputs
input_map = {
image_input: reader.streams.features,
roi_input: reader.streams.rois,
label_input: reader.streams.roiLabels
}
BrainScript
Deserializers
Laten we eens kijken naar het volgende configuratiefragment voor de HTKMLFReader van de end-to-end LSTM/FullUtterance-test (hier volledige configuratie):
...
# Old reader config. For illustration only.
reader = [
readerType = "HTKMLFReader"
readMethod = "blockRandomize"
nbruttsineachrecurrentiter = 32
randomize = "auto"
verbosity = 0
features = [
dim = 363
type = "real"
scpFile = "$DataDir$/glob_0000.scp"
]
labels = [
mlfFile = "$DataDir$/glob_0000.mlf"
labelMappingFile = "$DataDir$/state.list"
labelDim = 132
labelType = "category"
]
]
Dit fragment van de configuratie declareert een lezer die twee gegevensstromen met namen "features"
en "labels"
. Het neemt als invoer twee typen bestanden:
- een lijst met functiebestanden die bekend zijn in HTK-parlance als een
scp
bestand ('script'-bestand) - een labelbestand dat bekend staat als
mlf
bestand ('hoofdlabelbestand')
In het bovenstaande configuratiefragment zijn er geen expliciete entiteiten die definiëren hoe scp
of mlf
indelingen gedeserialiseerd worden.
Alles wordt ingekapseld in de HTKMLFReader-configuratie .
Dus als u nog een invoerstroom van verschillende gegevensindeling scp
samen met en mlf
, moet u HTKMLFReader wijzigen en daar ondersteuning toevoegen.
Om de composabiliteit te vergroten en opnieuw te gebruiken, definieert de nieuwe configuratie voor dezelfde invoer expliciet deserializers en de invoerstromen die ze produceren:
reader = [
verbosity = 0
randomize = true
# A list of deserializers the reader uses.
deserializers = (
[
# Type of deserializer, in this case the one that knows
# how to deserialize HTK feature files.
type = "HTKFeatureDeserializer"
# Module (.dll or .so) where this deserializer is implemented
module = "HTKDeserializers"
# Description of input streams the deserializer provides,
# can be one or many, depending on a particular
# deserializer implementation
# For HTKFeatureDeserializer, just one stream can be described.
input = [
# Description of input stream to feed the Input node named "features"
features = [
dim = 363
scpFile = "$DataDir$/glob_0000.scp"
]
]
]:
[
# Type of deserializer, in this case the one
# that knows how to deserialize mlf files.
type = "HTKMLFDeserializer"
module = "HTKDeserializers"
# Description of input streams the deserializer provides,
# For HTKMLFDeserializer, just one stream can be described.
input = [
# Description of input stream to feed the Input node named "labels"
labels = [
dim = 132
mlfFile = "$DataDir$/glob_0000.mlf"
labelMappingFile = "$DataDir$/state.list"
# whether phone boundary information should be encoded
# set to true in CTC-type training
phoneBoundaries=false
]
]
]
)
]
De reeksen die door de mlf
en htk
deserialisaties worden geproduceerd, worden gecombineerd op basis van hun logische sleutel (dit is een tekenreeks die een spraakuiting uniek identificeert en aanwezig is in zowel als scp
mlf
bestanden).
Wanneer u een andere stroom van verschillende indeling nodig hebt, kunt u de bijbehorende deserializer gewoon toevoegen aan de configuratie (het is niet mogelijk met de HTK-functie en HTK MLF deserializers op dit moment om meer dan één invoerstroom beschikbaar te maken).
Notitie
Momenteel worden zowel oude als nieuwe lezerconfiguraties ondersteund. Wanneer de sleutel 'deserializers' wordt gebruikt in de configuratie van de lezer, wordt het type lezer impliciet ingesteld op 'CompositeDataReader'. Om ervoor te zorgen dat de CompositeDataReader-module in Windows kan worden geladen, moet deze Cntk.Composite.dll
zich in dezelfde map bevinden als het uitvoerbare CNTK-bestand. In Linux Cntk.Composite.so
moet zich in de lib
map bevinden die naast de bin
map met het uitvoerbare CNTK-bestand staat.
CnTK ondersteunt momenteel de onderstaande deserializers:
Type deserializer | Module | Description |
---|---|---|
HTKFeatureDeserializer | HTKDeserializers | Deserializer voor HTK-functiebestanden |
HTKMLFDeserializer | HTKDeserializers | Deserializer voor HTK MLF-bestanden |
ImageDeserializer | ImageReader | Deserializer voor afbeeldingen die zijn gecodeerd als gewone bestanden of in zip-archief. |
Base64ImageDeserializer | ImageReader | Deserializer voor afbeeldingen die zijn gecodeerd als base64-tekenreeksen in het toewijzingsbestand. |
CNTKTextFormatDeserializer | CNTKTextFormatReader | Deserializer voor CNTK-tekstbestanden |
CNTKBinaryFormatDeserializer | CNTKBinaryReader | Deserializer voor binaire CNTK-indelingsbestanden |
Raadpleeg de onderstaande tabellen voor de volledige beschrijving van de configuratieparameters.
Transformaties
Een transformatie is een eenvoudige abstractie die een reeks als invoer neemt, enkele transformaties van voorbeelden in de reeks uitvoert en de uitvoerreeks retourneert. Typische voorbeelden van transformaties zijn verschillende transformaties van afbeeldingen, zoals bijsnijden, schalen of transponeren. Transformaties kunnen per invoer worden geconfigureerd.
Laten we eens kijken hoe transformaties kunnen worden toegepast op de invoer (de configuratie wordt genomen uit de test Tests/EndToEndTests/Image/AlexNet ):
deserializers = ([
type = "ImageDeserializer"
module = "ImageReader"
# Map file which maps images to labels
file = "$ConfigDir$/train_map.txt"
# Description of input streams
input = [
# Description of input stream to feed the Input node named "features"
features = [
transforms = (
[
type = "Crop"
# Possible values: Center, RandomSide, RandomArea, Multiview10. Default: Center
cropType = "RandomSide"
# Crop scale side ratio.
sideRatio = 0.875
# Crop scale ratio jitter type
jitterType = "UniRatio"
]:[
type = "Scale"
width = 224
height = 224
channels = 3
# Interpolation to use when scaling image to width x height size.
interpolations = "linear"
]:[
type = "Mean"
# Stores mean values for each pixel in OpenCV matrix XML format.
meanFile = "$ConfigDir$/ImageNet1K_mean.xml"
]:[
# Changes the image layout from HWC to CHW
type = "Transpose"
]
)
]
# Description of input stream to feed the Input node named "labels"
labels = [
labelDim = 1000
]
]
]
])
In deze configuratie worden vier transformaties toegepast op de invoerstroom features
.
Aanvankelijk produceert de afbeeldingsgegevens deserializer reeksen die bestaan uit één afbeelding in de HWC-weergave.
Daarna wordt de geordende lijst met transformaties toegepast op de afbeelding: eerst de transformatie Bijsnijden , gevolgd door Schaal en Gemiddelde.
De laatste transformatie is Transponeren waarmee de afbeeldingsindeling van HWC wordt gewijzigd in CHW.
Momenteel worden de volgende transformaties geïmplementeerd. Zie ImageReader voor een gedetailleerde beschrijving.
Transformatietype | Module |
---|---|
Bijsnijden | ImageReader |
Schalen | ImageReader |
Kleur | ImageReader |
Gemiddeld | ImageReader |
Transponeren | ImageReader |
Beschrijving van configuratie-indeling voor nieuwe lezer
Een sectie voor lezerconfiguratie voor het opstellen van verschillende gegevensdeserialisaties ziet er als volgt uit:
reader = [
randomize = true|false
verbosity = 0|1|2
...
deserializers = (
[<deserializerConfiguration1>]:
[<deserializerConfiguration2>]:
...
[<deserializerConfigurationN>]
)
]
Elke deserializer-configuratie wordt opgegeven als:
[
module = "<readerModuleName>" # Name of the external module (.dll or .so) where this particular deserializer is implemented
type = "<deserializerType>" # The type of the deserializer
# There could be more deserializer-specific options in this section
# Date deserializer input - describes a set of streams this deserializer produces.
# It can be one (as in HTK) or many (as in CNTKTextFormat)
input = [
# Replace 'InputNameN' by the name of the corresponding input node in the network.
InputName1 = [<inputConfiguration>]
InputName2 = [<inputConfiguration>]
...
]
]
Een invoerconfiguratie bevat invoerspecifieke opties en, optioneel, een geordende lijst met transformaties die op de invoer moeten worden toegepast:
[
# Per-input data deserializer-specific options
# Optionally a pipeline of transformations, to be implemented by data deserializer's reader module:
transforms = (
[<transformationConfiguration1>]:
[<transformationConfiguration2>]:
...
[<transformationConfigurationN>]
)
]
Transformatieconfiguratie identificeert het transformatietype en eventuele transformatiespecifieke opties:
[
type = "<transformName>"
# Transform-specific options
]
Configuratieopties
Algemene lezerconfiguratie
Parameter | Beschrijving |
---|---|
verbosity |
Uitgebreidheidsniveau (0 , 1 , 2 ), bepaalt de diagnostische uitvoer van verschillende onderdelen (Randomizer, Deserializer, Bundler, enzovoort) Optioneel, standaard ingesteld op 0 . |
randomize |
Hiermee geeft u op of de invoer moet worden gerandomiseerd ( , true false ). De randomisatiemethode is identiek aan blockRandomize van de HTKMLFReader. Optioneel, standaard ingesteld op true . |
randomizationSeed |
Initialization seed value (incremented every sweep when the input data is re-randomized). Optioneel, standaard ingesteld op 0 . |
randomizationWindow |
Hiermee geeft u de grootte (positief geheel getal) van het randomisatievenster (bijvoorbeeld randomisatiebereik). Deze parameter is van invloed op hoeveel van de gegevensset in het geheugen tegelijk moet worden opgeslagen. Optioneel, wordt standaard ingesteld op de grootte van de hele gegevensset (in voorbeelden of in segmenten, afhankelijk van de sampleBasedRandomizationWindow waarde). Als een van de deserializers echter niet expliciet isCNTKTextFormatDeserializer sampleBasedRandomizationWindow ingesteld op true , randomizationWindow wordt standaard ingesteld 128 op (dat is ongeveer 4 GB schijfruimte van segmenten). Deze parameter wordt genegeerd wanneer randomize dit is false . |
sampleBasedRandomizationWindow |
Als true , de grootte van het randomisatievenster wordt geïnterpreteerd als een bepaald aantal steekproeven en als een aantal segmenten anders. Optioneel, wordt standaard ingesteld true als CNTKTextFormatDeserializer deze niet aanwezig is in de lijst met deserializers en anders false . Op dezelfde manier randomizationWindow wordt deze parameter genegeerd, wanneer randomize dit is false . |
truncationLength |
Hiermee geeft u de afkappingslengte op in steekproeven voor BPTT (positief geheel getal). Alleen vereist als truncated dit is true , anders genegeerd. |
multiThreadedDeserialization |
Hiermee geeft u op of meerdere threads moeten worden gebruikt bij het verzamelen van reeksen voor een minibatch van de deserializers (true , false ). Optioneel. |
frameMode |
Hiermee geeft u op of gegevens moeten worden gerandomiseerd en geretourneerd op frame- of reeksniveau. Wanneer true , worden de invoerreeks gesplitst in frames. Optioneel. Beide frameMode en truncated kunnen niet op hetzelfde moment worden ingesteld true . |
truncated |
Wanneer true , schakelt afgekapte back-doorgifte in door de tijd (BPTT). Optioneel. Beide frameMode en truncated kunnen niet op hetzelfde moment worden ingesteld true . |
useNumericSequenceKeys |
Reekssleutels worden gebruikt om gecorreleerde reeksen tussen verschillende deserializers te correleren. Voor sommige deserializers (d.w.w.v. HTK en MLF) zijn de reekssleutels willekeurige tekenreeksen. Het opslaan van ze vereist veel geheugen op een groot corpus. Als u zeker weet dat uw reekssleutels numeriek zijn, stelt u deze parameter in op waar, in dat geval worden alle tekenreekssleutels geconverteerd naar gehele getallen die de geheugendruk verlagen. Optioneel, standaard false . |
hashSequenceKeys |
Om de hierboven beschreven geheugenredenen kunnen de tekenreekssleutels ook worden gehasht door deze parameter in te stellen op true. Gebruik deze alleen voor deserializers die tekenreekssleutels (HTK, MLF) ondersteunen. Optioneel, standaard false . |
cacheIndex |
Hiermee geeft u op of de metagegevens die tijdens de voorverwerkingsfase zijn gebouwd, moeten worden weggeschreven naar de schijf en moeten worden geladen vanaf schijf indien beschikbaar (true , ). false Optioneel, standaard ingesteld op false . Zie de onderstaande sectie voor meer informatie. Nieuw in CNTK versie 2.1. |
Indexcaching
Notitie
Nieuw in CNTK versie 2.1.
Met indexcaching kunt u (met een factor van 2-3x) opstarttijden aanzienlijk verminderen, met name wanneer u met grote invoerbestanden werkt. Als u de cacheIndex
vlag instelt zodat true
de lezer de indexeringsmetagegevens naar de schijf schrijft (dezelfde map als het invoerbestand) als het cachebestand niet beschikbaar is of als het verouderd is (ouder dan het invoerbestand). Het schrijven is het beste werk en wordt uitgevoerd op een afzonderlijke thread om de prestaties van de lezer niet te beïnvloeden. Als het cachebestand aanwezig is en up-to-date is, wordt het invoerbestand niet meer door de lezer overgeslagen om de index te bouwen. In plaats daarvan wordt de index uit het cachebestand geladen. Houd er rekening mee dat bepaalde configuratieparameters van de lezer een directe invloed hebben op indexering (bijvoorbeeld verschillende waarden van frameMode
kunnen leiden tot indexen met een ander aantal reeksen). Daarom kan een cachebestand worden genegeerd door een lezer met een andere configuratie dan het bestand dat de cache heeft geproduceerd. Als u het volledige voordeel van caching wilt zien, moet de configuratie niet worden gewijzigd bij volgende nieuwe uitvoeringen.
cacheIndex
heeft geen effect op ImageDeserializer en CNTKBinaryFormatDeserializer, omdat de eerste de invoergegevens niet indexeert en de latere de indexinformatie in de indeling zelf heeft ingesloten.
Algemene deserializer-configuratie
Parameter | Beschrijving |
---|---|
module |
Hiermee geeft u de naam van de lezermodule op waarmee de gegevensdeserializer wordt geïmplementeerd. Vereist. |
type |
Hiermee geeft u een naam voor gegevensdeserializer die wordt weergegeven door de opgegeven lezermodule. Vereist. |
Algemene transformatieconfiguratie
Parameter | Beschrijving |
---|---|
type |
Hiermee geeft u een transformatienaam die wordt weergegeven door de lezermodule die deserializer voor gegevens implementeert. Vereist. |
HTKFeatureDeserializer-opties
Parameter | Beschrijving |
---|---|
scpFile |
Een lijst met paden naar SCP-bestanden die moeten worden verwerkt. De bestanden moeten HTK-compatibele bestanden zijn en moeten worden opgegeven in de 'archiefindeling'. De details van het gebruik van een archief worden beschreven in HTKMLF Reader. Vereist. |
dim |
Een geheel getal dat de dimensie van de volledige functievector aangeeft met het gewenste contextvenster. 1vereist |
contextWindow |
Kan worden opgegeven als een paar positieve gehele getallen of als één positief geheel getal (in dat geval wordt dit geïnterpreteerd als een paar met hetzelfde getal dat tweemaal wordt herhaald). Hiermee geeft u de grootte van links en rechts (eerste en tweede geheel getal van het paar) van het contextvenster in voorbeelden op. Optioneel, standaard ingesteld op 1 . |
prefixPathInSCP |
Een voorvoegseltekenreeks die moet worden toegepast op de paden die zijn opgegeven in de SCP-bestanden. Optioneel. |
1 Als u bijvoorbeeld 72-dimensionale functies (24dimensionale filterbankfuncties plus delta- en delta-deltacoëfficiënten) hebt en het netwerk is ontworpen om een contextvenster van 11 frames te verwerken, moet de opgegeven dimensie 792 zijn.
HTKMLFDeserializer-opties
Parameter | Beschrijving |
---|---|
mlfFile |
Pad naar een HTK-bestand mlf met de labels voor alle uitingen die zijn opgegeven in de scp bestanden. Vereist als mlfFileList dit niet is opgegeven. |
mlfFileList |
Matrix van paden naar HTK-bestand mlf (en) met de labels voor alle uitingen die zijn opgegeven in de scp bestanden. Vereist als mlfFile dit niet is opgegeven. |
dim |
Totale kardinaliteit van de labelset (positief geheel getal). Vereist. |
labelMappingFile |
Pad naar een bestand met alle labels die in het mlf bestand worden weergegeven, één per regel. Vereist. |
labelDim kan worden gebruikt als synoniem voor dim.
CNTKTextFormatDeserializer-opties
Dezelfde opties die kunnen worden gebruikt met CNTKTextFormatReader
Opties voor ImageDeserializer
file
: een eenvoudig tekstbestand waarin elke regel een door tabs gescheiden toewijzing bevat tussen logische reekssleutel, afbeeldingsbestand (bijvoorbeeld JPEG, PNG, enzovoort) en label op basis van 0.
Zie ImageReader voor meer informatie.
Opties voor Base64ImageDeserializer
Deze deserializer ondersteunt dezelfde opties die kunnen worden gebruikt met ImageDeserializer. Het enige verschil is in de indeling van het toewijzingsbestand:
file
: een eenvoudig tekstbestand waarin elke regel een door tabs gescheiden toewijzing bevat tussen logische reekssleutels (optioneel, kan worden weggelaten), categorielabel op basis van 0 en base 64 gecodeerd afbeeldingsbestand (bijvoorbeeld JPEG, PNG, enzovoort).
Voorbeelden van configuraties en tests
U vindt volledige netwerkdefinities en de bijbehorende voorbeelden van gegevenssets in de CNTK-opslagplaats. Daar vindt u ook Eenheids- en End-to-End-tests die gebruikmaken van deserializers, dat wil gezegd hebben.
- https://github.com/Microsoft/CNTK/tree/release/latest/Tests/EndToEndTests/Speech/HTKDeserializers/LSTM/FullUtterance
- https://github.com/Microsoft/CNTK/tree/release/latest/Tests/EndToEndTests/Image/AlexNet
- https://github.com/Microsoft/CNTK/tree/release/latest/Tests/UnitTests/ReaderTests/Config/ImageAndTextReaderSimple_Config.cntk
- https://github.com/Microsoft/CNTK/tree/release/latest/Tests/UnitTests/ReaderTests/Config/CNTKTextFormatReader/dense.cntk