Lecteur de format de texte CNTK BrainScript
Cette page documente le CNTKTextFormatReader du point de vue de BrainScript, mais les utilisateurs de Python peuvent apprendre en lisant ce document également - les concepts, les paramètres et les modèles sont tous les mêmes.
CNTKTextFormatReader (plus tard , lecteur CTF) est conçu pour consommer des données de texte d’entrée mises en forme en fonction de la spécification ci-dessous. Il prend en charge les principales fonctionnalités suivantes :
- Flux d’entrée multiples (entrées) par fichier
- Entrées éparses et denses
- Séquences de longueur variable
format de texte CNTK (CTF)
Chaque ligne du fichier d’entrée contient un exemple pour une ou plusieurs entrées. Étant donné que (explicitement ou implicitement) chaque ligne est également attachée à une séquence, elle définit une ou plusieurs <séquences, entrées, exemples> de relations. Chaque ligne d’entrée doit être mise en forme comme suit :
[Sequence_Id](Sample or Comment)+
où
Sample=|Input_Name (Value )*
Comment=|# some content
- Chaque ligne commence par un ID de séquence et contient un ou plusieurs exemples (en d’autres termes, chaque ligne est une collection non ordonnée d’échantillons).
- L’ID de séquence est un nombre. Il peut être omis, auquel cas le numéro de ligne sera utilisé comme ID de séquence.
- Chaque exemple est effectivement une paire clé-valeur composée d’un nom d’entrée et du vecteur de valeur correspondant (le mappage à des dimensions plus élevées est effectué dans le cadre du réseau lui-même).
- Chaque exemple commence par un symbole de canal (
|
) suivi du nom d’entrée (aucun espace), suivi d’un délimiteur d’espaces blancs, puis d’une liste de valeurs. - Chaque valeur est un nombre ou un nombre avec préfixe d’index pour les entrées éparses.
- Les onglets et les espaces peuvent être utilisés indifféremment comme délimiteurs.
- Un commentaire commence par un canal immédiatement suivi d’un symbole de hachage :
|#
, puis suivi du contenu réel (corps) du commentaire. Le corps peut contenir n’importe quel caractère, mais un symbole de canal à l’intérieur du corps doit être placé dans une séquence d’échappement en y ajoutant le symbole de hachage (voir l’exemple ci-dessous). Le corps d’un commentaire se poursuit jusqu’à la fin de la ligne ou du canal non échappé suivant, selon ce qui se produit en premier.
Exemple simple
Cet exemple est basé sur un ensemble minimal de paramètres et d’options de format.
Pour utiliser le lecteur CTF, définissez la readerType
CNTKTextFormatReader
valeur dans la section lecteur de votre configuration CNTK :
...
reader = [
readerType = "CNTKTextFormatReader"
file = "c:\mydata\SampleInput.txt" # See the second example for Linux path example
# IMPORTANT!
# All inputs are grouped within "input" sub-section.
input = [
A = [
dim = 5
format = "dense"
]
B = [
dim = 1000000
format = "sparse"
]
C = [
dim = 1
format = "dense"
]
]
]
# the rest of the cntk config ...
(Ce fragment ainsi que d’autres exemples NDL de ce document ne présentent que reader
la section, omettant le reste de la configuration CNTK; consultez la fin de cette page pour obtenir des pointeurs vers un ensemble d’exemples complets de réseaux et de jeux de données correspondants)
Le lecteur CTF nécessite l’ensemble de paramètres suivant :
file
: chemin d’accès au fichier avec le jeu de données.input
- sous-section définissant les entrées identifiées par les noms d’entrée (A
B
etC
dans l’exemple ci-dessus). Dans chaque entrée, les paramètres requis suivants doivent être spécifiés :format
: spécifie le type d’entrée. Doit êtredense
ousparse
dim
- spécifie la dimension du vecteur de valeur d’entrée (pour l’entrée dense , cela correspond directement au nombre de valeurs dans chaque échantillon, pour une éparse , cela représente la limite supérieure de la plage de valeurs d’index possibles).
Les données d’entrée correspondant à la configuration de lecteur ci-dessus doivent ressembler à ceci :
|B 100:3 123:4 |C 8 |A 0 1 2 3 4 |# a CTF comment
|# another comment |A 0 1.1 22 0.3 54 |C 123917 |B 1134:1.911 13331:0.014
|C -0.001 |# a comment with an escaped pipe: '|#' |A 3.9 1.11 121.2 99.13 0.04 |B 999:0.001 918918:-9.19
Notez ce qui suit sur le format d’entrée :
|Input_Name
identifie le début de chaque exemple d’entrée. Cet élément est obligatoire et est suivi du vecteur de valeur correspondant.- Le vecteur dense n’est qu’une liste de valeurs à virgule flottante; Vecteur éparse est une liste de
index:value
tuples. - Les onglets et les espaces sont autorisés en tant que délimiteurs de valeur (dans les vecteurs d’entrée) ainsi que les délimiteurs d’entrée (entre les entrées).
- Chaque ligne distincte constitue une « séquence » de longueur 1 (« real » séquences de longueur variable) sont expliquées dans l’exemple étendu ci-dessous.
- Chaque identificateur d’entrée ne peut apparaître qu’une seule fois sur une seule ligne (ce qui se traduit en un échantillon par entrée par exigence de ligne ).
- L’ordre des exemples d’entrée au sein d’une ligne n’est PAS important (conceptuellement, chaque ligne est une collection non ordonnée de paires clé-valeur)
- Chaque ligne bien formée doit se terminer par un symbole « Saut de ligne »
\n
ou « Retour chariot, Saut de ligne ».\r\n
Exemple étendu
Cet exemple présente tous les paramètres de configuration possibles et affiche différentes options de format d’entrée. Reportez-vous aux tableaux ci-dessous pour obtenir la description complète des paramètres de configuration utilisés dans cet exemple.
...
precision="double"
reader = [
readerType = "CNTKTextFormatReader"
file = "/home/mydata/SampleInput.txt" # See the first example for Windows style path example
randomize = true
randomizationWindow = 30
skipSequenceIds = false
maxErrors = 100
traceLevel = 2
chunkSizeInBytes = 1024
keepDataInMemory = true
frameMode = false
input = [
Some_very_long_input_name = [
alias = "a"
dim = 3
format = "dense"
]
Some_other_also_very_long_input_name = [
alias = "b"
dim = 2
format = "dense"
]
]
]
# the rest of the cntk config ...
Avec un lecteur composite, il souhaite les éléments suivants :
reader = {
verbosity = 0 ;
randomize = true;
randomizationWindow=30
deserializers = ({
type = "CNTKTextFormatDeserializer" ; module = "CNTKTextFormatReader"
file = "/home/mydata/SampleInput.txt" # See the first example for Windows style path example
maxErrors = 100
skipSequenceIds = false
traceLevel = 2
input = {
qu1fea = {alias = "qui"; dim = 95589; format = "sparse"}
qu2fea = {alias = "quj"; dim = 95589; format = "sparse"}
pairweight = {alias = "wij"; dim = 1; format = "dense"}
}
})
}
Le fichier d’entrée correspondant peut ensuite se présenter comme suit :
100 |a 1 2 3 |b 100 200
100 |a 4 5 6 |b 101 201
100 |b 102983 14532 |a 7 8 9
100 |a 7 8 9
200 |b 300 400 |a 10 20 30
333 |b 500 100
333 |b 600 -900
400 |a 1 2 3 |b 100 200
|a 4 5 6 |b 101 201
|a 4 5 6 |b 101 201
500 |a 1 2 3 |b 100 200
Toutes les options décrites dans l’exemple ci-dessus s’appliquent toujours ici. En plus de cela, nous avons introduit deux fonctionnalités supplémentaires :
Alias de nom d’entrée
Les noms d’entrée peuvent être longs arbitraires et, par conséquent, les répéter dans le fichier d’entrée peuvent ne pas être efficaces dans l’espace. Pour atténuer ce problème, le jeu de données peut utiliser des « alias » au lieu de noms d’entrée complets. Les alias doivent ensuite être spécifiés dans chaque sous-section d’entrée. Dans notre exemple, le jeu de données utilise des a
alias et b
, respectivement, mappés à « Some_very_long_input_name » et « Some_other_also_very_long_input_name » dans la section de configuration du lecteur.
ID de séquence
Comme mentionné précédemment, chaque ligne distincte du fichier d’entrée représente une séquence contenant un seul exemple pour chaque entrée. Toutefois, si une ligne est précédée d’un nombre non négatif, le nombre est utilisé comme ID de séquence correspondant. Toutes les lignes suivantes qui partagent le même ID de séquence sont fusionnées pour devenir une partie de la même séquence. Par conséquent, la répétition du même préfixe numérique pour les lignes N permet de créer une séquence à plusieurs échantillons, avec chaque entrée contenant entre 1 et N échantillons. L’omission du préfixe de séquence sur les secondes et les lignes suivantes a le même effet. Ainsi, l’exemple de jeu de données ci-dessus définit cinq séquences avec ids 100
, 200
, 333
et 400
500
.
Définir le skipSequenceIds
paramètre dans la section true
lecteur sur , force le lecteur à ignorer tous les ID de séquence explicites dans le jeu de données et à traiter des lignes distinctes comme des séquences individuelles. En outre, l’omission de l’ID de séquence sur la première ligne du jeu de données a le même effet : tous les ID de séquence suivants sont ignorés, les lignes traitées comme des séquences individuelles, comme dans cet exemple :
|a 1 2 3 |b 100 200
100 |a 4 5 6 |b 101 201
200 |b 102983 14532 |a 7 8 9
Quelques points finaux à prendre en compte lors de l’utilisation de séquences :
- Les ID de séquence doivent être uniques.
- Les préfixes d’ID ne peuvent être répétés que pour les lignes consécutives.
- La longueur de séquence dans les lignes (autrement dit, le nombre de lignes partageant le même préfixe d’ID) ne doit pas dépasser la longueur d’entrée maximale dans les échantillons (le nombre d’échantillons dans une entrée) dans cette séquence.
Par exemple, les jeux de données suivants ne sont pas valides :
100 |a 1 2 3 |b 100 200
200 |a 4 5 6 |b 101 201
100 |b 102983 14532 |a 7 8 9
123 |a 1 2 3 |b 100 200
456 |a 4 5 6
456 |b 101 201
Quelques exemples de Real-World
- Classification : chaque ligne contient un exemple, constitué d’une étiquette et de caractéristiques. Aucun ID de séquence n’est nécessaire, car chaque ligne est sa propre « séquence » de longueur 1.
|class 23:1 |features 2 3 4 5 6
|class 13:1 |features 1 2 0 2 3
...
- DSSM : chaque ligne contient une paire de documents source-cible, exprimée par un sac de mots, encodée en tant que vecteurs épars.
|src 12:1 23:1 345:2 45001:1 |tgt 233:1 766:2 234:1
|src 123:1 56:1 10324:1 18001:3 |tgt 233:1 2344:2 8889:1 2234:1 253434:1
- Balisage d’une partie de la reconnaissance vocale : séquences mappant chaque élément à une étiquette correspondante. Les séquences sont alignées verticalement (un mot + balise par ligne).
0 |word 234:1 |tag 12:1
0 |word 123:1 |tag 10:1
0 |word 123:1 |tag 13:1
1 |word 234:1 |tag 12:1
1 |word 123:1 |tag 10:1
...
- Classification de séquence : séquences mappées à une seule étiquette. Les séquences sont alignées verticalement ; L’étiquette « class » peut se produire dans n’importe quelle ligne qui a le même sequenceId.
Notes
Pour le moment, le nombre de lignes ne doit pas dépasser la longueur de la séquence la plus longue. Cela signifie que l’étiquette ne peut pas apparaître seule sur une ligne. Il s’agit d’un détail d’implémentation qui sera levé à l’avenir.
0 |word 234:1 |class 3:1
0 |word 123:1
0 |word 890:1
1 |word 11:1 |class 2:1
1 |word 344:1
- Séquence à séquence : mapper une séquence source à une séquence cible. Les deux séquences sont alignées verticalement et, dans le cas le plus simple, juste imprimées après une autre. Ils sont joints en ayant le même « ID de séquence » global (qui devient ensuite un « ID d’unité de travail » dans ce cas).
Notes
Pour le moment, le nombre de lignes ne doit pas dépasser la longueur de la séquence la plus longue. Cela signifie que les séquences doivent être alignées horizontalement. Il s’agit d’un détail d’implémentation qui sera levé à l’avenir.
0 |sourceWord 234:1 |targetWord 344:1
0 |sourceWord 123:1 |targetWord 456:1
0 |sourceWord 123:1 |targetWord 2222:1
0 |sourceWord 11:1
1 |sourceWord 123:1
...
- Learning à Rank : une « séquence » représente une requête, chaque exemple d’un document avec une évaluation étiquetée manuellement. Dans ce cas, la « séquence » n’est qu’un multiset qui (dans le contexte d’une fonction de perte d’apprentissage à classement) n’a pas de classement.
0 |rating 4 |features 23 35 0 0 0 21 2345 0 0 0 0 0
0 |rating 2 |features 0 123 0 22 44 44 290 22 22 22 33 0
0 |rating 1 |features 0 0 0 0 0 0 1 0 0 0 0 0
1 |rating 1 |features 34 56 0 0 0 45 1312 0 0 0 0 0
1 |rating 0 |features 45 45 0 0 0 12 335 0 0 0 0 0
2 |rating 0 |features 0 0 0 0 0 0 22 0 0 0 0 0
...
Paramètres de configuration
Paramètre | Description |
---|---|
precision |
Spécifie la précision à virgule flottante (double ou float ) des valeurs d’entrée. Facultatif, la valeur par défaut est float . |
reader
Section
Paramètre | Description |
---|---|
readerType |
Spécifie l’un des lecteurs de CNTK pris en charge à charger (par exemple). CNTKTextFormatReader Requis. |
file |
Chemin d’accès au fichier contenant le jeu de données d’entrée (style Windows ou Linux). Requis. |
randomize |
Spécifie si l’entrée doit être aléatoire (true , false ). Facultatif, valeur par défaut .true |
randomizationSeed |
Valeur initiale de départ de la randomisation (incrémentée chaque balayage lorsque les données d’entrée sont réinitialisée). Facultatif, valeur par défaut .0 |
randomizationWindow |
Spécifie la taille (entier positif) de la fenêtre de randomisation (c’est-à-dire la plage de randomisation). Ce paramètre affecte la quantité du jeu de données à résider en mémoire à la fois. Facultatif, en fonction de la sampleBasedRandomizationWindow valeur, par défaut, soit de la taille de l’ensemble du jeu de données dans les échantillons (c’est-à-dire, l’entrée est aléatoire sur l’ensemble du jeu de données) ou de 4 Go d’espace disque (c’est-à-dire 128 , lorsque la taille du segment est égale à 32 Mo). Ce paramètre est ignoré quand randomize est false . |
sampleBasedRandomizationWindow |
Si true , la taille de la fenêtre de randomisation est interprétée comme un certain nombre d’exemples, sinon - comme un certain nombre de blocs. Facultatif, valeur par défaut .false De la même façon que randomizationWindow , ce paramètre est ignoré, quand randomize est false . |
skipSequenceIds |
Si true , le lecteur ignore les ID de séquence dans le fichier d’entrée, en interprétant chaque ligne distincte comme une séquence indépendante de taille 1 (voir la section sur les ID de séquence). Facultatif, valeur par défaut .false |
maxErrors |
Nombre d’erreurs d’entrée après lesquelles une exception doit être levée. Facultatif, par défaut 0 , ce qui signifie que la première valeur mal formée déclenche une exception. |
traceLevel |
Niveau de verbe de sortie. 0 - afficher uniquement les erreurs ; 1 - afficher les erreurs et les avertissements ; 2 - affiche toutes les sorties. Facultatif, valeur par défaut .1 |
chunkSizeInBytes |
Nombre d’octets consécutifs à lire à partir du disque dans une seule opération de lecture. Facultatif, valeur par défaut 33554432 (32 Mo). |
keepDataInMemory |
Si true , l’ensemble du jeu de données est mis en cache en mémoire. Facultatif, valeur par défaut .false |
frameMode |
true signale au lecteur d’utiliser une méthode d’emballage optimisée pour les images (séquences qui ne contiennent qu’un seul exemple). Facultatif, valeur par défaut .false |
cacheIndex |
Spécifie si les métadonnées créées au cours de la phase de prétraitement doivent être écrites sur le disque et chargées à partir du disque si disponibles (,true false ). Facultatif, valeur par défaut .false Pour plus d’informations, consultez la section ci-dessous. Nouveautés de CNTK version 2.1. |
Mise en cache d’index
Notes
Nouveautés de CNTK version 2.1.
La mise en cache d’index permet de réduire considérablement (par un facteur de 2 à 3x) les temps de démarrage, en particulier lors de l’utilisation de fichiers d’entrée volumineux. La définition de l’indicateur cacheIndex
pour true
signaler au lecteur d’écrire les métadonnées d’indexation sur le disque (même répertoire que le fichier d’entrée) si le fichier cache n’est pas disponible ou s’il est obsolète (plus ancien que le fichier d’entrée). L’écriture est le meilleur effort et est effectuée sur un thread distinct afin de ne pas affecter les performances du lecteur. Si le fichier de cache est présent et est à jour, le lecteur n’écrémera plus le fichier d’entrée pour générer l’index, mais il chargera l’index à partir du fichier de cache. Notez que certains paramètres de configuration de lecteur ont un impact direct sur l’indexation (par exemple, différentes valeurs frameMode
peuvent entraîner des index qui ont un nombre différent de séquences). Pour cette raison, un fichier de cache peut être ignoré par un lecteur avec une configuration différente de celle qui a produit le cache. Pour voir l’avantage complet de la mise en cache, la configuration ne doit pas être modifiée lors des réexécutions suivantes.
input
sous-section
input
combine un certain nombre d’entrées individuelles, chacune avec une sous-section de configuration étiquetée de manière appropriée. Tous les paramètres décrits ci-dessous sont spécifiques à une sous-section nom d’entrée associée à une entrée particulière.
Paramètre | Description |
---|---|
alias |
Autre nom abrégé (chaîne) utilisé pour identifier l’entrée dans le jeu de données. Facultatif |
format |
Spécifie le type d’entrée (dense , sparse ). Requis. |
dim |
Dimension (entier positif) de la valeur d’entrée (c’est-à-dire le nombre de valeurs d’entrée dans un exemple d’entrée dense , la limite supérieure de la plage d’index pour l’entrée éparse ). Requis. |
definesMBSize |
Indicateur (false par défaut), indiquant si la taille de minibatch doit être comptabilisée dans les échantillons de ce flux particulier Facultatif. |
Vous trouverez des définitions réseau complètes et des exemples de jeu de données correspondants dans le référentiel CNTK. Vous trouverez également un test de bout en bout qui utilise le lecteur CNTKTextFormat.