Compartilhar via


Leitor brainscript HTKMLF

Aviso

HTKMLFReader é obsoleto e está sendo substituído por HTK MLF e desserializadores de recursos, cf. Noções básicas e estendendo leitores. Use-os para suas redes.

HTKMLFReader é um leitor de dados que lê arquivos normalmente associados a tarefas de reconhecimento de fala e especificamente com o conjunto de ferramentas HTK (Hidden Markov Model Toolkit). O leitor pode usar como entrada dois tipos de arquivos, uma lista de arquivos de recursos conhecidos na linguagem HTK como um scp arquivo (arquivo "script"), um arquivo de rótulo conhecido como mlf arquivo ("arquivo de rótulo de modelo") e um arquivo de arquivo de arquivo.

O HTKMLFReader depende de formatos definidos por HTK de conjuntos de dados, portanto, recomendamos nos familiarizar com as noções básicas do HTK usando, por exemplo, o HTK Book.

Como CNTK pode ser usado para criar redes com topologia arbitrária, incluindo redes com várias entradas e saídas, o HTKMLFReader pode processar um ou vários scpMLF arquivos. Um exemplo típico de uso para o HTKMLFReader é o seguinte:

    reader = [
        readerType = "HTKMLFReader"
        readMethod = "blockRandomize"
        miniBatchMode = "partial"
        randomize = "17280000"
        features = [
            dim = 792
            scpFile = "$ScpDir$\TIMIT.train.scp.fbank.fullpath"
        ]
        labels = [
            mlfFile = "$MlfDir$\TIMIT.train.align_cistate.mlf.cntk"
            labelDim = 183
            labelMappingFile = "$MlfDir$\TIMIT.statelist"
        ]
    ]

O HTKMLFReader tem os seguintes parâmetros de configuração:

  • readMethod: o método usado para ler os arquivos de recursos na memória para processamento durante o treinamento de rede. A configuração readMethod para blockRandomize dividir os dados em blocos grandes e, em seguida, randomizar a ordem dos blocos e, em seguida, a ordem dos dados dentro do bloco. Os dados em cada bloco são lidos diretamente dos arquivos de recurso e liberados da RAM quando não são mais usados. A opção blockRandomize requer um arquivo de arquivo morto, descrito abaixo. Além disso, conforme descrito abaixo, quando usado em conjunto com frameMode = "false" o blockRandomize método de leitura será randomizado em enunciados, mas não em quadros. Isso é apropriado para uso com arquiteturas recorrentes ao preservar a natureza sequencial dos exemplos de treinamento desejados. Uma alternativa é rollingWindow , que lê em todos os arquivos de recursos e os armazena em disco em um arquivo binário temporário grande. Em seguida, os dados são randomizados executando uma grande janela de rolagem sobre os dados neste arquivo e randomizando os dados dentro da janela. Esse método só deve ser usado quando um arquivo de arquivo morto não está disponível e só funciona no modo de quadro. O método padrão é blockRandomize.

  • pageFilePath: especifique onde o arquivo de página temporário dos recursos deve ser armazenado. Por padrão, ele usará o arquivo temporário fornecido pelo sistema.

  • randomize: especifica o tamanho da janela de randomização. CNTK usa uma janela sem interrupção desse tamanho sobre os dados a serem amostrado. Somente os exemplos dentro dessa janela sem interrupção são carregados do disco e mantidos na RAM apenas o tempo necessário. A configuração recomendada para corporação de fala em tamanho de produção é de 48 horas, ou seja, especificar 17280000. O randomize parâmetro também entende dois valores especiais: auto ou none. none desabilita completamente a randomização, útil para avaliar ou gravar dados de saída. auto lerá todo o corpus em RAM, o que normalmente não é viável ou desejável para conjuntos de dados de tamanho de produção de milhares de horas de fala.

  • minibatchMode: partial ou full, essa opção decide como lidar com a última minibatch se não houver quadros suficientes para formar uma minibatch completa do tamanho solicitado. O padrão é partial, que usará os quadros restantes em uma minibatch final menor da época de treinamento. A full opção processará apenas minibatches completos.

O exemplo acima tem duas fontes de dados sendo processadas pelo leitor, recursos, na forma de uma lista de arquivos de recursos HTK e rótulos, que estão na forma de um arquivo MLF HTK. Os recursos e os rótulos correspondem a nós na rede computacional, nesse caso, os nós de entrada e saída, respectivamente. Observe que features e labels são os nomes padrão usados pelo SimpleNetworkBuilder, mas se a rede for projetada usando a NDL (Linguagem de Descrição de Rede), todos os nomes poderão ser usados, desde que cada um deles tenha um nó correspondente na rede.

