Wiki

Clone wiki

gpyvozcontrol / julius

Creación del modelo acústico con Julius y HTK


  1. Bibliotecas (libraries) de Software necesarias
  2. Preparación de los datos de entrenamiento
  3. Creación de los monofónos en los HMMS
  4. Creación de los estados de ligadura (atadura) de los trifonemas
  5. Ejecución de Julius

Bibliotecas de Software necesarias

Los programas de soporte necesarios para la creación del modelo acústico son:

El conjunto de herramientas HTK
Es un conjunto de herramientas de software para la construcción y manipulación de modelos acústicos representados como modelos ocultos de Markov. Se utiliza principalmente en el reconocimiento de voz. La licencia de HTK requiere estar registrado antes de descargar el conjunto de herramientas. Además, aunque las fuentes están disponibles, se establecen limitaciones para su libre distribución. Sin embargo el modelo acústico creado no tiene ninguna restricción para su distribución y operación autónoma. Para este desarrollo se utilizó la versión 3.4 de HTK, que se puede descargar desde http://htk.eng.cam.ac.uk/ftp/software/HTK-3.4.1.tar.gz una vez que tiene usuario y clave. La página web del registro es: http://htk.eng.cam.ac.uk.
Julius
Es un motor de reconocimiento continuo del habla. Se puede utilizar para el desarrollo de aplicaciones de control y dictado. Julius es software libre y por tanto no tiene limitaciones para su uso. Utiliza modelos acústicos en formato HTK y archivos de gramática en su propio formato. Se usó para este proyecto la version 4.2.2. Se puede descargar desde: http://julius.osdn.jp/en_index.php?q=index-en.html#download_julius. La versión usada en el proyecto está en: http://osdn.jp/projects/julius/downloads/56549/julius-4.2.2.tar.gz/.
Julia
Es un lenguaje para programar a Julius. Se dice que es un lenguaje dinámico, flexible, de alto rendimiento similar a los lenguajes estáticos, combina programación imperativa, funcional y orientada a objetos. La sintaxis es similar a la de Matlab y GNU Octave. Se puede revisar el [manual] explicativo de julia. Se puede descargar desde: http://julialang.org/downloads/. Algunos de los script de ejecución están realizados en este lenguaje, como se explicará en cada caso.

Preparación de los datos de entrenamiento

Paso 1 Creación de la gramática

La gramática de reconocimiento en Julius se divide en dos archivos, el archivo con extensión .grammar en el cual se definen un conjunto de reglas con las que se norman las expresiones lingüísticas (en este caso órdenes) que se espera reconocer y el archivo con extensión .voca que contiene la pronunciación o fonema de las palabras que se van a reconocer, las cuales se encuentran definidas por las categorías en el archivo .grammar.

Formato de los archivos .grammar y .voca

  • .grammar

En este archivo se definen el conjunto de reglas que rigen las palabras permitidas y las expresiones que se esperan reconocer, utilizando un formato BNF modificado escrito de la siguiente forma:

Sentencia: [Expresión con sentencias]
donde "Sentencia" es un no terminal y "[Expresión con sentencias]" es un conjunto de secuencias de expresiones que pueden ser terminales y/o no terminales.

A continuación se muestra un fragmento del archivo .grammar creado para el sistema de órdenes de voz:

S: SN_B SENT SN_E
SENT: NOMBRE
SENT: ACCION EDITOR DE EDICION
SENT: ACCION PROGRAMA_O
SENT: ACCION  CARPETA ARCHIVO
SENT: ACCION  CARPETA DE ARCHIVO
SENT: ACCION_V LA VENTANA

donde "S" es el inicio del símbolo de frase, "SN_B", "SN_E" son necesarios en toda gramática de Julius. "SN_B", "SN_E", "NOMBRE", "ACCION", "EDITOR", "DE", "EDICION", "PROGRAMA_O", "CARPETA", "ARCHIVO", entre otros son terminales que representan categorías de palabras en el archivo .voca, "SENT" son no terminales y no tienen una definición en el archivo .voca.

  • .voca

En este archivo se definen las palabras con su pronunciación para cada categoría. El símbolo "%" (porcentaje) define cada categoría, las definiciones del conjunto de palabras de cada categoría son definidas en la línea siguiente, una por línea, donde la primera columna representa la cadena que se mostrará cuando es reconocida y la segunda su pronunciación. El formato sería el siguiente:

% CATEGORIA
palabra_1   pronunciaci|ó|n_1
palabra_2   pronunciaci|ó|n_2
palabra_3   pronunciaci|ó|n_3
... ...
... ...

a continuación un fragmento del archivo .voca creado para el sistema (gpyvozcontrol):

% SN_B
<s>        sil

% SN_E
</s>        sil

% ACCION
abrir a b r i r 
abre a b r e 

% ACCION_V
cerrar th e rr a r 
cierra th i e rr a 
maximizar m a k s i m i th a r 
maximiza m a k s i th a
minimizar m i n i m i th a r 
minimiza m i n i m i th a 
ampliar a m p l i a r 
amplia a m p i a 
reducir r e d u th i r 
reduce r e d u th e 

