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. ConfigurarreadMethod
parablockRandomize
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. AblockRandomize
opção requer um ficheiro de arquivo, descrito abaixo. Além disso, como descrito abaixo, quando usado em conjunto comframeMode = "false"
o método deblockRandomize
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, especificar17280000
. Orandomize
parâmetro também compreende dois valores especiais:auto
ounone
.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
oufull
, 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. Afull
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 estilomlf
HTK que contém as etiquetas para todas as expressões especificadas noscp
ficheiro.labelDim
: a cardinalidade total do conjunto de rótulos.labelMappingFile
: o caminho para um ficheiro que lista todas as etiquetas vistas nomlf
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
oufalse
, se o leitor deve aleatoriamente os dados ao nível da moldura ou o nível de expressão.true
A definiçãoframeMode
é 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 parafalse
, 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 deblockRandomize
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
oufalse
. 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-7
fala 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). Esampperiod
deve ser100000
(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.