Поделиться через


Средство чтения текстового формата CNTK BrainScript

На этой странице документируется CNTKTextFormatReader с точки зрения BrainScript, но Python пользователи могут узнать, прочитав этот документ, а также основные понятия, параметры и шаблоны.

CNTKTextFormatReader (позже просто средство чтения CTF) предназначено для использования входных текстовых данных, отформатированных в соответствии со спецификацией ниже. Он поддерживает следующие основные функции:

  • Несколько входных потоков (входных данных) на файл
  • Разреженные и плотные входные данные
  • Последовательности переменной длины

текстовый формат CNTK (CTF)

Каждая строка во входном файле содержит один пример для одного или нескольких входных данных. Так как (явно или неявно) каждая строка также присоединяется к последовательности, она определяет одну или несколько <последовательностей, входных данных, примеров> связей. Каждая входная строка должна быть отформатирована следующим образом:

[Sequence_Id](Sample or Comment)+

where

Sample=|Input_Name (Value )*

Comment=|# some content

  • Каждая строка начинается с идентификатора последовательности и содержит один или несколько примеров (другими словами, каждая строка представляет собой неупорядоченную коллекцию примеров).
  • Идентификатор последовательности — это число. Его можно опустить, в этом случае номер строки будет использоваться в качестве идентификатора последовательности.
  • Каждый пример фактически представляет собой пару "ключ-значение", состоящую из входного имени и соответствующего вектора значений (сопоставление с более высокими измерениями выполняется как часть самой сети).
  • Каждый пример начинается с символа канала (|), за которым следует входное имя (без пробелов), за которым следует разделитель пробелов, а затем список значений.
  • Каждое значение — это число или число с префиксом индекса для разреженных входных данных.
  • Как вкладки, так и пробелы можно использовать в качестве разделителей.
  • Комментарий начинается с канала, за которым сразу следует хэш-символ: |#а затем — фактические содержимое (текст) комментария. Текст может содержать любые символы, однако символ канала внутри тела должен быть экранирован путем добавления к нему хэш-символа (см. пример ниже). Текст комментария продолжается до конца строки или следующей неисключаемой трубы, в зависимости от того, что происходит первым.

Простой пример

Этот пример основан на минимальном наборе параметров и параметров формата.

Чтобы использовать средство чтения CTF, задайте значение readerTypeCNTKTextFormatReader в разделе чтения конфигурации 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 ...

(Этот фрагмент, а также другие примеры NDL в этом документе содержат только reader раздел, опустив остальную часть конфигурации CNTK; в конце этой страницы приведены указатели на набор полных примеров сетей и соответствующих наборов данных).

Для чтения CTF требуется следующий набор параметров:

  • file — путь к файлу с набором данных.
  • input— подраздел, определяющий входные данные, определяемые именами входных данных (ABи C в приведенном выше примере). В каждом входе необходимо указать следующие обязательные параметры:
    • format — указывает тип входных данных. Должен быть или densesparse
    • dim — задает измерение вектора входных значений (для плотных входных данных это напрямую соответствует количеству значений в каждом образце, для разреженности это представляет верхнюю границу диапазона возможных значений индекса).

Входные данные, соответствующие приведенной выше конфигурации чтения, должны выглядеть примерно так:

|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

Обратите внимание на следующее о формате ввода:

  • |Input_Name идентифицирует начало каждого входного образца. Этот элемент является обязательным и за ним следует вектор значения корреспондента.
  • Плотный вектор — это просто список значений с плавающей запятой; Разреженный вектор — это список кортежей index:value .
  • Вкладки и пробелы могут быть разделителями значений (в векторах ввода), а также разделителями входных данных (между входными данными).
  • Каждая отдельная строка представляет собой "последовательность" длиной 1 (последовательности с переменной длиной real описаны в расширенном примере ниже).
  • Каждый входной идентификатор может отображаться только один раз в одной строке (что преобразуется в один образец на входные данные для каждой строки ).
  • Порядок входных выборок в строке не важен (концептуально каждая строка является неупорядоченной коллекцией пар "ключ-значение")
  • Каждая хорошо сформированная строка должна заканчиваться символами "Строка веб-канала" \n или "Возврат каретки, канал строки". \r\n

Расширенный пример

В этом примере представлены все возможные параметры конфигурации и показаны различные параметры входного формата. Полный описание параметров конфигурации, используемых в этом примере, см. в таблицах ниже .

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

При использовании составного средства чтения он будет выглядеть следующим образом:

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

