Compartir a través de


Lector de formato de texto de BrainScript CNTK

Esta página documenta el CNTKTextFormatReader desde el punto de vista de BrainScript, pero los usuarios de Python también pueden aprender leyendo este documento; los conceptos, parámetros y patrones son los mismos.

CNTKTextFormatReader (más adelante, simplemente lector CTF) está diseñado para consumir datos de texto de entrada con formato según la especificación siguiente. Admite las siguientes características principales:

  • Varias secuencias de entrada (entradas) por archivo
  • Entradas dispersas y densas
  • Secuencias de longitud variable

formato de texto de CNTK (CTF)

Cada línea del archivo de entrada contiene un ejemplo para una o varias entradas. Dado que (explícita o implícitamente) todas las líneas también se adjuntan a una secuencia, define una o más <secuencia, entrada, relaciones de ejemplo> . Cada línea de entrada debe tener el formato siguiente:

[Sequence_Id](Sample or Comment)+

where

Sample=|Input_Name (Value )*

Comment=|# some content

  • Cada línea comienza con un identificador de secuencia y contiene uno o varios ejemplos (es decir, cada línea es una colección desordenada de muestras).
  • El identificador de secuencia es un número. Se puede omitir, en cuyo caso el número de línea se usará como identificador de secuencia.
  • Cada ejemplo es efectivamente un par clave-valor que consta de un nombre de entrada y el vector de valor correspondiente (la asignación a dimensiones superiores se realiza como parte de la propia red).
  • Cada ejemplo comienza con un símbolo de canalización (|) seguido del nombre de entrada (sin espacios), seguido de un delimitador de espacios en blanco y, a continuación, una lista de valores.
  • Cada valor es un número o un número con prefijo de índice para entradas dispersas.
  • Tanto las pestañas como los espacios se pueden usar indistintamente como delimitadores.
  • Un comentario comienza con una canalización inmediatamente seguida de un símbolo hash: |#, seguido del contenido (cuerpo) realmente del comentario. El cuerpo puede contener cualquier carácter, pero un símbolo de canalización dentro del cuerpo debe escaparse anexando el símbolo hash a él (vea el ejemplo siguiente). El cuerpo de un comentario continúa hasta el final de la línea o la siguiente canalización sin escape, lo que ocurra primero.

Ejemplo sencillo

Este ejemplo se basa en un conjunto mínimo de parámetros y opciones de formato.

Para usar el lector CTF, establezca en readerTypeCNTKTextFormatReader en la sección lector de la configuración de 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 ...

(Este fragmento, así como otros ejemplos de NDL de este documento solo reader presentan, omiten el resto de la configuración de CNTK; vea el final de esta página para punteros a un conjunto de redes de ejemplo completo y los conjuntos de datos correspondientes).

El lector CTF requiere el siguiente conjunto de parámetros:

  • file : ruta de acceso al archivo con el conjunto de datos.
  • input: subsección que define entradas identificadas por nombres de entrada (ABy C en el ejemplo anterior). Dentro de cada entrada se deben especificar los parámetros necesarios siguientes:
    • format : especifica el tipo de entrada. Debe ser dense o sparse
    • dim : especifica la dimensión del vector de valor de entrada (para la entrada densa , esto corresponde directamente al número de valores de cada muestra, para dispersión , representa el límite superior en el intervalo de valores de índice posibles).

Los datos de entrada correspondientes a la configuración del lector anterior deben tener un aspecto similar al siguiente:

|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

Tenga en cuenta lo siguiente sobre el formato de entrada:

  • |Input_Name identifica el principio de cada ejemplo de entrada. Este elemento es obligatorio y va seguido del vector de valor correspondiente.
  • Vector denso es simplemente una lista de valores de punto flotante; vector disperso es una lista de index:value tuplas.
  • Tanto las pestañas como los espacios se permiten como delimitadores de valor (dentro de vectores de entrada), así como delimitadores de entrada (entre entradas).
  • Cada línea independiente constituye una "secuencia" de longitud 1 (las secuencias de longitud variable "Real" se explican en el ejemplo extendido siguiente).
  • Cada identificador de entrada solo puede aparecer una vez en una sola línea (lo que se traduce en una muestra por cada requisito de entrada por línea ).
  • El orden de las muestras de entrada dentro de una línea NO es importante (conceptualmente, cada línea es una colección desordenada de pares clave-valor)
  • Cada línea bien formada debe terminar con un símbolo "Avance de línea" \n o "Retorno de carro, Avance de línea \r\n ".

Ejemplo extendido

En este ejemplo se muestran todos los parámetros de configuración posibles y se muestran varias opciones de formato de entrada. Consulte las tablas siguientes para obtener la descripción completa de los parámetros de configuración usados en este ejemplo.

...
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 ...

Con un lector compuesto, le gustaría lo siguiente:

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"}
            }
        })
    }

