BrainScript a Python: Principy a rozšíření čtenářů
Od verze 1.5 se CNTK přesouvá od monolitického návrhu čtečky směrem k kompozovatelnému modelu, který umožňuje zadat a vytvářet vstupní data různých formátů.
Před každým čtenářem zodpovídá za různé aspekty čtení dat, mimo jiné:
- Deserializace dat z externího úložiště do reprezentace v paměti
- Randomizace celého korpusu
- Různé transformace vstupních sekvencí/ukázek (tj. oříznutí nebo škálování obrázků)
- Vytvoření minibatch pro různé režimy (tj. rám, posloupnost nebo zkrácený BPTT) s rozložením, které může gpu využívat
- Předběžné načtení na úrovni minibatch a vstupně-výstupních bloků dat
Ve verzi 1.5 byly hlavní části výše uvedené funkce zohledněny a přesunuty do jádra CNTK, které se mají sdílet mezi různými čtenáři. Tato verze také zavádí dvě hlavní abstrakce, které je možné rozšířit, aby podporovaly nové formáty dat:
- deserializátor - zodpovídá za deserializaci vstupu z externího úložiště do sekvencí v paměti.
- transformace – transformuje vstupní sekvenci na výstupní sekvenci.
V dalších částech probereme tyto abstrakce podrobněji.
Konfigurace čtečky (zdroj minibatch) v Pythonu
Tato část obsahuje několik příkladů konfigurace složené čtečky (neboli MinibatchSource) v Pythonu.
Následující příklad byl upraven z AlexNet_ImageNet_Distributed.py, ukazuje ekvivalent Pythonu čtečky AlexNet z části Transformace .
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))))
Následující příklad (přizpůsobený z A2_RunCntk_py3.py) ukazuje, jak se dá zkombinovat několik deserializérů.
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
Pojďme se podívat na následující fragment konfigurace pro HTKMLFReader z kompletního testu LSTM/FullUtterance ( úplná konfigurace zde):
...
# 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"
]
]
Tento fragment konfigurace deklaruje čtenáře, který vytváří dva datové proudy s názvy "features"
a "labels"
. Přebírá jako vstup dva typy souborů:
- seznam souborů funkcí známých v analyzátoru HTK jako
scp
soubor ("skript" soubor) - soubor popisku známý jako
mlf
soubor ("hlavní soubor popisku")
Ve výše uvedeném fragmentu konfigurace neexistují žádné explicitní entity, které by definovaly způsob scp
deserializace formátů mlf
.
Všechno je zapouzdřené v konfiguraci HTKMLFReader .
Takže pokud potřebujete zveřejnit další vstupní stream různých formátů dat společně s scp
a mlf
, budete muset změnit HTKMLFReader a přidat podporu tam.
Pokud chcete zvýšit kompozitnost a opakované použití, nová konfigurace pro stejný vstup explicitně definuje deserializátory a vstupní datové proudy, které vytvářejí:
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
]
]
]
)
]
Sekvence vytvořené mlf
a htk
deserializery se zkombinují na základě jejich logického klíče (což je řetězec, který jednoznačně identifikuje řečovou promluvu a nachází se v obou scp
i mlf
souborech).
Pokud potřebujete další datový proud jiného formátu, můžete jednoduše přidat odpovídající deserializátor do konfigurace (není to možné s funkcí HTK a HTK MLF deserializery právě teď zpřístupnit více než jeden vstupní stream každý).
Poznámka
V současné době se podporují staré i nové konfigurace čtečky. Při použití klíče deserializers v konfiguraci čtečky je typ čtečky implicitně nastaven na "CompositeDataReader". Chcete-li zajistit, aby byl modul CompositeDataReader načten ve Windows, Cntk.Composite.dll
měl by být umístěn ve stejném adresáři jako spustitelný soubor CNTK. V Linuxu Cntk.Composite.so
lib
by měl být ve složce, která se nachází vedle bin
složky obsahující spustitelný soubor CNTK.
V současné době CNTK podporuje následující deserializátory:
Typ deserializátoru | Modul | Description |
---|---|---|
HTKFeatureDeserializer | HTKDeserializers | Deserializer pro soubory funkcí HTK |
HTKMLFDeserializer | HTKDeserializers | Deserializer pro soubory HTK MLF |
ImageDeserializer | ImageReader | Deserializátor pro obrázky kódované jako prosté soubory nebo v archivu zip. |
Base64ImageDeserializer | ImageReader | Deserializer pro obrázky kódované jako řetězce base64 v souboru mapování. |
CNTKTextFormatDeserializer | CNTKTextFormatReader | Deserializer pro soubory textového formátu CNTK |
CNTKBinaryFormatDeserializer | CNTKBinaryReader | Deserializer pro soubory binárního formátu CNTK |
Úplný popis parametrů konfigurace najdete v následujících tabulkách.
Transformace
Transformace je jednoduchá abstrakce, která vezme posloupnost jako vstup, provede některé transformace ukázek v sekvenci a vrátí výstupní sekvenci. Typické příklady transformací jsou různé transformace obrázků, jako jsou oříznutí, měřítko nebo transponace. Transformace je možné nakonfigurovat na základě vstupu.
Pojďme se podívat, jak se dají transformace použít na vstup (konfigurace se používá z testu 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
]
]
]
])
V této konfiguraci se na vstupní datový proud features
použijí čtyři transformace .
Zpočátku deserializátor dat obrázku vytváří sekvence skládající se z jednoho obrázku v reprezentaci HWC.
Potom se na obrázek použije seřazený seznam transformací: nejprve transformace Oříznutí následovaný měřítkem a průměrem.
Poslední transformací je Transpozice , která změní rozložení obrázku z HWC na CHW.
V současné době se implementují následující transformace. Podrobný popis naleznete v tématu ImageReader.
Typ transformace | Modul |
---|---|
Oříznout | ImageReader |
Měřítko | ImageReader |
Barva | ImageReader |
Mean | ImageReader |
Transponovat | ImageReader |
Popis nového formátu konfigurace čtečky
Oddíl konfigurace čtenáře, který vytvoří několik deserializérů dat, vypadá takto:
reader = [
randomize = true|false
verbosity = 0|1|2
...
deserializers = (
[<deserializerConfiguration1>]:
[<deserializerConfiguration2>]:
...
[<deserializerConfigurationN>]
)
]
Každá konfigurace deserializátoru je zadána takto:
[
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>]
...
]
]
Vstupní konfigurace obsahuje možnosti specifické pro vstup a volitelně uspořádaný seznam transformací, které by se měly použít pro vstup:
[
# Per-input data deserializer-specific options
# Optionally a pipeline of transformations, to be implemented by data deserializer's reader module:
transforms = (
[<transformationConfiguration1>]:
[<transformationConfiguration2>]:
...
[<transformationConfigurationN>]
)
]
Konfigurace transformace identifikuje typ transformace a všechny možnosti specifické pro transformaci:
[
type = "<transformName>"
# Transform-specific options
]
Možnosti konfigurace
Obecná konfigurace čtečky
Parametr | Popis |
---|---|
verbosity |
Úroveň podrobností (0 , 1 , 2 ), řídí diagnostický výstup různých komponent (Randomizer, Deserializer, Bundler atd.) Volitelné, výchozí hodnota je 0 . |
randomize |
Určuje, zda má být vstup randomizován ( true , false ). Metoda randomizace je stejná jako blockRandomize HTKMLFReader. Volitelné, výchozí hodnota je true . |
randomizationSeed |
Počáteční hodnota seed randomizace (zvýší se při opětovném náhodném přemíscení vstupních dat). Volitelné, výchozí hodnota je 0 . |
randomizationWindow |
Určuje velikost (kladné celé číslo) okna randomizace (tj. rozsah randomizace). Tento parametr ovlivňuje, kolik datové sady se musí najednou nacházet v paměti. Volitelné, výchozí hodnota je velikost celé datové sady (v ukázkách nebo v blocích v závislosti na sampleBasedRandomizationWindow hodnotě). Pokud je CNTKTextFormatDeserializer ale jeden z deserializerů a sampleBasedRandomizationWindow nebyl explicitně nastaven na true , randomizationWindow ve výchozím nastavení se nastaví 128 (což je přibližně 4 GB místa na disku, které stojí za bloky dat). Tento parametr je ignorován, pokud randomize je false . |
sampleBasedRandomizationWindow |
Pokud true je velikost okna randomizace interpretována jako určitý počet vzorků a jako počet bloků jinak. Volitelné, výchozí nastavení true , pokud CNTKTextFormatDeserializer není v seznamu deserializerů, a jinak false . Podobně jako randomizationWindow tento parametr je ignorován, pokud randomize je false . |
truncationLength |
Určuje délku zkrácení ve vzorcích pro BPTT (kladné celé číslo). Povinné pouze v případě, že truncated je true , ignorováno jinak. |
multiThreadedDeserialization |
Určuje, jestli se má použít více vláken při shromažďování sekvencí pro minibatch z deserializerů (true , false ). Volitelné. |
frameMode |
Určuje, jestli mají být data randomizována a vrácena na úrovni rámce nebo sekvence. Když true se vstupní sekvence rozdělí na rámce. Volitelné. Obě frameMode a truncated nesmí být nastaveny na true stejnou dobu. |
truncated |
Když true povolí zkrácení zpětného šíření v čase (BPTT). Volitelné. Obě frameMode a truncated nesmí být nastaveny na true stejnou dobu. |
useNumericSequenceKeys |
Klíče posloupnosti slouží ke korelaci sekvencí mezi různými deserializery. U některých deserializerů (tj. HTK a MLF) jsou klíče sekvence libovolnými řetězci. Ukládání je vyžaduje hodně paměti na velkém korpusu. Pokud máte jistotu, že jsou klíče sekvence číselné, nastavte tento parametr na true, v takovém případě se všechny řetězce klíče převedou na celá čísla, která snižují zatížení paměti. Volitelné, výchozí false . |
hashSequenceKeys |
Z výše popsaných důvodů paměti mohou být klíče řetězců také hashovány nastavením tohoto parametru na true. Použijte ho pouze pro deserializery, které podporují klíče sekvence řetězců (HTK, MLF). Volitelné, výchozí false . |
cacheIndex |
Určuje, zda by se meta-data vytvořená během fáze předběžného zpracování měla zapsat na disk a načíst je z disku, pokud je k dispozici (true , false ). Volitelné, výchozí hodnoty .false Další podrobnosti najdete v následující části. Novinka v CNTK verze 2.1. |
Ukládání indexů do mezipaměti
Poznámka
Novinka v CNTK verze 2.1.
Ukládání indexů do mezipaměti umožňuje výrazně (faktorem 2–3x) snížit časy spuštění, zejména při práci s velkými vstupními soubory. Pokud soubor mezipaměti není dostupný nebo pokud není soubor mezipaměti zastaralý (starší než vstupní soubor), nastavíte cacheIndex
příznak tak, aby true
čtečka signalizovala zápis meta-dat na disk (stejný adresář jako vstupní soubor). Psaní je nejlepší a provádí se na samostatném vlákně, aby to nemělo vliv na výkon čtenáře. Pokud soubor mezipaměti existuje a je aktuální, čtečka už nebude přeskočovat vstupní soubor k sestavení indexu, místo toho index načte ze souboru mezipaměti. Upozorňujeme, že některé parametry konfigurace čtenáře mají přímý dopad na indexování (například různé hodnoty frameMode
by mohly vést k indexům, které mají různý počet sekvencí). Z tohoto důvodu může soubor mezipaměti ignorovat čtenář s konfigurací jinou než ten, který mezipaměť vytvořil. Pokud chcete zobrazit úplnou výhodu ukládání do mezipaměti, konfigurace by se neměla upravovat při následných opakovaných spuštěních.
cacheIndex
nemá žádný vliv na ImageDeserializer a CNTKBinaryFormatDeserializer, protože bývalý neindexuje vstupní data a později obsahuje informace o indexu vložené do samotného formátu.
Obecná konfigurace deserializátoru
Parametr | Popis |
---|---|
module |
Určuje název modulu čtenáře, který implementuje deserializátor dat. Povinné. |
type |
Určuje název deserializátoru dat vystavený daným modulem čtenáře. Povinné. |
Obecná konfigurace transformace
Parametr | Popis |
---|---|
type |
Určuje název transformace vystavený modulem čtenáře, který implementuje deserializátor dat. Povinné. |
Možnosti HTKFeatureDeserializer
Parametr | Popis |
---|---|
scpFile |
Seznam cest k souborům SCP, které se mají zpracovat. Soubory by měly být kompatibilní se soubory HTK a musí být zadány ve formátu "archiv". Podrobnosti použití archivu jsou popsány v nástroji HTKMLF Reader. Povinné. |
dim |
Celé číslo, které určuje úplnou dimenzi vektoru funkce s požadovaným kontextovým oknem. 1Povinné |
contextWindow |
Je možné zadat buď jako dvojici kladných celých čísel, nebo jako jedno kladné celé číslo (v takovém případě se interpretuje jako pár se stejným číslem, který se opakuje dvakrát). Určuje velikost vlevo a vpravo (první a druhé celé číslo páru) kontextového okna v ukázkách. Volitelné, výchozí hodnoty .1 |
prefixPathInSCP |
Řetězec předpony, který se má použít u cest zadaných v souborech SCP. Volitelné. |
1 Pokud jste například měli 72rozměrné funkce (24rozměrné funkce filterbank plus rozdílové a rozdílové koeficienty) a síť je navržená tak, aby zpracovávala kontextové okno s 11 snímky, zadaný rozměr by měl být 792.
Možnosti HTKMLFDeserializer
Parametr | Popis |
---|---|
mlfFile |
Cesta k souboru stylu mlf HTK, který obsahuje popisky všech promluv zadaných v scp souborech. Povinné , pokud mlfFileList není zadáno. |
mlfFileList |
Pole cest k souborům ve stylu mlf HTK, které obsahují popisky pro všechny promluvy zadané v scp souborech. Povinné , pokud mlfFile není zadáno. |
dim |
Celková kardinalita sady popisků (kladné celé číslo). Povinné. |
labelMappingFile |
Cesta k souboru, který obsahuje všechny popisky zobrazené v mlf souboru, jeden na řádek. Povinné. |
labelDim se dá použít jako synonymum pro dim.
Možnosti CNTKTextFormatDeserializer
Stejné možnosti, které lze použít s CNTKTextFormatReader
Možnosti imageDeserializátoru
file
: jednoduchý textový soubor, ve kterém každý řádek obsahuje mapování oddělené tabulátorem mezi logickým klíčem sekvence, souborem obrázku (např. JPEG, PNG atd.) a 0 popiskem.
Další informace naleznete v tématu ImageReader.
Možnosti base64ImageDeserializer
Tento deserializátor podporuje stejné možnosti, které lze použít s ImageDeserializer. Jediný rozdíl je ve formátu souboru mapování:
file
: Jednoduchý textový soubor, kde každý řádek obsahuje mapování oddělené tabulátorem mezi logickým klíčem sekvence (volitelné, lze vynechat), popisek kategorie 0 a základní soubor obrázku s kódováním 64 (např. JPEG, PNG atd.).
Příklady konfigurací a testů
V úložišti CNTK najdete kompletní definice sítě a odpovídající příklady sady dat. Najdete zde také testy jednotek a end-to-end, které používají deserializery, tj.
- 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