Затем соответствующий входной файл может выглядеть примерно следующим образом:

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

Все варианты, описанные в приведенном выше примере, по-прежнему применяются здесь. Кроме того, мы представили два дополнительных компонента:

Псевдонимы входных имен

Имена входных данных могут быть произвольными, поэтому повторять их во входном файле может быть недостаточно места. Чтобы устранить эту проблему, набор данных может использовать псевдонимы вместо полных входных имен. Затем псевдонимы необходимо указать в каждом входном подразделе. В нашем примере набор данных использует псевдонимы a и b, которые сопоставляются с "Some_very_long_input_name" и "Some_other_also_very_long_input_name" соответственно в разделе конфигурации средства чтения.

Идентификаторы последовательностей

Как уже упоминалось, каждая отдельная строка во входном файле представляет последовательность , содержащую один образец для каждого входного ввода. Однако если строка имеет префикс неотрицательное число, оно используется в качестве соответствующего идентификатора последовательности. Все последующие строки с одинаковым идентификатором последовательности объединяются, чтобы стать частью одной последовательности. Таким образом, повторение одного и того же числового префикса для N строк позволяет создать последовательность с несколькими выборками с каждым входным значением, содержащим от 1 до N выборок. Пропуск префикса последовательности во второй и следующих строках имеет одинаковый эффект. Таким образом, приведенный выше пример набора данных определяет пять последовательностей с идентификаторами100, , 200и 500333400 .

Установка skipSequenceIds параметра в разделе true"Читатель" заставляет читателя игнорировать все явные идентификаторы последовательности в наборе данных и обрабатывать отдельные строки как отдельные последовательности. Кроме того, пропуск идентификатора последовательности в первой строке набора данных имеет тот же эффект. Все последующие идентификаторы последовательности игнорируются, строки обрабатываются как отдельные последовательности, как в следующем примере:

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

Некоторые окончательные моменты, которые следует учитывать при использовании последовательностей:

  • Идентификаторы последовательности должны быть уникальными.
  • Префиксы идентификаторов могут повторяться только для последовательных строк.
  • Длина последовательности в строках (т. е. количество строк с одинаковым префиксом идентификатора) не должно превышать максимальную длину входных данных в примерах (количество выборок во входных данных) в этой последовательности.

Например, следующие наборы данных недопустимы:

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

Несколько примеров Real-World

  • Классификация: каждая строка содержит образец, состоящий из метки и признаков. Идентификатор последовательности не нужен, так как каждая строка имеет собственную "последовательность" длины 1.
|class 23:1 |features 2 3 4 5 6
|class 13:1 |features 1 2 0 2 3
...
  • DSSM: каждая строка содержит пару исходного документа, выраженную с помощью мешка слов, закодированную как разреженные векторы.
|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
  • Добавление тегов в части речи: последовательности сопоставляют каждый элемент с соответствующей меткой. Последовательности выравниваются по вертикали (по одному слову + тегу на строку).
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
...
  • Классификация последовательностей: последовательности, сопоставленные с одной меткой. Последовательности выравниваются по вертикали; Метка "class" может находиться в любой строке с одинаковым идентификатором sequenceId.

Примечание

На данный момент количество строк не должно превышать длину самой длинной последовательности. Это означает, что метка не может отображаться в строке самостоятельно. Это подробное описание реализации, которое будет отменено в будущем.

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
  • Последовательность для последовательности: сопоставление исходной последовательности с целевой последовательностью. Две последовательности выравниваются по вертикали и, в самом простом случае, просто печатаются после другой. К ним присоединяется тот же общий идентификатор последовательности (который в данном случае становится идентификатором единицы работы).

Примечание

На данный момент количество строк не должно превышать длину самой длинной последовательности. Это означает, что последовательности должны быть выровнены по горизонтали. Это подробное описание реализации, которое будет отменено в будущем.

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
...
  • Обучение ранга: "последовательность" представляет запрос, каждый пример документа с ручной оценкой. В этом случае "последовательность" — это просто мультинабор, который (в контексте функции потери ранга в обучении) не имеет упорядочения.
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
...

Параметры конфигурации

Параметр Описание
precision Указывает точность с плавающей запятой (double или float) входных значений. Необязательный, по умолчанию — float.

Раздел reader