Para especificar recursos com valor contínuo, por exemplo, coeficientes do banco de filtros MFCC ou do log mel, os seguintes parâmetros devem ser incluídos em um bloco de configuração:

  • scpFile: uma lista de arquivos a serem processados. Os arquivos devem ser arquivos compatíveis com HTK e podem ser especificados no formato padrão ou "archive". Os detalhes do uso de um arquivo morto são descritos abaixo.

  • dim: um inteiro que especifica a dimensão completa do vetor do recurso com a janela de contexto desejada. Por exemplo, se você tiver recursos dimensionais 72 (recursos do banco de filtros 24 dimensões mais coeficientes delta e delta) e a rede for projetada para processar uma janela de contexto de 11 quadros, a dimensão especificada deverá ser 792. Observe que há suporte apenas para janelas de contexto simétrico.

Para especificar os rótulos correspondentes, por exemplo, rótulos phoneme ou senone, um bloco de configuração deve ser usado que especifica os seguintes parâmetros:

  • mlfFile: um arquivo no estilo mlf HTK que contém os rótulos de todos os enunciados especificados no scp arquivo.

  • labelDim: a cardinalidade total do conjunto de rótulos.

  • labelMappingFile: o caminho para um arquivo que lista todos os rótulos vistos no mlf arquivo, um por linha.

Observe que várias entradas e saídas podem ser especificadas usando blocos de leitor adicionais para recursos lidos de arquivos listados em um scp arquivo ou rótulos lidos de um mlf arquivo. Por exemplo, em um cenário de aprendizado de várias tarefas, em que a rede estava prevendo a identidade do locutor e o rótulo senone, o usuário especificaria um bloco adicional que inclui um mlf arquivo que contém rótulos correspondentes sobre a identidade do locutor. Da mesma forma, para uma rede com várias entradas, por exemplo, recursos MFCC e PLP, um bloco de recursos adicional seria usado.

Para estruturas recorrentes, como um RNN ou um LSTM, há opções de configuração adicionais no HTKMLFReader

  • frameMode: true ou false, se o leitor deve randomizar os dados no nível do quadro ou no nível de enunciado. A true configuração frameMode é o padrão e é apropriada para redes de treinamento sem conexões temporais. Para redes projetadas para aprender informações sequenciais, por exemplo, RNN, frameMode devem ser definidas como false, o que significa que os enunciados são aleatórios, mas a sequência adequada é mantida em um enunciado. Observe que isso só funciona com o blockRandomize método de leitura.

  • nbruttsineachrecurrentiter: especifica o número de enunciados a serem processados em conjunto para treinamento eficiente de redes com estruturas recorrentes. O padrão é 1, mas qualquer valor abaixo de 20 a 30 levará a degradações significativas de eficiência com GPUs.

  • truncated: true ou false. Isso habilita o BPTT truncado.

É importante observar que há algumas pequenas diferenças entre o padrão scp e mlf os arquivos usados no HTK e os usados em CNTK.

Mais notavelmente, o mlf arquivo deve conter os símbolos reais usados para classificação. Para o reconhecimento contínuo de fala, isso normalmente significa rótulos correspondentes aos sinônimos (physicalHMMstates). No entanto, o HVite normalmente gera um mlf alinhamento forçado durante o qual inclui apenas os nomes de estado lógicos do HMM. Portanto, para usá-lo mlf em CNTK, deve mlf ser pós-processado para substituir os nomes de estado lógico por os rótulos senone correspondentes ou o HVite deve ser modificado para que ele grave os rótulos senone diretamente.

Os scp arquivos processados pelo HTKMLFReader podem ser uma das duas variedades: o formato padrão, em que cada linha corresponde a um arquivo de recurso físico ou o formato aliased, em que cada linha contém um nome lógico e se refere a um segmento de um arquivo físico possivelmente maior, definido por quadros de início e de fim. O nome lógico é usado para identificar os rótulos correspondentes no mlf arquivo. Mesmo que os arquivos sejam armazenados individualmente, como no primeiro caso, o formato aliased deve ser sempre usado com o blockRandomize método de leitura, pois ele usa as informações sobre os quadros inicial e final no scp arquivo para determinar os comprimentos de enunciado sem precisar abrir os próprios arquivos. Nesse caso, o quadro inicial deve ser 0 e o quadro final deve ser igual ao comprimento do enunciado menos 1. Além disso, para várias entradas e/ou saídas, o formato aliased também deve ser usado para que todos os scp arquivos e mlf arquivos tenham seus nomes lógicos em comum. Se o rollingWindow método de leitura for usado em vez de, as informações de blockRandomizequadro inicial e final poderão ser omitidas.

Aqui estão exemplos de snippets e scpmlf arquivos para o corpus TIMIT para apropriado para uma rede com 2 entradas de recurso (nesse caso, recursos MFCC e PLP) e 1 saída correspondente aos estados de phoneme.

O scp arquivo lista todos os arquivos a serem processados, usando essa sintaxe:

