BrainScript und Python: Grundlegendes und Erweitern von Lesern
Ab Version 1.5 bewegt sich CNTK von dem monolithischen Leserdesign in Richtung eines komponierbaren Modells, mit dem Sie Eingabedaten verschiedener Formate angeben und verfassen können.
Vor, jede und jede Leser war für verschiedene Aspekte des Lesens von Daten verantwortlich, einschließlich, aber nicht beschränkt auf:
- Deserialisierung der Daten aus externem Speicher in die In-Memory-Darstellung
- Zufallszahl des gesamten Korpus
- Unterschiedliche Transformationen von Eingabesequenzen/Beispielen (z. B. Zuschneiden oder Skalierung von Bildern)
- Erstellung von Minibatches für verschiedene Modi (z. B. Frame, Sequenz oder abgeschnittene BPTT) mit einem Layout, das von GPU genutzt werden kann
- Prefetch auf der Ebene von Minibatches und IO-Blöcken
In Version 1.5 wurden die wichtigsten Teile der obigen Funktionalität herausgefiltert und in das Kern-CNTK verschoben, um zwischen verschiedenen Lesern geteilt zu werden. Diese Version führt auch zwei Hauptabstraktionen ein, die erweitert werden können, um neue Datenformate zu unterstützen:
- deserializer – es ist für die Deserialisierung von Eingaben aus externem Speicher in Speichersequenzen verantwortlich.
- transform - es transformiert eine Eingabesequenz in eine Ausgabesequenz
In den nächsten Abschnitten werden diese Abstraktionen ausführlicher behandelt.
Konfigurieren eines Reader (Minibatchquelle) in Python
Dieser Abschnitt enthält mehrere Beispiele, wie ein zusammengesetzter Reader (aka MinibatchSource) in Python konfiguriert werden kann.
Das folgende Beispiel wurde von AlexNet_ImageNet_Distributed.py angepasst, es zeigt das Python-Äquivalent des AlexNet-Reader aus transforms Abschnitt.
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))))
Das folgende Beispiel (angepasst von A2_RunCntk_py3.py) zeigt, wie mehrere Deserializer zusammen kombiniert werden können.
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
Deserializer
Sehen wir uns das folgende Konfigurationsfragment für den HTKMLFReader aus dem End-to-End-LSTM /FullUtterance-Test an (vollständige Konfiguration hier):
...
# 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"
]
]
Dieses Fragment der Konfiguration deklariert einen Leser, der zwei Datenströme mit Namen "features"
"labels"
und . Es dauert zwei Arten von Dateien:
- eine Liste der Featuredateien, die in der HTK-Parität als
scp
Datei ("Skriptdatei") bekannt sind - eine Bezeichnungsdatei, die als
mlf
Datei ("Master label file") bezeichnet wird
Im obigen Konfigurationsfragment gibt es keine expliziten Entitäten, die definieren würden, wie oder mlf
wie scp
Formate deserialisiert werden.
Alles wird in der HTKMLFReader-Konfiguration gekapselt.
Wenn Sie also noch einen anderen Eingabestrom unterschiedlicher Datenformate zusammen scp
mit anderen Datenformaten verfügbar machen müssen, mlf
müssen Sie HTKMLFReader ändern und dort Unterstützung hinzufügen.
Um die Zusammenstellung und Wiederverwendung zu erhöhen, definiert die neue Konfiguration für dieselbe Eingabe explizit Deserializer und die von ihnen erzeugten Eingabedatenströme:
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
]
]
]
)
]
Die von den mlf
und htk
deserializern erzeugten Sequenzen werden basierend auf ihrem logischen Schlüssel kombiniert (eine Zeichenfolge, die eine Sprachausgabe eindeutig identifiziert und in beiden scp
mlf
Dateien vorhanden ist).
Wenn Sie einen anderen Datenstrom unterschiedlicher Formate benötigen, können Sie einfach den entsprechenden Deserializer zur Konfiguration hinzufügen (es ist mit dem HTK-Feature und HTK MLF MLF deserializers derzeit nicht möglich, mehr als einen Eingabedatenstrom verfügbar zu machen).
Hinweis
Derzeit werden sowohl alte als auch neue Readerkonfigurationen unterstützt. Wenn der Schlüssel "Deserializers" in der Readerkonfiguration verwendet wird, wird der Lesetyp implizit auf "CompositeDataReader" festgelegt. Um sicherzustellen, dass das CompositeDataReader-Modul unter Windows geladen werden kann, Cntk.Composite.dll
sollte sich im gleichen Verzeichnis wie die ausführbare CNTK-Datei befinden. Unter Linux Cntk.Composite.so
sollte sich in dem Ordner befinden, der lib
sich neben dem Ordner befindet, der bin
die ausführbare Datei "CNTK" enthält.
Derzeit unterstützt CNTK die folgenden Deserializer:
Deserializertyp | Modul | BESCHREIBUNG |
---|---|---|
HTKFeatureDeserializer | HTKDeserializer | Deserializer für HTK-Featuredateien |
HTKMLFDeserializer | HTKDeserializer | Deserializer für HTK-MLF-Dateien |
ImageDeserializer | ImageReader | Deserializer für Bilder, die als einfache Dateien oder im ZIP-Archiv codiert sind. |
Base64ImageDeserializer | ImageReader | Deserializer für Bilder, die als Base64-Zeichenfolgen in der Zuordnungsdatei codiert sind. |
CNTKTextFormatDeserializer | CNTKTextFormatReader | Deserializer für CNTK-Textdateien |
CNTKBinaryFormatDeserializer | CNTKBinaryReader | Deserializer für CNTK-Binärformatdateien |
Weitere Informationen finden Sie in den nachstehenden Tabellen, um die vollständige Beschreibung der Konfigurationsparameter zu erhalten.
Transformationen
Eine Transformation ist eine einfache Abstraktion, die eine Sequenz als Eingabe verwendet, einige Transformationen von Beispielen in der Sequenz ausführt und die Ausgabesequenz zurückgibt. Typische Beispiele für Transformationen sind unterschiedliche Transformationen von Bildern wie Zuschneiden, Skalieren oder Transponieren. Transformationen können pro Eingabebasis konfiguriert werden.
Sehen wir uns an, wie Transformationen auf die Eingabe angewendet werden können (die Konfiguration wird aus den Tests/EndToEndTests/Image/AlexNet-Test entnommen):
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 dieser Konfiguration werden vier Transformationen auf den Eingabedatenstrom features
angewendet.
Zunächst erzeugt die Bilddaten deserializer Sequenzen, die aus einem einzelnen Bild in der HWC-Darstellung bestehen.
Danach wird die sortierte Liste der Transformationen auf das Bild angewendet: zuerst die Zuschneidentransformation , gefolgt von Skalierung und Mittelwert.
Die letzte Transformation ist Transponieren , die das Bildlayout von HWC in CHW ändert.
Derzeit werden die folgenden Transformationen implementiert. Ausführliche Beschreibung finden Sie unter ImageReader.
Transformationstyp | Modul |
---|---|
Crop | ImageReader |
Skalieren | ImageReader |
Color | ImageReader |
Mittelwert | ImageReader |
Transponieren | ImageReader |
Beschreibung des Neuen Reader-Konfigurationsformats
Ein Abschnitt zur Lesekonfiguration zum Verfassen mehrerer Daten deserializers sieht wie folgt aus:
reader = [
randomize = true|false
verbosity = 0|1|2
...
deserializers = (
[<deserializerConfiguration1>]:
[<deserializerConfiguration2>]:
...
[<deserializerConfigurationN>]
)
]
Jede Deserializer-Konfiguration wird wie folgt angegeben:
[
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>]
...
]
]
Eine Eingabekonfiguration enthält eingabespezifische Optionen und optional eine sortierte Liste der Transformationen, die auf die Eingabe angewendet werden sollen:
[
# Per-input data deserializer-specific options
# Optionally a pipeline of transformations, to be implemented by data deserializer's reader module:
transforms = (
[<transformationConfiguration1>]:
[<transformationConfiguration2>]:
...
[<transformationConfigurationN>]
)
]
Transformationskonfiguration identifiziert den Transformationstyp und alle transformationsspezifischen Optionen:
[
type = "<transformName>"
# Transform-specific options
]
Konfigurationsoptionen
Allgemeine Reader-Konfiguration
Parameter | BESCHREIBUNG |
---|---|
verbosity |
Verbosity Level (0 , , 2 1 ), steuert die Diagnoseausgabe verschiedener Komponenten (Randomizer, Deserializer, Bundler usw.) Optional, Standardwerte für 0 . |
randomize |
Gibt an, ob die Eingabe zufällig ( true , false ) sein soll. Randomization-Methode ist identisch mit blockRandomize des HTKMLFReader. Optional, Standardwerte für true . |
randomizationSeed |
Initial randomization seed value (incremented every sweep when the input data is re-randomized). Optional, Standardwerte für 0 . |
randomizationWindow |
Gibt die Größe (positive ganze Zahl) des Randomisierungsfensters (z. B. Zufälligkeitsbereich) an. Dieser Parameter wirkt sich darauf aus, wie viel des Datasets gleichzeitig im Arbeitsspeicher gespeichert sein muss. Optional ist standardmäßig die Größe des gesamten Datasets (in Beispielen oder in Blöcken abhängig vom sampleBasedRandomizationWindow Wert). Wenn eines der Deserializer jedoch nicht explizit auf festgelegt wurde sampleBasedRandomizationWindow CNTKTextFormatDeserializer , randomizationWindow wird standardmäßig auf (etwa 4 GB Speicherplatz im Wert von Blöcken) festgelegt true 128 . Dieser Parameter wird ignoriert, wenn randomize es sich um false . |
sampleBasedRandomizationWindow |
Wenn true die Größe des Zufallsfensters als eine bestimmte Anzahl von Beispielen interpretiert wird, und als eine Reihe von Blöcken andernfalls. Optional, standardmäßig true , wenn CNTKTextFormatDeserializer in der Liste der Deserializer nicht vorhanden ist, und andernfalls false . Ähnlich wie , randomizationWindow wird dieser Parameter ignoriert, wenn randomize ist false . |
truncationLength |
Gibt die Abschneidenlänge in Beispielen für BPTT (positive ganze Zahl) an. Ist nur erforderlich , wenn truncated true , andernfalls ignoriert wird. |
multiThreadedDeserialization |
Gibt an, ob beim Sammeln von Sequenzen für ein Minibatch aus den Deserializern (true , false ) mehrere Threads verwendet werden sollen. Optional: |
frameMode |
Gibt an, ob Daten zufällig und auf Frame- oder Sequenzebene zurückgegeben werden sollen. Wenn true die Eingabesequenz in Frames aufgeteilt wird. Optional: Beide frameMode und truncated können nicht gleichzeitig festgelegt true werden. |
truncated |
Wenn true , aktiviert abgeschnittene Back-Verteilung durch Zeit (BPTT). Optional: Beide frameMode und truncated können nicht gleichzeitig festgelegt true werden. |
useNumericSequenceKeys |
Sequenztasten werden zum Korrelieren von Sequenzen zwischen verschiedenen Deserializern verwendet. Für einige Deserializer (d. h. HTK und MLF) sind die Sequenztasten beliebige Zeichenfolgen. Die Speicherung erfordert viel Arbeitsspeicher auf großem Korpus. Wenn Sie sicher sind, dass die Sequenztasten numerisch sind, legen Sie diesen Parameter auf "true" fest. In diesem Fall werden alle Zeichenfolgentasten in ganze Zahlen konvertiert, die den Arbeitsspeicherdruck verringern. Optional, Standard false . |
hashSequenceKeys |
Aus den oben beschriebenen Speichergründen können die Zeichenfolgenschlüssel auch hashen, indem sie diesen Parameter auf "true" festlegen. Verwenden Sie es nur für Deserializer, die Zeichenfolgensequenztasten (HTK, MLF) unterstützen. Optional, Standard false . |
cacheIndex |
Gibt an, ob die metadaten, die während der Vorverarbeitungsphase erstellt wurden, auf den Datenträger geschrieben und auf dem Datenträger geladen werden sollen, sofern verfügbar (true , false ). Optional, Standardwerte für false . Weitere Details finden Sie im folgenden Abschnitt. Neu in CNTK, Version 2.1. |
Indexcache
Hinweis
Neu in CNTK, Version 2.1.
Das Zwischenspeichern von Index ermöglicht es, die Startzeiten (um einen Faktor von 2-3x) erheblich zu reduzieren, insbesondere beim Arbeiten mit großen Eingabedateien. Durch Festlegen des cacheIndex
Flags true
wird der Leser signalisiert, dass die Indizierung von Metadaten auf den Datenträger (dasselbe Verzeichnis wie die Eingabedatei) geschrieben wird, wenn die Cachedatei nicht verfügbar ist oder veraltet ist (älter als die Eingabedatei). Die Schreibweise ist am besten bestrebt und wird auf einem separaten Thread durchgeführt, um die Leseleistung nicht zu beeinträchtigen. Wenn die Cachedatei vorhanden ist und aktuell ist, übergibt der Leser nicht mehr die Eingabedatei, um den Index zu erstellen, sondern lädt den Index aus der Cachedatei. Bitte beachten Sie, dass bestimmte Lesekonfigurationsparameter direkte Auswirkungen auf die Indizierung haben (z. B. können unterschiedliche Werte frameMode
zu Indizes führen, die unterschiedliche Anzahl von Sequenzen aufweisen). Aus diesem Grund könnte eine Cachedatei von einem Leser ignoriert werden, der sich von der Konfiguration unterscheidet, die den Cache erzeugt hat. Um den vollständigen Vorteil des Zwischenspeicherns zu sehen, sollte die Konfiguration bei nachfolgenden Wiederholungen nicht geändert werden.
cacheIndex
hat keine Auswirkung auf ImageDeserializer und CNTKBinaryFormatDeserializer, da der frühere nicht die Eingabedaten indiziert und später die Indexinformationen im Format selbst eingebettet hat.
Allgemeine Deserializer-Konfiguration
Parameter | BESCHREIBUNG |
---|---|
module |
Gibt den Namen des Readermoduls an, der die Daten deserializer implementiert. Erforderlich. |
type |
Gibt einen Daten deserializer-Namen an, der vom angegebenen Readermodul verfügbar gemacht wird. Erforderlich. |
Allgemeine Transformationskonfiguration
Parameter | BESCHREIBUNG |
---|---|
type |
Gibt einen Transformationsnamen an, der vom Lesermodul verfügbar gemacht wird, das die Daten deserializer implementiert. Erforderlich. |
HTKFeatureDeserializer-Optionen
Parameter | BESCHREIBUNG |
---|---|
scpFile |
Eine Liste der Pfade zu SCP-Dateien, die verarbeitet werden sollen. Die Dateien sollten HTK-kompatible Dateien sein und im Format "Archiv" angegeben werden. Die Details zur Verwendung eines Archivs werden im HTKMLF Reader beschrieben. Erforderlich. |
dim |
Eine ganze Zahl, die die vollständige Featurevektordimension mit dem gewünschten Kontextfenster angibt. 1Erforderlich |
contextWindow |
Kann entweder als Paar positiver Ganzzahlen oder als einzelne positive ganze Zahl angegeben werden (in diesem Fall wird es als Paar interpretiert, bei dem dieselbe Zahl zweimal wiederholt wird). Gibt die linke und rechte Größe (erste und zweite Ganzzahl des Paares) des Kontextfensters in Beispielen an. Optional, Standardwerte für 1 . |
prefixPathInSCP |
Eine Präfixzeichenfolge, die auf die in den SCP-Dateien angegebenen Pfade angewendet werden soll. Optional: |
1 Wenn Sie beispielsweise 72dimensionale Features (24dimensionale Filterbankfeatures plus Delta- und Delta-Delta-Koeffizienten) hatten und das Netzwerk so konzipiert ist, dass ein Kontextfenster von 11 Frames verarbeitet wird, sollte die angegebene Dimension 792 sein.
HTKMLFDeserializer-Optionen
Parameter | BESCHREIBUNG |
---|---|
mlfFile |
Pfad zu einer HTK-Formatdatei mlf , die die Bezeichnungen für alle in der scp Datei angegebenen Ausdrücke enthält. Erforderlich , wenn mlfFileList nicht angegeben. |
mlfFileList |
Array von Pfaden zu HTK-Formatdatei mlf (n), die die Bezeichnungen für alle in den scp Datei(n) angegebenen Ausdrücken enthält. Erforderlich , wenn mlfFile nicht angegeben. |
dim |
Gesamt kardinalität des Bezeichnungssatzes (positive ganze Zahl). Erforderlich. |
labelMappingFile |
Pfad zu einer Datei, die alle in der mlf Datei angezeigten Bezeichnungen auflistet, 1 pro Zeile. Erforderlich. |
labelDim kann als Synonym für Dim verwendet werden.
CNTKTextFormatDeserializer-Optionen
Dieselben Optionen, die mit CNTKTextFormatReader verwendet werden können
ImageDeserializer-Optionen
file
: eine einfache Textdatei, in der jede Zeile eine tabstopptrennte Zuordnung zwischen logischen Sequenzschlüsseln, Bilddatei (z. B. JPEG, PNG usw.) und 0-basierte Bezeichnung enthält.
Weitere Informationen finden Sie unter ImageReader.
Base64ImageDeserializer-Optionen
Dieser Deserializer unterstützt dieselben Optionen, die mit ImageDeserializer verwendet werden können. Der einzige Unterschied besteht im Format der Zuordnungsdatei:
file
: eine einfache Textdatei, in der jede Zeile eine tabstopptrennte Zuordnung zwischen logischen Sequenzschlüsseln enthält (optional, kann weggelassen werden), 0-basierte Kategoriebeschriftung und Basis-64-codierte Bilddatei (z. B. JPEG, PNG usw.).
Beispiele für Konfigurationen und Tests
Sie finden vollständige Netzwerkdefinitionen und die entsprechenden Datasetbeispiele im CNTK-Repository. Dort finden Sie auch Unit- und End-to-End-Tests, die Deserializer verwenden, d. h.
- 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