Partilhar via


Leitor HTKMLF BrainScript

Aviso

O HTKMLFReader é obsoleto e está a ser substituído por HTK MLF e deserializadores de recurso, cf. Compreensão e Alargamento dos Leitores. Por favor, use-os para as suas redes.

HTKMLFReader é um leitor de dados que lê ficheiros tipicamente associados a tarefas de reconhecimento de voz, e especificamente com o conjunto de ferramentas do Modelo Markov (HTK) escondido . O leitor pode tomar como entrada dois tipos de ficheiros, uma lista de ficheiros de funcionalidades conhecidos na linguagem HTK como um scp ficheiro ("script"), um ficheiro de etiqueta conhecido como mlf ficheiro ("modelo ficheiro de etiqueta") e um ficheiro de arquivo.

O HTKMLFReader baseia-se em formatos definidos HTK de conjuntos de dados, pelo que recomendamos que se familiarize com os básicos do HTK utilizando, por exemplo, o Livro HTK.

Como CNTK pode ser usado para construir redes com topologia arbitrária, incluindo redes com múltiplas entradas e saídas, o HTKMLFReader pode processar um ou vários scp ficheiros.MLF Um exemplo típico de utilização 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 utilizado para ler os ficheiros de características na memória para processamento durante o treino em rede. Configurar readMethod para blockRandomize dividir os dados em blocos grandes e, em seguida, aleatoriamente a ordem dos blocos e, em seguida, a ordem dos dados dentro do bloco. Os dados em cada bloco são lidos diretamente a partir dos ficheiros de funcionalidades, e libertados da RAM quando já não são utilizados. A blockRandomize opção requer um ficheiro de arquivo, descrito abaixo. Além disso, como descrito abaixo, quando usado em conjunto com frameMode = "false" o método de blockRandomize leitura irá aleatoriamente ao longo de expressões, mas não quadros. Isto é adequado para ser utilizado com arquiteturas recorrentes na preservação da natureza sequencial dos exemplos de formação. Uma alternativa é rollingWindow , que lê em todos os ficheiros de funcionalidades e os armazena em disco num grande ficheiro binário temporário. Os dados são então aleatórios executando uma grande janela rolante sobre os dados neste ficheiro e aleatoriamente os dados dentro da janela. Este método só deve ser utilizado quando um ficheiro de arquivo não estiver disponível e funcionar apenas no modo de fotogramas. O método padrão é blockRandomize.

  • pageFilePath: especificar onde deve ser armazenado o ficheiro de página temporária das funcionalidades. Por predefinição, utilizará o sistema fornecido com ficheiro temporário.

  • randomize: Isto especifica o tamanho da janela de aleatoriedade. CNTK usa uma janela rolante deste tamanho sobre os dados para amostrar. Apenas as amostras dentro desta janela rolante são carregadas do disco e mantidas em RAM apenas o tempo necessário. A definição recomendada para a linguagem corpora de tamanho de produção é de 48 horas, ou seja, especificar 17280000. O randomize parâmetro também compreende dois valores especiais: auto ou none. none desativa completamente a aleatoriedade, útil para avaliação ou escrita de 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 em tamanho de produção de vários milhares de horas de discurso.

  • minibatchMode: partial ou full, esta 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 treino. A full opção só irá processar minibatches completos.

O exemplo acima tem duas fontes de dados sendo processadas pelo leitor, funcionalidades, sob a forma de uma lista de ficheiros de recurso HTK, e etiquetas, que são sob a forma de um ficheiro HTK MLF. Tanto as características como as etiquetas correspondem a nós na rede computacional, neste caso, os nós de entrada e saída, respectivamente. Note que features e labels são os nomes predefinidos utilizados pelo SimpleNetworkBuilder mas se a rede for concebida utilizando o Language de Descrição da Rede (NDL), então quaisquer nomes podem ser utilizados, desde que cada um deles tenha um nó correspondente na rede.

Para especificar as características de valor contínuo, por exemplo, coeficientes de filtros de MFCC ou de log mel, os seguintes parâmetros devem ser incluídos no bloco de configuração:

  • scpFile: uma lista de ficheiros a processar. Os ficheiros devem ser ficheiros compatíveis com HTK e podem ser especificados em formato padrão ou em formato "arquivo". Os detalhes da utilização de um arquivo são descritos abaixo.

  • dim: um número inteiro que especifica a dimensão vetorial de característica completa com a janela de contexto desejada. Por exemplo, se tivesse características 72-dimensional (características de filterbank 24-dimensional mais coeficientes delta e delta-delta) e a rede foi concebida para processar uma janela de contexto de 11 quadros, a dimensão especificada deve ser de 792. Note que apenas as janelas de contexto simétricas são suportadas.

Para especificar as etiquetas correspondentes, por exemplo, etiquetas de telefone ou senone, deve ser utilizado um bloco de configuração que especifique os seguintes parâmetros:

  • mlfFile: um ficheiro de estilo mlf HTK que contém as etiquetas para todas as expressões especificadas no scp ficheiro.

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

  • labelMappingFile: o caminho para um ficheiro que lista todas as etiquetas vistas no mlf ficheiro, uma por linha.