id=pathname

Uma extensão proprietária CNTK desse formato (que não é encontrada no HTK original) é que CNTK permite uma sintaxe de nome de caminho relativo mais conveniente quando o scp arquivo está localizado ao lado dos recursos:

id=.../filename

em que ... se refere ao diretório do scp arquivo.

O scp arquivo para os recursos do MFCC contém entradas como essas.

train-dr1-fcjf0-si1027.mfc=//hostname/data/TIMIT/mfc/train/dr1/fcjf0/train-dr1-fcjf0-si1027.mfc[0,306]

train-dr1-fcjf0-si1657.mfc=//hostname/data/TIMIT/mfc/train/dr1/fcjf0/train-dr1-fcjf0-si1657.mfc[0,281]

train-dr1-fcjf0-si648.mfc=//hostname/data/TIMIT/mfc/train/dr1/fcjf0/train-dr1-fcjf0-si648.mfc[0,359]

O scp arquivo para os recursos PLP é semelhante, mas aponta para arquivos físicos diferentes. Observe que o nome raiz lógico em ambos os scp arquivos é o mesmo.

train-dr1-fcjf0-si1027.plp=//hostname/data/TIMIT/plp/train/dr1/fcjf0/train-dr1-fcjf0-si1027. plp[0,306]

train-dr1-fcjf0-si1657.plp=//hostname/data/TIMIT/plp/train/dr1/fcjf0/train-dr1-fcjf0-si1657. plp[0,281]

train-dr1-fcjf0-si648.plp=//hostname/data/TIMIT/plp/train/dr1/fcjf0/train-dr1-fcjf0-si648.plp [0,359]

Um mlf arquivo lista os rótulos, usando essa sintaxe:

#!MLF!#
"id"
labelBegin1 labelEnd1 label1
labelBegin2 labelEnd2 label1

...

.
"id"
labelBegin1 labelEnd1 label1
labelBegin2 labelEnd2 label1

...

.

...

Aqui, temos uma seção terminada com . (ponto) por cada arquivo de entrada e uma linha por token em cada seção. Os tempos de rótulo são fornecidos em uma base de tempo de 10e-7, e os quadros de fala são normalmente 10e-2, portanto , 5 zeros são necessários para acrescentar a cada índice de tempo.

É importante observar que CNTK lê apenas as três primeiras colunas* dentro de uma seção de um mlp arquivo e ignora o restante. Em nosso arquivo de exemplo mlf , também compartilha o nome lógico com ambos os arquivos ''scp''. Aqui está o snippet:

#!MLF!#
"train-dr1-fcjf0-si1027.rec"
0 200000 h#_s2 -136.655975 h# -589.680481 h#
200000 400000 h#_s3 -145.780716
400000 800000 h#_s4 -307.243774
800000 1200000 q_s2 -349.529327 q -897.429504 q
1200000 1500000 q_s3 -280.568817
1500000 1800000 q_s4 -267.331390
1800000 1900000 iy_s2 -76.825096 iy -673.892883 iy
1900000 2400000 iy_s3 -305.832458
2400000 2800000 iy_s4 -291.235352

Agora, descreveremos arquivos de arquivo morto, que às vezes também são conhecidos como chunk arquivos. CNTK usa um conceito de parte para todos os seus Leitores, e isso significa uma coisa absolutamente diferente, portanto, para evitar a confusão, não usamos a parte do termo em relação aos arquivos descritos abaixo, mas sim chamá-los de Arquivos.

Arquivos de arquivos de arquivo são basicamente matrizes principais de coluna, float32com um cabeçalho de 12 bytes que contém o tamanho da amostra e o número de amostras. Geralmente, eles são mais fáceis de usar, especialmente como um começo. O cabeçalho esperado do arquivo é definido por meio do struct seguinte:

struct fileheader
{
    int nsamples;
    int sampperiod;
    short sampsize;
    short sampkind;
}

em que:

  • sampsize é o tamanho de um vetor em bytes (=4 * feature dimension);
  • sampkind é um identificador numérico do tipo de recurso (MFCC, PLP etc.). CNTK ignora isso. Se os arquivos não forem criados pelo HTK, basta definir isso como 9 (USUÁRIO). And
  • sampperioddeve ser 100000 (CNTK ignora principalmente esse valor, exceto possivelmente para mensagens de erro).

Por fim, é importante observar que, na maioria dos aplicativos de reconhecimento de fala, os recursos com valor contínuo são usados como entradas enquanto rótulos categóricos discretos são usados como a saída. No entanto, o HTKMLFReader apenas associa os dados aos nomes dos nós e é independente de como esses dados são usados. Por exemplo, um arquivo apropriado mlf de rótulos de identidade do locutor pode ser usado para gerar um vetor único dos recursos de identidade do locutor como uma entrada para a rede.