Después, el archivo de entrada correspondiente puede tener un aspecto aproximado del siguiente:

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

Todas las opciones descritas en el ejemplo anterior se siguen aplicando aquí. Además, presentamos dos características adicionales:

Alias de nombre de entrada

Los nombres de entrada pueden ser arbitrarios largos y, por tanto, repetirlos en todo el archivo de entrada puede no ser eficiente en el espacio. Para mitigar esto, el conjunto de datos puede usar "alias" en lugar de nombres de entrada completos. Los alias deben especificarse en cada subsección de entrada. En nuestro ejemplo, el conjunto de datos usa alias a y b, que se asignan a "Some_very_long_input_name" y "Some_other_also_very_long_input_name" respectivamente en la sección configuración del lector.

Identificadores de secuencia

Como ya se ha mencionado, cada línea independiente del archivo de entrada representa una secuencia que contiene una única muestra para cada entrada. Sin embargo, si una línea tiene como prefijo un número no negativo, el número se usa como identificador de secuencia correspondiente. Todas las líneas posteriores que comparten el mismo identificador de secuencia se combinan para formar parte de la misma secuencia. Por lo tanto, repetir el mismo prefijo numérico para N líneas permite crear una secuencia de varias muestras, con cada entrada que contenga entre 1 y N muestras. Omitir el prefijo de secuencia en la segunda y las líneas siguientes tiene el mismo efecto. Por lo tanto, el conjunto de datos de ejemplo anterior define cinco secuencias con identificadores 100, 200, 333400 y 500.

Al establecer skipSequenceIds el parámetro en la sección truelector en , se fuerza al lector a omitir todos los identificadores de secuencia explícitos del conjunto de datos y tratar líneas independientes como secuencias individuales. Además, omitir el identificador de secuencia en la primera línea del conjunto de datos tiene el mismo efecto: todos los identificadores de secuencia posteriores se omiten, las líneas tratadas como secuencias individuales, como en este ejemplo:

|a 1 2 3 |b 100 200
100 |a 4 5 6 |b 101 201
200 |b 102983 14532 |a 7 8 9

Algunos aspectos finales que se deben tener en cuenta al usar secuencias:

  • Los identificadores de secuencia deben ser únicos.
  • Los prefijos id solo se pueden repetir para líneas consecutivas.
  • La longitud de la secuencia en líneas (es decir, el número de líneas que comparten el mismo prefijo id) no debe superar la longitud máxima de entrada en las muestras (el número de muestras de una entrada) en esta secuencia.

Por ejemplo, los siguientes conjuntos de datos no son válidos:

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

Algunos ejemplos de Real-World

  • Clasificación: cada línea contiene un ejemplo, que consta de una etiqueta y características. No se necesita ningún identificador de secuencia, ya que cada línea es su propia "secuencia" de longitud 1.
|class 23:1 |features 2 3 4 5 6
|class 13:1 |features 1 2 0 2 3
...
  • DSSM: cada línea contiene un par de documentos de destino de origen, expresado a través de un contenedor de palabras, codificado como vectores dispersos.
|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
  • Etiquetado de voz parcial: las secuencias asignan cada elemento a una etiqueta correspondiente. Las secuencias se alinean verticalmente (una palabra + etiqueta por línea).
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
...
  • Clasificación de secuencia: secuencias asignadas a una sola etiqueta. Las secuencias se alinean verticalmente; La etiqueta "class" se puede producir en cualquier línea que tenga el mismo sequenceId.

Nota

En este momento, el número de líneas no debe superar la longitud de la secuencia más larga. Esto significa que la etiqueta no puede aparecer por sí sola en una línea. Se trata de un detalle de implementación que se levantará en el futuro.

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
  • Secuencia a secuencia: asigne una secuencia de origen a una secuencia de destino. Las dos secuencias se alinean verticalmente y, en el caso más sencillo, se imprimen después de otra. Se unen al tener el mismo "id. de secuencia" general (que luego se convierte en un "identificador de unidad de trabajo" en este caso).

Nota

En este momento, el número de líneas no debe superar la longitud de la secuencia más larga. Esto significa que las secuencias deben alinearse horizontalmente. Se trata de un detalle de implementación que se levantará en el futuro.

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 a Rank: una "secuencia" representa una consulta, cada ejemplo de un documento con una clasificación etiquetada a mano. En este caso, la "secuencia" es simplemente un conjunto múltiple que (en el contexto de una función de pérdida de aprendizaje a clasificación) no tiene una ordenación.
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
...

Parámetros de configuración

Parámetro Descripción
precision Especifica la precisión de punto flotante (double o float) de los valores de entrada. Opcional, el valor predeterminado es float.

reader Sección