Параметр Описание
readerType Указывает один из поддерживаемых модулей чтения CNTK для загрузки (например, CNTKTextFormatReader). Обязательно.
file Путь к файлу, содержаму входной набор данных (Windows или стиль Linux). Обязательно.
randomize Указывает, следует ли рандомизировать входные данные (true, false). Необязательный, по умолчанию — true.
randomizationSeed Начальное начальное значение рандомизации (увеличивается при повторной случайности входных данных). Необязательный, по умолчанию — 0.
randomizationWindow Задает размер (положительное целое число) окна случайной выборки (т. е. диапазон случайных значений). Этот параметр влияет на то, сколько набор данных должен находиться в памяти одновременно. Необязательный, в зависимости от sampleBasedRandomizationWindow значения, по умолчанию используется размер всего набора данных в примерах (т. е. входные данные случайным образом в целом наборе данных) или 4 ГБ дискового пространства, равного фрагментам (т 128 . е. если размер блока равен 32 МБ). Этот параметр игнорируется при randomize значении false.
sampleBasedRandomizationWindow Если trueразмер окна случайной выборки интерпретируется как определенное количество выборок, в противном случае — как число фрагментов. Необязательный, по умолчанию — false. Аналогично этому параметру randomizationWindowигнорируется, когда randomize он имеет значение false.
skipSequenceIds Если trueмодуль чтения игнорирует идентификаторы последовательности во входном файле, интерпретируя каждую отдельную строку как независимую последовательность размером 1 (см. раздел идентификаторов последовательности). Необязательный, по умолчанию — false.
maxErrors Количество входных ошибок, после которых должно возникать исключение. Необязательный, по умолчанию используется 0, что означает, что первое неправильно сформированное значение приведет к возникновению исключения.
traceLevel Уровень детализации выходных данных. 0 — отображение только ошибок; 1 — отображение ошибок и предупреждений; 2 — отображение всех выходных данных. Необязательный, по умолчанию — 1.
chunkSizeInBytes Число последовательных байтов для чтения с диска в одной операции чтения. Необязательный, по умолчанию 33554432 — 32 МБ.
keepDataInMemory Если trueвесь набор данных будет кэширован в памяти. Необязательный, по умолчанию — false.
frameMode true сигнализирует средству чтения использовать метод упаковки, оптимизированный для кадров (последовательности, содержащие только один образец). Необязательный, по умолчанию — false.
cacheIndex Указывает, должны ли метаданные, созданные на этапе предварительной обработки, записываться на диск и загружаться с диска, если они доступны (true, false). Необязательный, по умолчанию — false. Дополнительные сведения см. в разделе ниже. Новые возможности в CNTK версии 2.1.
Кэширование индекса

Примечание

Новые возможности в CNTK версии 2.1.

Кэширование индексов позволяет значительно (с коэффициентом 2–3x) сократить время запуска, особенно при работе с большими входными файлами. cacheIndex Если флаг будет сигнализировать читателю true записать метаданные индексирования на диск (тот же каталог, что и входной файл), если файл кэша недоступен или если он устарел (старше входного файла). Написание является лучшим усилием и выполняется в отдельном потоке, чтобы не повлиять на производительность средства чтения. Если файл кэша присутствует и обновлен, средство чтения больше не будет пропускать входной файл для сборки индекса, вместо этого он загрузит индекс из файла кэша. Обратите внимание, что некоторые параметры конфигурации читателя оказывают непосредственное влияние на индексирование (например, различные значения frameMode могут привести к индексам с разными числами последовательностей). По этой причине файл кэша может игнорироваться средством чтения с конфигурацией, отличной от конфигурации, которая произвела кэш. Чтобы увидеть полное преимущество кэширования, конфигурация не должна быть изменена при последующих повторных запусках.

input вложенный раздел

input объединяет несколько отдельных входных данных, каждый из которых имеет соответствующую метку подсечения конфигурации. Все описанные ниже параметры относятся к подразделу "Входное имя ", связанному с определенными входными данными.

Параметр Описание
alias Альтернативное сокращенное имя (строка), используемое для идентификации входных данных в наборе данных. Необязательно
format Указывает тип входных данных (dense, sparse). Обязательно.
dim Измерение (положительное целое число) входного значения (т. е. количество входных значений в образце для плотного ввода, верхняя граница диапазона индекса для разреженных входных данных). Обязательно.
definesMBSize Флаг (по умолчанию false), указывающий, следует ли учитывать размер мини-пакета в примерах из данного конкретного потока Необязательный.

Полные определения сети и соответствующие примеры набора данных находятся в репозитории CNTK. Там вы также найдете сквозной тест , использующий средство чтения CNTKTextFormat.