Note que várias entradas e saídas podem ser especificadas usando blocos de leitores adicionais para ambas as funcionalidades lidas a partir de ficheiros listados num scp ficheiro ou etiquetas lidas a partir de um mlf ficheiro. Por exemplo, num cenário de aprendizagem multi-tarefas, onde a rede estava a prever a identidade dos altifalantes e a etiqueta senone, o utilizador especificaria um bloco adicional que inclui um mlf ficheiro que contém etiquetas correspondentes à identidade do altifalante. Da mesma forma, para uma rede com múltiplas entradas, por exemplo, tanto as funcionalidades MFCC como PLP, seria utilizado um bloco de funcionalidades adicional.

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

  • frameMode: true ou false, se o leitor deve aleatoriamente os dados ao nível da moldura ou o nível de expressão. true A definição frameMode é o padrão e é apropriado para redes de treino sem qualquer ligação temporal. Para as redes que são projetadas para aprender informações sequenciais, por exemplo, RNN, frameMode devem ser definidas para false, o que significa que as expressões são aleatórias, mas a sequência adequada é mantida dentro de uma expressão. Note que isto só funciona com o método de blockRandomize leitura.

  • nbruttsineachrecurrentiter: especifica o número de expressões a processar em conjunto para uma formação 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. Isto permite o BPTT truncado.

É importante notar que existem algumas pequenas diferenças entre a norma scp e mlf os ficheiros utilizados no HTK e os utilizados em CNTK.

Mais notavelmente, o mlf ficheiro deve conter os símbolos reais utilizados para a classificação. Para reconhecimento contínuo da fala, isto significa tipicamente rótulos correspondentes aos senones (estados físicosHMM). No entanto, o HVite normalmente gera um mlf alinhamento forçado que inclui apenas os nomes de estado hmm lógicos. Assim, para usá-lo mlf em CNTK, ou deve ser processado após o mlf processo para substituir os nomes de estado lógico por etiquetas senone correspondentes, ou HVite deve ser modificado de modo a que escreva diretamente as etiquetas senone.

Os scp ficheiros processados pelo HTKMLFReader podem ser uma de duas variedades: ou o formato padrão, onde cada linha corresponde a um ficheiro de recurso físico, ou o formato pseudónimo, onde cada linha contém um nome lógico e se refere a um segmento de um ficheiro físico possivelmente maior, definido por quadros de início e fim. O nome lógico é usado para identificar as etiquetas correspondentes no mlf ficheiro. Mesmo que os ficheiros sejam armazenados individualmente, como no primeiro caso, o formato aliased deve ser sempre utilizado com o blockRandomize método de leitura, uma vez que utiliza as informações sobre os quadros iniciais e finais no scp ficheiro para determinar os comprimentos de expressão sem ter de abrir os próprios ficheiros. Neste caso, o quadro de partida deve ser 0 e o quadro final deve ser igual ao comprimento da expressão menos 1. Além disso, para múltiplas entradas e/ou saídas, o formato aliased também deve ser usado para que todos os scp ficheiros e mlf ficheiros tenham os seus nomes lógicos em comum. Se o rollingWindow método de leitura for utilizado em vez de blockRandomize, então as informações de partida e de final de quadro podem ser omitidas.

Aqui estão exemplo snippets e mlf ficheiros scp para o corpus TIMIT para apropriado para uma rede com 2 entradas de recurso (neste caso, funcionalidades MFCC e PLP) e 1 saída correspondente aos estados do fonme.

O scp ficheiro lista todos os ficheiros que processa, utilizando esta sintaxe:

id=pathname

Uma extensão CNTK-proprietária deste formato (que não se encontra no HTK original) é que CNTK permite uma sintaxe de pathname relativa mais conveniente quando o scp ficheiro está localizado ao lado das funcionalidades:

id=.../filename

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

O scp ficheiro para as funcionalidades do MFCC contém entradas como estas.

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 ficheiro para as funcionalidades PLP é semelhante, mas aponta para diferentes ficheiros físicos. Note que o nome lógico em ambos os scp ficheiros é 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 ficheiro lista as etiquetas, utilizando esta sintaxe:

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

...

.
"id"
labelBegin1 labelEnd1 label1
labelBegin2 labelEnd2 label1

...

.

...

Aqui temos uma secção terminada com . (ponto) por cada ficheiro de entrada, e uma linha por token dentro de cada secção. Os tempos de etiqueta são dados numa base de tempo de , e os quadros de 10e-7fala são normalmente 10e-2, pelo que são necessários 5 zeros para anexar a cada índice de cada vez.

É importante notar que CNTK lê apenas as primeiras três colunas* dentro de uma secção de um mlp ficheiro e ignora o resto. No nosso ficheiro de exemplo mlf também partilha o nome lógico com ambos os ficheiros 'scp'. Aqui está o corte:

#!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 vamos descrever ficheiros Archive , que às vezes também são conhecidos como chunk ficheiros. CNTK usa um conceito de pedaço para todos os seus Leitores, e significa uma coisa absolutamente diferente, por isso, para evitar a confusão não usamos o termo pedaço em relação aos ficheiros descritos abaixo, mas antes chamá-los de Arquivos.

Os ficheiros de arquivo são basicamente matrizes de colunas de float32, com um cabeçalho de 12 bytes que contém o tamanho da amostra e o número de amostras. Geralmente são mais fáceis de usar, especialmente no início. O cabeçalho esperado do ficheiro é definido através 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 isto. Se os seus ficheiros não forem criados pelo HTK, pode apenas defini-lo para 9 (USER). E
  • sampperioddeve ser 100000 (CNTK ignora maioritariamente este valor, exceto possivelmente para mensagens de erro).

Por último, é importante notar que, na maioria das aplicações de reconhecimento de voz, as características de valor contínuo são utilizadas como entradas, enquanto rótulos categóricos discretos são usados como saída. No entanto, o HTKMLFReader apenas associa os dados com os nomes dos nós e é agnóstico quanto à forma como estes dados são utilizados. Por exemplo, um ficheiro apropriado mlf de etiquetas de identidade de altifalantes poderia ser usado para gerar um vetor de características de identidade de um só hot como uma entrada para a rede.