Parámetro Descripción
readerType Especifica uno de los lectores de CNTK admitidos que se van a cargar (por ejemplo, CNTKTextFormatReader). Requerido.
file Ruta de acceso al archivo que contiene el conjunto de datos de entrada (estilo Windows o Linux). Requerido.
randomize Especifica si la entrada debe ser aleatoria (true, false). Opcional, el valor predeterminado es true.
randomizationSeed Valor inicial de inicialización aleatoria (incrementó cada barrido cuando los datos de entrada se vuelven a aleatorizar). Opcional, el valor predeterminado es 0.
randomizationWindow Especifica el tamaño (entero positivo) de la ventana de selección aleatoria (es decir, intervalo de selección aleatoria). Este parámetro afecta a la cantidad del conjunto de datos que debe residir en la memoria a la vez. Opcional, según el sampleBasedRandomizationWindow valor, el valor predeterminado es el tamaño de todo el conjunto de datos en muestras (es decir, la entrada se aleatoriza en todo el conjunto de datos) o 4 GB de espacio en disco de fragmentos (es decir, 128 cuando el tamaño del fragmento es igual a 32 MB). Este parámetro se omite cuando randomize es false.
sampleBasedRandomizationWindow Si truees , el tamaño de la ventana de selección aleatoria se interpreta como un número determinado de muestras, de lo contrario, como un número de fragmentos. Opcional, el valor predeterminado es false. De forma similar a randomizationWindow, este parámetro se omite cuando randomize es false.
skipSequenceIds Si truees , el lector omitirá los identificadores de secuencia en el archivo de entrada, interpretando cada línea independiente como una secuencia independiente de tamaño 1 (consulte la sección sobre los identificadores de secuencia). Opcional, el valor predeterminado es false.
maxErrors Número de errores de entrada después de los cuales se debe generar una excepción. Opcional, el valor predeterminado es 0, lo que significa que el primer valor con formato incorrecto desencadenará una excepción.
traceLevel Nivel de detalle de salida. 0 - mostrar solo errores; 1 - mostrar errores y advertencias; 2 : muestra toda la salida. Opcional, el valor predeterminado es 1.
chunkSizeInBytes Número de bytes consecutivos que se van a leer desde el disco en una sola operación de lectura. Opcional, el valor predeterminado es 33554432 (32 MB).
keepDataInMemory Si truees , todo el conjunto de datos se almacenará en caché en la memoria. Opcional, el valor predeterminado es false.
frameMode true indica al lector que use un método de empaquetado optimizado para fotogramas (secuencias que contienen solo una sola muestra). Opcional, el valor predeterminado es false.
cacheIndex Especifica si los metadatos creados durante la fase de preprocesamiento deben escribirse en el disco y cargarse desde el disco si están disponibles (true, false). Opcional, el valor predeterminado es false. Para más información, consulte la sección siguiente. Novedad de CNTK versión 2.1.
Almacenamiento en caché de índices

Nota

Novedad de CNTK versión 2.1.

El almacenamiento en caché de índices permite reducir significativamente (por un factor de 2 a 3 veces) los tiempos de inicio, especialmente cuando se trabaja con archivos de entrada grandes. Al establecer la cacheIndex marca en true , se indicará al lector que escriba los metadatos de indexación en el disco (el mismo directorio que el archivo de entrada) si el archivo de caché no está disponible o si está obsoleto (anterior al archivo de entrada). La escritura es el mejor esfuerzo y se lleva a cabo en un subproceso independiente para no afectar al rendimiento del lector. Si el archivo de caché está presente y está actualizado, el lector dejará de esquiar el archivo de entrada para compilar el índice; en su lugar, cargará el índice desde el archivo de caché. Tenga en cuenta que determinados parámetros de configuración del lector tienen un impacto directo en la indexación (por ejemplo, los distintos valores de frameMode podrían dar lugar a índices que tienen un número diferente de secuencias). Por ese motivo, un lector podría omitir un archivo de caché con una configuración diferente de la que generó la memoria caché. Para ver la ventaja completa del almacenamiento en caché, la configuración no debe modificarse en las repeticiones posteriores.

input subsección

input combina una serie de entradas individuales, cada una con una subsección de configuración etiquetada correctamente. Todos los parámetros descritos a continuación son específicos de una subsección nombre de entrada asociada a una entrada determinada.

Parámetro Descripción
alias Un nombre abreviado alternativo (cadena) que se usa para identificar la entrada en el conjunto de datos. Opcional
format Especifica el tipo de entrada (dense, sparse). Requerido.
dim Dimensión (entero positivo) del valor de entrada (es decir, el número de valores de entrada de una muestra para la entrada densa , el límite superior del intervalo de índice para la entrada dispersa ). Requerido.
definesMBSize Marca (valor predeterminado false), que indica si el tamaño de minibatch debe contarse en muestras de esta secuencia determinada Opcional.

Encontrará definiciones de red completas y los ejemplos de conjuntos de datos correspondientes en el repositorio de CNTK. Allí también encontrará una prueba de un extremo a otro que usa el lector CNTKTextFormat.