% EDICION
presentacion p r e s e n t a th i o n 
texto t e k s t o 
documento d o k u m e n t o s 
hoja o x a 

% PROGRAMA_O
calculadora k a l k u l a d o r a 
navegador n a b e g a d o r 
mensajeria m e n s a x e r i a 
terminal t e r m i n a l
consola k o n s o l a  
correo k o rr e o 

% NOMBRE
vozcontrol b o th k o n t r o l

Las categorías "SN_B", "SN_E" son un modelo de silencio definidos en el modelo acústico y representan el inicio y el final de la entrada de voz; "NOMBRE", "ACCION", "EDITOR", "EDICION", "PROGRAMA_O", entre otros tiene definida las palabras con sus respectivas pronunciaciones, que son los fonemas que serán reconocidos y que deben estar en el modelo acústico.

Julius necesita de un archivo, donde cada transición de palabra a palabra esta en una lista de forma explícita, esto se logra compilando los archivos .grammar y .voca. mkdfa.pl genera este archivo buscando la sentencia inicial "S" en el archivo .grammar y reemplazando todas las categorias por las palabras que se encuentran definidas en el archivo .voca, formando una lista predefinida de todas las posibles combinaciones de las frases a reconocer.

Cuando Julius escucha los sonidos de una palabra o frase de un usuario, lo que se intenta hacer es coincidir estos sonidos con la representación estadistíca del modelo acústico, si se produce una coincidencia, Julius determina el fonema correspondiente al sonido. Se realiza un seguimiento de los fonemas que coinciden hasta que el usuario haga una pausa. Entonces es cuando se busca la gramática equivalente de los fonemas. Por ejemplo, si ha reconocido los fonemas " a b r i r n a b e g a d o r ", devolverá las palabras "<sil> abrir navegador </sil>" en el manejador de llamada.

Para obtener los archivos ".term", ".dfa" y ".dic" se utiliza el siguiente comando:

mkdfa.pl gpyvozcontrol

donde ".term" y ".dfa" obtenidos contienen información del automáta finito y ".dic" la pronunciación del diccionario, todos en formato Julius.

La representación de la gramática se muestra a continuación:

(SENT-START ( vozcontrol | ACCION (editor de EDICION | PROGRAMA_O | carpeta ARCHIVO | reproductor) | ACCION_V [todas] LA ventanas] | ACCION_R LAMINA | ACCION_RP volumen al (reproductor | SISTEMA) | t{í}tulo de la ACTIVO | DECIR la DATE | ACCION_L LAMINA | ACCION_RP_1 el reproductor | ACCION_S SISTEMA | presentar TESIS | LAMINA ACCION_R | cambiar a la lámina (DIGIT5 | DIGIT9 | DIGIT10 | DIGIT100 [y (DIGIT5 | DIGIT9)]) | ACCION_A ACCESIBILIDAD) SENT-END)
ACCION = abrir | abre;
ACCION_V = cerrar | cierra | maximiza[r] | minimiza[r] | ampl{'i}a[r] | reducir | reduce;
EDICION = presentaci|ó|n | texto | documento | hoja;
PROGRAMA_O = calculadora | navegador | mensajer{'i}a | terminal | consola | correo;
SISTEMA = equipo | sistema;
ACCION_S = apagar | reiniciar;
ARCHIVO = personal | videos | música | descargas | documentos;
LA = la | las;
ACCION_R = siguiente | anterior | detener | reproducir;
ACCION_L = primera | última | cambiar | próxima;
ACCION_RP = bajar | subir | silenciar;
ACCION_RP_1 = cerrar | cierra | pausa[r];
LAMINA = lámina | canción;
TESIS = tesis | proyecto;
ACTIVO = canción | ventana;
DECIR = decir | dime;
DIGIT5 = uno | dos | tres | cuatro | cinco;
DIGIT9 = seis | siete | ocho | nueve;
DIGIT10 = diez | once | doce | trece | catorce | quince;
DIGIT100 = veinte | treinta | cuarenta | cincuenta | sesenta | setenta | ochenta | noventa;
ACCION_A = activa[r] | desactiva[r];
ACCESIBILIDAD = orca | teclado | magnificador;
DATE = hora | fecha;
donde las "|" (barras verticales) son elementos alternativos, los "[ ]' (corchetes)' son elementos opcionales y "< >' son elementos que se repiten'.

Paso 2 Creación del diccionario de pronunciación

En primer lugar se crea un archivo "prompts.txt" que contiene los fonemas que se utilizan en nuestra gramática y los fonemas necesarios para crear un diccionario foneticamente balanceado. A continuación se muestra algunas líneas del archivo "prompts.txt" de las 282 frases que contiene este archivo, que fue creado para el sistema de órdenes de voz (gpyvozcontrol):

*/01 entre los libros infantiles más leídos está el cuento de caperucita roja
*/02 el inspector carlos ha tenido mucho peso en la resolución del caso
*/03 a lo lejos se divisaba una luz azulada que se movía en zigzag
*/04 siempre se ha dicho que por la boca muere el pez
*/05 clavó el gusano en el anzuelo
*/06 las autoridades sanitarias advierten que el tabaco perjudica seriamente la salud
*/07 en el techo el yeso estaba agrietado
*/08 mi madre me ha dicho que coma todo lo que tengo en el plato
*/09 el mago parecía de goma se metió en la caja en un abrir y cerrar de ojos
*/10 el padre dio como dote unos zapatos y una colección de sellos muy cara
...
...

Es de acotar que cada frase se grabó en un audio diferente.

En segundo lugar se genera un archivo "wList" que contiene la lista de palabras que se encuentran en el archivo "prompts.txt", el script "prompts2wlist.jl" crea este archivo. Se ejecuta:

julia ../bin/prompts2wlist.jl prompts.txt wList

lo que genera el archivo "wlist".

Nota: el script agrega las siguientes palabras en orden a la lista:
-SENT-END
-SENT-START
que son entradas internas necesarias para la creación y proceso del modelo acústicocon Julius.

El siguiente paso es añadir información de la pronunciación, es decir, los fonemas que componen la palabra, a cada una de las palabras en el archivo "wList". HTK utiliza el comando HDMan que pasa por el archivo "wList", y busca la pronunciación de cada palabra en un archivo de léxico independiente, y dando como resultado la creación del diccionario de pronunciación.

Así que se crea el diccionario de pronunciación, ejecutando el comando mencionado anteriormente:

HDMan -A -D -T 1 -m -w wList -n -i monophones1 -l dlog dict ../lexicon/VoxForgeDict.txt

suponiendo que el archivo "VoxForgeDict.txt" es un diccionario de pronunciación y que contiene todas las palabras que están en el archivo "prompts.txt".

Esto genera el archivo "dict" que es el diccionario de pronunciación necesario para el modelo acústico y "monophones1" que es simplemente los fonemas utilizados en "dict".

Por último se crea otro archivo "monophones" para pasos posteriores. Solo se copia el archivo "monophones1" a otro nuevo archivo "monophones0" y se elimina la pausa corta ''sp' del archivo "monophones0", esto se hace de la siguiente forma:

cat monophones1 | grep -v sp >monophones0

Paso 3 Grabaciones

Los audios para el entrenamiento deben tener las siguientes características:
+ Formato MSWav + Frecuencia de muestra 16 Khz + A 16-bits. + Stereo aplicación de escritorio.

Estos audios, son las grabaciones de las frases que se encuentran en el archivo "prompts.txt", cada una por separado.

Paso 4 Creación de los archivos de transcripción

El kit de herramientas de HTK no puede procesar directamente el archivo "prompts.txt", por esta razón se crea el archivo de transcripción el cual tiene el siguiente formato:

"*/01.lab"
entre
los
libros
infantiles
más
leídos
está
el
cuento
de
caperucita
roja
.

y así para cada frase del archivo "prompts.txt". El script "prompts2mlf.jl" permite hacer esto automaticamente, el proceso se describe a continuación.

Se crea el archivo de transcripción "words.mlf", ejecutando en consola:

julia ../bin/prompts2mlf.jl prompts.txt words.mlf

Se amplía el archivo de transcripción "words.mlf". Es decir, se cambia cada palabra con su fonema y colocando la salida en un nuevo archivo, esto se consigue comparando el archivo mlf con el diccionario creado anteriormente, lo que genera el archivo "phones0.mlf" y que no tendr{á} pausas cortas 'sp' después de cada grupo de palabras.

En primer lugar se crea el archivo "mkphones.led" con lo siguiente:

EX
ES sil sil
DE sp

Nota: este archivo lleva una línea en blanco al final

y luego se ejecuta:

HLEd -A -D -T 1 -l '*' -d -i dict phones0.mlf mkphones0.led words.mlf

esto genera el archivo "phones0.mlf".

A continuación, se crea un segundo archivo "phones1.mlf" (que incluye pausas cortas ('sp') después de cada grupo depalabra). Se Crea el archivo "mkphones1.led" con lo siguiente:

EX
ES sil sil

Nota: igual que en el archivo anterior, este archivo tiene una línea en blanco al final

y se ejecuta así:

HLEd -A -D -T 1 -l '*' -d -i dict phones1.mlf mkphones1.led words.mlf

con lo que se obtiene el archivo "phones1.mlf".

Paso 5 Codificación de los datos de entrenamiento

HTK no es eficiente en el procesamiento de archivos ".wav" como lo es con su formato interno, por lo tanto se debe convertir los archivos ".wav" al formato ".mfcc (Mel Frequency Cepstral Coefficients)" que hace referencia generalmente a "Vectores de características" (conjunto de parámetros espectrales, que se obtienen de pequeños segmentos de audio).

El comando HCopy realiza la conversión de formato "wav" a "mfcc"cite{28}. Para ello, se requiere un archivo de configuración (config) que especifica todos los parámetros de conversión necesarios. Se crea el archivo "wav-config" que contiene:

SOURCEFORMAT = WAV
TARGETKIND = MFCC_0_D
TARGETRATE = 100000.0
SAVECOMPRESSED = T
SAVEWITHCRC = T
WindowSize = 250000.0
USEHAMMING = T
PREEMCOEF = 0,97
NUMCHANS = 26
CEPLIFTER = 22
NUMCEPS = 12

y el script "codetrain.scp" que contiene la ruta de origen de los archivos "wav" y de destino "mfcc" los cuáles, para el sistema de órdenes gpyvozControl, lucen así (esto es solo un fragmento. Habrá tantos como archivos wav se estén procesando) :

../train/wav/quinteron/01.wav ../train/mfcc/quinteron/01.mfc
../train/wav/quinteron/02.wav ../train/mfcc/quinteron/02.mfc
../train/wav/quinteron/03.wav ../train/mfcc/quinteron/03.mfc
../train/wav/quinteron/04.wav ../train/mfcc/quinteron/04.mfc
../train/wav/quinteron/05.wav ../train/mfcc/quinteron/05.mfc
...
...
../train/wav/guzmanl/01.wav ../train/mfcc/guzmanl/01.mfc
../train/wav/guzmanl/02.wav ../train/mfcc/guzmanl/02.mfc
../train/wav/guzmanl/03.wav ../train/mfcc/guzmanl/03.mfc
../train/wav/guzmanl/04.wav ../train/mfcc/guzmanl/04.mfc
../train/wav/guzmanl/05.wav ../train/mfcc/guzmanl/05.mfc
...
...
../train/wav/ramirezm/01.wav ../train/mfcc/ramirezm/01.mfc
../train/wav/ramirezm/02.wav ../train/mfcc/ramirezm/02.mfc
../train/wav/ramirezm/03.wav ../train/mfcc/ramirezm/03.mfc
../train/wav/ramirezm/04.wav ../train/mfcc/ramirezm/04.mfc
../train/wav/ramirezm/05.wav ../train/mfcc/ramirezm/05.mfc
...
...

luego se ejecuta:

HCopy -A -D -T 1 -C wav_config -S codetrain.scp

El resultado es la creación de una serie de archivos "mfc" correspondientes a los archivos que aparecen en el script codetrain.scp en la carpeta "train/mfcc/".

Creación de los monofónos en los HMMS{monofonos}

Paso 6 Creación de los Monófonos planos de inicio

El primer paso en la formación de un hmm (Hidden Markov Model), es la definición de un modelo prototipo, el énfasis es crear una estructura de modelo. Los parámetros no son importantes al comienzo, su propósito es definir la topología del modelo.

Se crea el archivo "proto" con lo siguiente:

~o <VecSize> 25 <MFCC_0_D_N_Z>
~h "proto"
<BeginHMM>
  <NumStates> 5
  <State> 2
    <Mean> 25
          {small 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 }
    <Variance> 25
       1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 <State> 3
    <Mean> 25
      0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 
    <Variance> 25
       1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 <State> 4
    <Mean> 25
       0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
    <Variance> 25
       1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 <TransP> 5
   0.0 1.0 0.0 0.0 0.0
  0.0 0.6 0.4 0.0 0.0
  0.0 0.0 0.6 0.4 0.0
  0.0 0.0 0.0 0.7 0.3
  0.0 0.0 0.0 0.0 0.0 }
<EndHMM>

Para mayor información sobre este archivo, se recomienda leer el libro de HTKcite, la sección 3.2.1.

También es necesario un archivo de configuración, por lo que se crea un archivo llamado "config" que contiene:

TARGETKIND = MFCC_0_D_N_Z
TARGETRATE = 100000.0
SAVECOMPRESSED = T
SAVEWITHCRC = T
WINDOWSIZE = 250000.0
USEHAMMING = T
PREEMCOEF = 0.97
NUMCHANS = 26
CEPLIFTER = 22
NUMCEPS = 12

HTK necesita saber donde están ubicados todos los archivos de vectores de caracteristicas, que son los archivos "mfc" creados anteriormente, por lo que se crea un script "train.scp" que contiene donde esté el origen de estos archivos. Para el sistema de órdenes de voz luce así:

../train/mfcc/quinteron/01.mfc
../train/mfcc/quinteron/02.mfc
../train/mfcc/quinteron/03.mfc
../train/mfcc/quinteron/04.mfc
../train/mfcc/quinteron/05.mfc
...
...
../train/mfcc/guzmanl/01.mfc
../train/mfcc/guzmanl/02.mfc
../train/mfcc/guzmanl/03.mfc
../train/mfcc/guzmanl/04.mfc
../train/mfcc/guzmanl/05.mfc
...
...
../train/mfcc/ramirezm/01.mfc
../train/mfcc/ramirezm/02.mfc
../train/mfcc/ramirezm/03.mfc
../train/mfcc/ramirezm/04.mfc
../train/mfcc/ramirezm/05.mfc
...
...
~~~T

En el siguiente paso se crea una carpeta "hmm0" y a continuación una nueva versión del archivo "proto" dentro de la carpeta reci{é}n creada ("hmm0") utilizando la herramienta "HCompV" de [HTK] [4] ejecutando:  

**HCompV -A -D -T 1 -C config -f -m 0,01 -S train.scp -M hmm0 proto**  

esto genera los archivos "proto" y "vFloors" en la carpeta "hmm0".  

Para formar los monófonos, solo se crean los archivos "hmmdefs" y "macros", los cuáles se construyen de la siguiente forma:

+ Archivo "hmmdefs".

Se copia el archivo "monophones0" a la carpeta "hmm0" y se renombra como "hmmdefs"; para cada fonema se hace:

+ Añadir al principio de cada fonema:  '~{}h ' (sin los apostrofes  y dejando un espacio luego de la h)
+ Poner el fonema entre comillas dobles.
+ Copiar de la linea 5 en adelante del archivo "proto" que se encuentra en la carpeta "hmm0" y pegarlo después de cada fonema.
+ Dejar una linea en blanco al final del archivo.

Con esto se crea el archivo "hmmdefs", que contiene los monófonos planos de inicio, donde se tiene la probabilidad inicial que representa el estado donde se cree que se encuentra inicialmente el hmm, la probabilidad de transición que representa el cambio en la cadena de Márkov y la probabilidad de emisión que representa con cuanta probabilidad aparece el siguiente fonema. Así debe quedar cada monófono:  
~h "sil" <BEGINHMM> <NUMSTATES> 5 <STATE> 2 <MEAN> 25 8.909576e-09 -3.484646e-09 -2.725015e-09 1.818136e-09 -1.063415e-08 2.443322e-08 1.127184e-08 6.560171e-10 -2.626804e-09 -1.013708e-09 -3.878243e-09 8.729842e-09 -2.313642e-04 4.048051e-04 -4.219529e-05 -4.874423e-04 -6.414966e-05 -1.043901e-03 -9.296974e-04 -6.693655e-04 1.530694e-04 -2.798930e-04 1.348085e-03 -2.755471e-04 -6.417893e-04 <VARIANCE> 25 4.503074e+01 2.756504e+01 3.618806e+01 3.808241e+01 3.697804e+01 5.397874e+01 4.106139e+01 3.781839e+01 4.048951e+01 3.191657e+01 2.334843e+01 2.268922e+01 1.443263e+00 1.474413e+00 1.613365e+00 1.815563e+00 1.749648e+00 2.556612e+00 2.102865e+00 1.877820e+00 1.969723e+00 1.811243e+00 1.592847e+00 1.414474e+00 1.156754e+00 <GCONST> 9.561387e+01 <STATE> 3 <MEAN> 25 8.909576e-09 -3.484646e-09 -2.725015e-09 1.818136e-09 -1.063415e-08 2.443322e-08 1.127184e-08 6.560171e-10 -2.626804e-09 -1.013708e-09 -3.878243e-09 8.729842e-09 -2.313642e-04 4.048051e-04 -4.219529e-05 -4.874423e-04 -6.414966e-05 -1.043901e-03 -9.296974e-04 -6.693655e-04 1.530694e-04 -2.798930e-04 1.348085e-03 -2.755471e-04 -6.417893e-04 <VARIANCE> 25 4.503074e+01 2.756504e+01 3.618806e+01 3.808241e+01 3.697804e+01 5.397874e+01 4.106139e+01 3.781839e+01 4.048951e+01 3.191657e+01 2.334843e+01 2.268922e+01 1.443263e+00 1.474413e+00 1.613365e+00 1.815563e+00 1.749648e+00 2.556612e+00 2.102865e+00 1.877820e+00 1.969723e+00 1.811243e+00 1.592847e+00 1.414474e+00 1.156754e+00 <GCONST> 9.561387e+01 <STATE> 4 <MEAN> 25 8.909576e-09 -3.484646e-09 -2.725015e-09 1.818136e-09 -1.063415e-08 2.443322e-08 1.127184e-08 6.560171e-10 -2.626804e-09 -1.013708e-09 -3.878243e-09 8.729842e-09 -2.313642e-04 4.048051e-04 -4.219529e-05 -4.874423e-04 -6.414966e-05 -1.043901e-03 -9.296974e-04 -6.693655e-04 1.530694e-04 -2.798930e-04 1.348085e-03 -2.755471e-04 -6.417893e-04 <VARIANCE> 25 4.503074e+01 2.756504e+01 3.618806e+01 3.808241e+01 3.697804e+01 5.397874e+01 4.106139e+01 3.781839e+01 4.048951e+01 3.191657e+01 2.334843e+01 2.268922e+01 1.443263e+00 1.474413e+00 1.613365e+00 1.815563e+00 1.749648e+00 2.556612e+00 2.102865e+00 1.877820e+00 1.969723e+00 1.811243e+00 1.592847e+00 1.414474e+00 1.156754e+00 <GCONST> 9.561387e+01 <TRANSP> 5 0.000000e+00 1.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 6.000000e-01 4.000000e-01 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 6.000000e-01 4.000000e-01 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 7.000000e-01 3.000000e-01 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 <ENDHMM>
+ Archivo "macros".

Se crea un archivo "macros" en la carpeta "hmm0" copiando a "vFloor"; se copia también las tres primeras lineas del archivo "proto" ubicado en la carpeta "hmm0" y se agrega al principio del archivo "macros".  

Para hacer la reestimación de los monófonos, se crean nueve carpetas hmm consecutivas (hmm1:hmm9). Cada carpeta contendrá una versión mejor elaborada de los modelos ocultos de Markov que están siendo entrenados para el reconocedor que se desarrolla.  

Los Monofonos al comienzo son re-calculadas utilizando la herramienta HERest. El propósito de esto es cargar todos los modelos en la carpeta hmm0 (éstos están contenidos en el archivo "hmmdefs"), y volver a evaluarlos utilizando los archivos MFCC enumerados en el script "train.scp", y crear un nuevo modelo que figura en "hmm1". Ejecutando el comando HERest:  

**HERest -A -D -T 1 -C config -I phones0.mlf -t 250.0 150.0 1000.0 -S train.scp -H hmm0/macros -H hmm0/hmmdefs -M hmm1 monophones0**  

esto genera los archivos "hmmdefs" y "macros" en la carpeta "hmm1", se repiten estos pasos para la carpeta "hmm2" y "hmm3" respectivamente para la creación de nuevos conjuntos de modelos:  

**HERest -A -D -T 1 -C config -I phones0.mlf -t 250.0 150.0 1000.0 -S train.scp -H hmm1/macros -H hmm1/hmmdefs -M hmm2 monophones0**  

esto genera los archivos "hmmdefs"' y "macros" en la carpeta "hmm2".

**HERest -A -D -T 1 -C config -I phones0.mlf -t 250.0 150.0 1000.0 -S train.scp -H hmm2/macros -H hmm2/hmmdefs -M hmm3 monophones0**  

y se obtiene los archivos "hmmdefs" y "macros" en la carpeta "hmm3"

### Paso 7 Fijar los silencios en el modelo

Los modelos hmmdefs creados hasta ahora no incluyen  una pausa corta 'sp', que se producen entre las palabras en el habla normal. Sin embargo, se ha creado un modelo de silencio 'sil' de mayor duración y hace referencia a las pausas que se producen al final de la oración.   

Para incluir la pausa corta "sp", se agrega un estado "sp" en los modelos "hmmdefs", el cual utiliza el centro de los estados "sil", luego ambos deben estar atados. Esto se hace mediante la copia del estado principal del modelo "sil" en el archivo hmmdefs, se agrega el estado "sp", y luego se ejecuta una herramienta especial llamada HHeD de "lazo" del estado "sp"~ al estado "sil" para que compartan el mismo estado principal.  

Para el sistema de órdenes de voz, se copia el contenido de la carpeta "hmm3" a "hmm4", se modifica el archivo "hmmdefs" ubicado en "hmm4" añadiendo un nuevo estado "sp" al final, de la siguiente forma:  

+ Se copia y pega el estado "sil", se cambia "sil" al nuevo "sp" (no se elimina el viejo estado "sil", ya que se necesita).
+ Se elimina el estado 2 y 4 del nuevo estado "sp" (es decir, se mantiene el estado principal del viejo estado "sil" en el nuevo estado "sp").
+ Se cambia \<NUMSTATES\> a 3
+ Se cambia \<STATE\> a 2
+ Se cambia \<TRANSP\> a 3
+ Se cambia la matriz en \<TRANSP\> a 3 by 3 array
+ Se cambia los números de la matriz a:  
 0,0 1,0 0,0  
 0,0 0,9 0,1  
 0,0 0,0 0,0  

A continuación se crea el archivo "sil.hed", el cual contiene lo siguiente:  

AT 2 4 0.2 {sil.transP}  
AT 4 2 0.2 {sil.transP}  
AT 1 3 0.3 {sp.transP}  
TI silst {sil.state[3],sp.state[2]}  

la última linea es el comando de atadura.  

Se ejecuta (utilizando monophones1, ya que contiene el estado 'sp'):  

**HHEd -A -D -T 1 -H hmm4/macros -H hmm4/hmmdefs -M hmm5 sil.hed monophones1**  

para  atar los estados  "sp" a los estados principales "sil". Esto genera los archivos "hmmdefs" y "macros" dentro de la carpeta "hmm5".  

Se ejecuta dos veces mas con el comando "HERest" y utilizando el archivo monophones1:  

**HERest -A -D -T 1 -C config  -I phones1.mlf -t 250.0 150.0 3000.0 -S train.scp -H hmm5/macros -H  hmm5/hmmdefs -M hmm6 monophones1**

el comando genera los archivos "hmmdefs" y "macros" en la carpeta "hmm6".  

**HERest -A -D -T 1 -C config  -I phones1.mlf -t 250.0 150.0 3000.0 -S train.scp -H hmm6/macros -H  hmm6/hmmdefs -M hmm7 monophones1**  

y se obtienen los archivos "hmmdefs" y "macros" en la carpeta "hmm7".

### Paso 8 Realineación de los datos de entrenamiento

Esta operación es similar a la operación llevada a cabo en el paso 4. Sin embargo, en este caso el comando "HVite" puede considerar todas las pronunciaciones de cada palabra (en el caso en que una palabra tiene más de una pronunciación), y luego usar la salida de la pronunciación que mejor coincide con los datos acústicos.  

Se ejecuta el comando "HVite" de la siguiente forma:  

**HVite -A -D -T 1 -l '*' -o SWT -b SENT-END -C config -H hmm7/macros -H hmm7/hmmdefs -i aligned.mlf -m -t 250.0 150.0 1000.0 -y lab -a -I words.mlf -S train.scp dict monophones1> hvite_log**  

y se obtiene el archivo "aligned.mlf".  

Se ejecuta "HERest" para "hmm8" y "hmm9":

**HERest -A -D -T 1 -C config -I aligned.mlf -t 250.0 150.0 3000.0 -S train.scp -H hmm7/macros -H hmm7/hmmdefs -M hmm8 monophones1**  

esto genera el archivo "hmdefs" y "macros" en la carpeta "hmm8".  

**HERest -A -D -T 1 -C config -I aligned.mlf -t 250.0 150.0 3000.0 -S train.scp -H hmm8/macros -H hmm8/hmmdefs -M hmm9 monophones1**  

y se genera el archivo "hmdefs" y "macros" en la carpeta "hmm9".

## Creación de los estados de ligadura (atadura) de los trifonemas{ligadura}
### Paso 9 Hacer trifonemas a partir de los fonemas

En el diccionario creado en el paso 2, la pronunciación de una palabra fue dada por una serie de fonemas (también llamados monofonemas, es decir, un solo fonema). Para generar un trifonema (un grupo de 3 fonemas) se usa una la declaración de fonemas, con un formato de tres letras. el fonema "L" (el fonema de la izquierda) precede del fonema "X" y el fonema "R" (el fonema de la derecha) sigue al fonema "X". El trifonema se declara en forma de "L - X + R".  

A continuación se muestra un ejemplo del trifonema de la palabra "texto", la primera linea muestra el fonema y la segunda linea el trifonema:  
textot e s k t o texto t+e t-e+s e-s+k s-k+t k-t+o t-o ~~~

hay que tener en cuenta que también se pueden obtener bifonemas (un grupo de 2 fonemas) al principio y al final de la palabra.

Para convertir las transcripciones fon{é}ticas en el archivo "aligned.mlf" creado en el paso 8 a un conjunto equivalente de transcripciones de trifonemas, se ejecuta el comando "HLEd", el cual se utiliza para generar una lista de todos los trifonemas para los cuales existe al menos un ejemplo en los datos de entrenamiento.

Pero antes, se crea el archivo "mktri.led", con lo siguiente:

WB sp
WB sil
TC

luego se ejecuta el editor de archivos de etiquetas (HLEd):

HLEd -A -D -T 1 -n triphones1 -l '*' -i wintri.mlf mktri.led aligned.mlf

se obtiene los archivos "wintri.mlf" (archivo de trifonos de multi etiquetas) y "triphones1 (lista de trifonos en su conjunto de entrenamiento)"

A continuación se ejecuta el archivo "mktrihed.jl", de la siguiente forma:

julia ../bin/mktrihed.jl monophones1 triphones1 mktri.hed

Esto genera el archivo "mktri.hed". Este archivo contiene un clon de comando 'CL' seguido de una serie de comandos, para que compartan el mismo conjunto de parámetros.

Se crea tres carpetas mas "hmm10", "hmm11" y "hmm12" y se ejecuta el comando "HHEd" (es el editor de definiciones de hmm en HTK y se utiliza principalmente para la aplicación de "ataduras" a través de parámetros HMM seleccionadas):

HHEd -A -D -T 1 -H hmm9/macros -H hmm9/hmmdefs -M hmm10 mktri.hed monophones1

lo que genera los archivos "hmmdes" y "macros" en la carpeta "hmm10".

Se ejecuta "HERest" dos veces mas:

HERest -A -D -T 1 -C config -I wintri.mlf -t 250.0 150.0 3000.0 -s stats -S train.scp -H hmm10/macros -H hmm10/hmmdefs -M hmm11 triphones1

esto genera los archivos "hmmdes" y "macros" en la carpeta "hmm11".

HERest -A -D -T 1 -C config -I wintri.mlf -t 250.0 150.0 3000.0 -s stats -S train.scp -H hmm11/macros -H hmm11/hmmdefs -M hmm12 triphones1

y se obtiene los archivos "hmmdes" y "macros" en la carpeta "hmm12".

Paso 10 - Hacer trifonemas Estado-Atado

Según el libro de HTKcite, una limitación de la creación de un modelo acústico basado en trifonemas en el paso 9 es que no trata con trifonemas para los que no existen ejemplos en los datos de entrenamiento. Este problema se puede aliviar mediante el diseño cuidadoso de la base de datos de entrenamiento, tratando de anticipar todos los trifonemas necesarios. Pero en la construcción de sistemas de grandes vocabularios los trifonemas invisibles son inevitables".

El árbol de decisión utilizado aquí permite reconocer trifonemas invisibles para ser sintetizados mediante el uso de un arbol de decisión fonética. Se organizan los modelos en un árbol y los parámetros que se pasan al árbol son llamados preguntas. El decodificador hace una pregunta sobre el contexto y decide cuál es el modelo a utilizar. "Un árbol de decisión fonética es un árbol binario en el que una pregunta sí/no fonética se adjunta a cada nodo. La pregunta en cada nodo se elige para maximizar la probabilidad de los datos de entrenamiento, dado el conjunto final de estados atados. Los árboles se definen por la TB de comandos. Todas las posibles cuestiones fonéticas debe cargar en HHED mediante comandos de QS" (es una traducción libre del tutorial cite{17} del paso 10).

A continuación, se crea un archivo "maketriphone.ded" que contenga:

AS sp
MP sil sil sp
TC

El comando TC dirige la edición "HDMan" a la salida de trifonemas.

Se ejecuta para todo el diccionario léxico, no solo para el diccionario utilizado hasta ahora, lo siguiente:

HDMan -A -D -T 1 -b sp -n fulllist0 -g maketriphones.ded -l flog dict-tri ../lexicon/VoxForgeDict.txt

y se obtiene los archivos "dict-tri" y "fulllist0"

Para anexar el contenido de "monophones0" al principio del archivo "fulllist0", eliminar las entradas duplicadas y colocar el resultado en "fulllist", se ejecuta el script "fixfulllist.jl" como sigue:

julia ../bin/fixfulllist.jl fulllist0 monophones0 fulllist

Ahora se crea el archivo "tree1.hed" (que contiene el contexto de preguntas que utilizara HTK para seleccionar los trifonemas pertinentes), puede encontrar mas información sobre como se crea este archivo desde 1 y 2. Para el sistema de órdenes de voz se utiliza el encontrado en 3.

Nota: el archivo "tree1.hed" contiene una linea en blanco al final.

Se ace una copia del archivo "tree1.hed" con el nombre de "tree.hed". Consultar el libro HTKcite{25} para obtener más información sobre estos comandos.

Para agregar los grupos estatales al archivo "tree.hed" creado anteriormente, se ejecuta el archivo "mkclscript.jl":

julia ../bin/mkclscript.jl monophones0 tree.hed

Ahora se crea tres carpetas mas "hmm13", "hmm14" y "hmm15" y se ejecuta "HHEd":

HHEd -A -D -T 1 -H hmm12/macros -H hmm12/hmmdefs -M hmm13 tree.hed triphones1

esto genera los archivos "hmmdefs", "macros" y "tiedlist".

Por último se ejecuta dos veces el comando "HERest":

HERest -A -D -T 1 -T 1 -C config -I wintri.mlf -t 250.0 150.0 3000.0 -S train.scp -H hmm13/macros -H hmm13/hmmdefs -M hmm14 tiedlist

esto genera los archivos "hmmdefs" y "macros" en la carpeta "hmm14".

HERest -A -D -T 1 -T 1 -C config -I wintri.mlf -t 250.0 150.0 3000.0 -S train.scp -H hmm14/macros -H hmm14/hmmdefs -M hmm15 tiedlist

y se obtiene los archivos "hmmdefs" y "macros" en la carpeta "hmm15".

El archivo de "hmmdefs" en la carpeta "hmm15" junto con el archivo "tiedlist", ahora se utiliza con Julius para reconocimiento de voz.

Ejecución de Julius{ejecucion}

Antes de ejecutar Julius, se debe crear un archivo de configuración para la aplicación, en este caso "gpyvozcontrol.jconf" donde sus principales parámetros son:

dfa gpyvozcontrol.dfa hash archivo de gramática del autómata de estado finitos.
v gpyvozcontrol.dict hash Diccionario de pronunciación
h hmm15/hmmdefs hash modelo acústico
hlist tiedlist
smpFreq 16000hash Velocidad de muestreo
spmodel 'sp' hash nombre de una pausa corta
multipath hash force enable MULTI-PATH model handling
gprune safe hash Metodo de poda de gauss
iwcd1 max hash Metodo de aproximación de trifonemas
iwsppenalty -70.0 hash transition penalty for the appended sp models
iwsp hash append a skippable sp model at all word ends
penalty1 5.0 hash word insertion penalty for grammar (pass1)
penalty2 20.0 hash word insertion penalty for grammar (pass2)
b2 200 hash beam width on 2nd pass (#words)
sb 200.0 hash score b1eam envelope threshold
n 1 hash num of sentences to find

y se ejecuta así:

julius -input mic -C gpyvozcontrol.jconf

Los primeros 2-3 segundos del discurso no son reconocidos, mientras Julius ajusta sus niveles de reconocimiento. A continuaci|ó|n, se reconocen las frases de la gramática creada en el paso 1.

En este punto se ha logrado construir la gramática y el modelo acústico necesarios para el desarrollo del Sistema de órdenes de voz "gpyvozcontrol".

anterior Inicio Siguiente

Updated