Y en cuánto grabemos un vídeo de demostración del sistema, lo subiremos a youtube y os lo pondremos también por aquí.
lunes, 8 de abril de 2013
Entrada 10: Presentación 1er hito - J21/03/2013
El jueves 21 de marzo tuvieron lugar las presentaciones del primer hito de las prácticas innovadoras. Ésta es la presentación con la que expusimos el proyecto:
Y en cuánto grabemos un vídeo de demostración del sistema, lo subiremos a youtube y os lo pondremos también por aquí.
Y en cuánto grabemos un vídeo de demostración del sistema, lo subiremos a youtube y os lo pondremos también por aquí.
lunes, 1 de abril de 2013
Entrada 9: Mejorando el procesado - M19/03/2013
En la última reunión con nuestro tutor, nos comentó algunos cambios en los algoritmos de reconocimiento de idioma que mejoran los resultados obtenidos.
El primero consiste en aumentar la frecuencia de muestreo a 16 kHz, ya que originalmente estaba a 8 kHz. De esta manera, se tienen más datos para procesar y la calidad del fichero de audio es mejor. Los cambios que tuvimos que realizar son:
-Cambiar las opciones del comando que graba el audio (arecord), sustituyendo 8000 por 16000 en la opción -r:
El segundo cambio propuesto consiste en normalizar la señal antes del procesado con SPro, y no una vez empezado éste. Para ello:
-Eliminamos la opción -R del comando anterior, que normaliza la señal, quedando definitivamente:
El primero consiste en aumentar la frecuencia de muestreo a 16 kHz, ya que originalmente estaba a 8 kHz. De esta manera, se tienen más datos para procesar y la calidad del fichero de audio es mejor. Los cambios que tuvimos que realizar son:
-Cambiar las opciones del comando que graba el audio (arecord), sustituyendo 8000 por 16000 en la opción -r:
$ arecord -D hw:1,0 -f S16_LE -c 1 -r 16000 -B 900000 "ruta_fichero/nombre_fichero.wav"-Modificar el fichero que llama al programa sfbcep (incluida en el toolkit SPro) para que sepa que el fichero que le pasamos es de 16 kHz y no de 8 kHz (por defecto). El fichero que hay que cambiar es "feature_extractHTK_Albayzin12.sh" y ésta es la línea que hay que cambiar:
OPTS_SFBCEP=" -e -i 200 -u 3800 -Z -R";y aquí está la línea editada:
OPTS_SFBCEP=" -e -i 200 -f 16000 -Z -R";Añadimos la opción -f 16000, indicando que la frecuencia de muestreo es 16 kHz. La opción -u la eliminamos porque por defecto usa la mitad de la frecuencia de muestreo, siguiendo el teorema de Niquist (8000 Hz).
El segundo cambio propuesto consiste en normalizar la señal antes del procesado con SPro, y no una vez empezado éste. Para ello:
-Eliminamos la opción -R del comando anterior, que normaliza la señal, quedando definitivamente:
OPTS_SFBCEP=" -e -i 200 -f 16000 -Z";
-Realizamos la normalización cuando se llama al script fea_process_beforeVAD.m:
function dout=fea_process_beforeVAD(d) d=rasta(d); %rasta filtering % Normalización u = mean(d, 2); s = sqrt(var(d,[],2)); y = zeros(size(d),class(d)); for i=1:size(y, 1) y(i,:) = (d(i,:) - u(i))/s(i); end % d=sdc(y); %shifted delta cepstra - default 7-1-3-7 dout=d;
Una vez realizados los cambios, comprobamos que todo funcionase correctamente. Pero encontramos un imprevisto: al ejecutarse arecord, éste nos avisaba de que la frecuencia máxima de grabación era de 11025 Hz. Esto se debe a que la tarjeta de sonido que viene con los micrófonos de la PlayStation 2 no es capaz de grabar a una frecuencia superior a esta. Por tanto decidimos deshacer los cambios respectivos a los 16 kHz. La solución a ésto será conseguir una tarjeta de sonido USB que pueda grabar hasta 16 kHz como mínimo, pero por ahora no va a ser nuestro objetivo principal.
jueves, 28 de marzo de 2013
Entrada 8: Memoria - S16&D17/03/2013
Durante este fin de semana hemos estado elaborando la memoria correspondiente al primer hito de la práctica. A diferencia del blog (este), donde estamos estructurando la práctica de forma cronológica para que cualquiera pueda ver los pasos que seguimos y el trabajo que hemos realizado, en la memoria estructuramos el proyecto por módulos. Para que podáis ver que os parece aquí os dejamos el enlace a dropbox, con la memoria en pdf:
LID on RPi: Memoria del primer hito.
martes, 26 de marzo de 2013
Entrada 7: Programa principal - V15/03/2013
A la hora de utilizar el sistema, y también pensando un tener una interfaz con el usuario, hemos decidido hacer un programa principal que vaya mostrando trazas mientras realiza el proceso completo del sistema: grabar el audio -> enviarlo al servidor -> realizar el reconocimiento del idioma -> mostrar el resultado.
Este programa lo hemos desarrollado en shell script de forma que se ejecuta en una terminal, es decir, todavía no tenemos una interfaz gráfica "bonita". A continuación mostramos el código fuente comentado del script:
#!/bin/sh # Dirección del servidor ssh server=diego@10.42.0.1 # Ruta al proyecto en el servidor LID_RPi_DIR=/home/diego/Dropbox/Universidad/SDG2_Matlab/LID_RPi # Destino del fichero de audio AUDIO_DIR=${LID_RPi_DIR}/audio # Ruta al fichero con los resultados del reconocimiento SCORES=${LID_RPi_DIR}/ivectoresMFCC/plenty_closed/results_512G_i400/plenty_closed_acus_400i_512G_WithLN_hmmHung_isEval__Albayzin_TEST.scores # Nombre del fichero de audio WAV_NAME=tmp # Configuración del micrófono amixer –c 1 sset Mic,0 100%,100% unmute cap 1>/dev/null # Grabación de la voz del usuario echo Pulse Enter para comenzar a grabar read keypress arecord –D hw:1,0 –f S16_LE –c 1 –r 8000 –B 900000 ${WAV_NAME}.WAV & >/dev/null 2>&1 echo Grabando… Pulse Enter para finalizar la grabación read keypress killall arecord 1>/dev/null # Envío del fichero de audio al servidor echo Enviando la información al servidor… scp ${WAV_NAME}.wav $server:$AUDIO_DIR >/dev/null 2>&1 || (echo “No se ha podido conectar con el servidor” && exit 1) # Actualizar la lista con el nombre del archivo para luego poder identificarlo echo Procesando… ssh $server “echo $WAV_NAME > ‘${LID_RPi_DIR}/prueba.lst’” >/dev/null 2>&1 # Ejecución del programa en el servidor ssh $server ${LID_RPi_DIR}/runAll2.sh >/dev/null 2>&1 # Muestra de los SCORES por la consola ssh $server cat ${SCORES} echo “¡Listo!”El único problema que hemos encontrado con el script es que cada vez que se realiza una conexión con el servidor te pide la contraseña, y esto no nos parecía viable ya que el usuario podría (debería) no conocer la contraseña que le da acceso a nuestro servidor. Por ello, a continuación contamos como se realiza dicha conexión en más detalle de lo que lo hicimos en la Entrada 1 y explicamos como hemos solucionado el problema de la autenticación.
Al principio decidimos usar el protocolo SSH debido a su sencillez. El nombre viene del acrónimo Secure Shell y es un protocolo de comunicaciones que permite acceder a la Shell o intérprete de comandos de una máquina a través de la red de forma encriptada. Funciona sobre TCP, asegurándonos fiabilidad, una característica a tener en cuenta, ya que vamos a enviar ficheros y necesitamos que lleguen correctamente.
Para la implementación de este protocolo, hemos utilizado openssh, que tiene dos opciones: openssh-client y openssh-server. openssh-client permite acceder a una terminal remota, mientras que openssh-server es el que permite al ordenador ser accedido de forma remota. Por tanto, para realizar la conexión Raspberry Pi <–> Servidor, será necesario tener instalado openssh-client en la Raspberry Pi (el cual, como en muchas distribuciones de Linux, ya viene incluido) y openssh-server en el servidor. Para instalar openssh-server introducimos en la terminal del servidor:
$ sudo apt-get install openssh-serverUna vez instalado openssh en ambos dispositivos, ya podemos acceder al servidor desde la Raspberry Pi y realizar las operaciones que ya mencionamos en dicha Entrada 1.
Ahora bien, como ya hemos dicho, cada vez que se ejecuta uno de estos comandos pide la contraseña del usuario con el que accedemos al servidor. Para evitar esto hay que usar claves DSA. Cuando se generan este tipo de claves, se crean dos ficheros: uno que contiene la clave pública del cliente, y la cual hay que copiar en el fichero de claves autorizadas del servidor, y otro que contiene la clave privada. El proceso que seguimos es el siguiente:
- Generar las claves dsa con el programa ssh-keygen (incluido en openssh):
$ ssh-keygen –t dsa
- Darle permisos de lectura y ejecución a todos los usuarios, y de escritura sólo al propietario a la carpeta .ssh:
$ mkdir .ssh $ chmod 755 .ssh
- Enviar la clave pública (id_dsa.pub) al servidor como authorized_keys y darle permisos de lectura y escritura al propietario:
$ scp ~/.ssh/id_dsa.pub usuario@dirección_servidor:.ssh/authorized_keys $ chmod 600 ~/.ssh/authorized_keys
Y una vez hemos realizado estos pasos ya podemos realizar todas las operaciones que soporte ssh sin que nos pidan una contraseña de validación por cada paso que demos.
domingo, 24 de marzo de 2013
Entrada 6: Resolución de problemas de ejecución - M12/03/2013
Como hemos comentado en la entrada anterior, el programa lanzaba una excepción porque intentaba acceder a unos datos vacíos. Después de un rato investigando y mirando todos los directorios
descubrimos que algunos de los archivos de datos que se generan estaban
vacíos, y al relanzar el programa no los generaba de nuevo si no que
partía de ellos.
No sabemos por qué pudo pasar esto, pero es posible que al intentar lanzar el programa cuando todavía no tenía todas las herramientas (SPro y Alize/LIA_RAL) instaladas no pudo generar estos archivos. En cualquier caso, la solución fue borrar todos estos archivos vacíos de forma que al volver a lanzar el programa, esta vez lo primero que hizo fue generarlos de nuevo.
A pesar de estos cambios seguía sin completarse la ejecución, sólo que esta vez las excepciones no nos daban mucha información de que estaba fallando. Esta vez lo que ocurría es que había una parte del código desordenado, de forma que las rutas de unos de los archivos de datos generados no cuadraban con las rutas de otra parte del programa. Así que realizamos los siguientes cambios, todos en el archivo go.testWavFileWithIVectors.sh:
En esta entrada quizá deberíamos haber puesto algún pantallazo de los errores que hemos mencionado al principio pero se nos olvidó hacerlos.
No sabemos por qué pudo pasar esto, pero es posible que al intentar lanzar el programa cuando todavía no tenía todas las herramientas (SPro y Alize/LIA_RAL) instaladas no pudo generar estos archivos. En cualquier caso, la solución fue borrar todos estos archivos vacíos de forma que al volver a lanzar el programa, esta vez lo primero que hizo fue generarlos de nuevo.
A pesar de estos cambios seguía sin completarse la ejecución, sólo que esta vez las excepciones no nos daban mucha información de que estaba fallando. Esta vez lo que ocurría es que había una parte del código desordenado, de forma que las rutas de unos de los archivos de datos generados no cuadraban con las rutas de otra parte del programa. Así que realizamos los siguientes cambios, todos en el archivo go.testWavFileWithIVectors.sh:
#La línea 273 la metemos dentro de la estructura if, entre las líneas 276 y 277: awk 'BEGIN{FS="=|\\[|]|,|{|}"} r==1{missing[$1".fea"]=1;} r==2{if(missing[$2]>0 {print $0 } }' r=1 $OUT_DIR/stats_${SUFFIX}/missing_${SUFFIX}.lst r=2 $OUT_DIR/ivec/ascii_out_${NGAUSS}G_${NIVEC}i/process_segm_test_${SUFFIX}.lst |sed 's/\.fea//g' > $OUT_DIR/stats_${SUFFIX}/stats_segm_${SUFFIX}.lstUna vez terminamos de realizar todos estos cambios volvimos a lanzar el programa, y esta vez nos decía que fallaba en la línea 34 del createNISTFileForTestFiles.pl por un command not found. Si vamos a esa línea podemos ver lo siguiente:
#En la línea 359 aparece una ruta equivocada, de forma que la línea debería ser: (cat $OUT_DIR/ivec/ascii_out_${NGAUSS}G_${NIVEC}i/generate_test.m | $matlab $matlab_executable_parameters ) 2>&1 |tee $OUT_DIR/generate_test.log
my $sTime = `soxi -D $sFilename`;Parece ser que no teníamos instalado el programa soxi, que también era necesario, por lo que instalamos todo el paquete escribiendo en la terminal:
$ sudo apt-get install soxDe esta forma hemos conseguido que ya se ejecute por completo y sin lanzar excepciones el módulo que realiza el reconocimiento del idioma, justo a 5 días de presentar la memoria del primer hito.
En esta entrada quizá deberíamos haber puesto algún pantallazo de los errores que hemos mencionado al principio pero se nos olvidó hacerlos.
lunes, 18 de marzo de 2013
Entrada 5: Problemas de ejecución: rutas - V8/03/2013
Una vez estamos en la carpeta del proyecto LID_RPi, el programa de identificación del lenguaje parte de runAll2.sh, que a su vez empieza a llamar a otros scripts. La primera vez que lo lanzamos, para ver que tal funcionaba, no llegó a ejecutarse puesto que se produjeron errores. A paritr de ahí tuvimos que empezar a hacer cambios para conseguir eliminar los fallos.
El primer cambio que tuvimos que realizar fue el de cambiar las rutas para que concordasen con nuestra estructura de directorios, así como cambiar las menciones a matlab64 por matlab, que es la versión que tenemos. De esta forma las líneas a modificar son:
Después de realizar estos cambios seguía sin completarse la ejecución, puesto que llegaba un momento en el que lanzaba una excepción un tanto extraña, puesto que intentaba acceder a unos datos vacíos. A continuación mostramos el pantallazo:
Matlab trata los datos como matrices, y al intentar acceder a una posición de un array vacío es cuando lanzaba la excepción. Tran un largo rato mirando las funciones .m en las que se lanzaba la excepción descubrimos que ahí no estaba el problema, sino que tenía que ser otra cosa la que fallaba, por lo que decidimos dejarlo para la siguiente sesión.
El primer cambio que tuvimos que realizar fue el de cambiar las rutas para que concordasen con nuestra estructura de directorios, así como cambiar las menciones a matlab64 por matlab, que es la versión que tenemos. De esta forma las líneas a modificar son:
- Dentro de runAll2.sh:
#En la línea 3 ponemos: BIN_DIR=~/Dropbox/Universidad/SDG2_Matlab/LID_RPi #Y en la línea 12: sMatlab='matlab' #Antes de la línea 22 añadimos esta línea para que se #encuentren los ficheros desde la RPi: cd $BIN_DIR
- Dentro de go.testWavFileWithIVectors.sh:
#La línea 247 deberá ser:
matlab_init="addpath(genpath('/home/diego/Dropbox/Universidad/SDG2_Matlab/LID_RPi/bin_matlab'))"
- Dentro de go.calculateScore.sh:
#En la línea 45 tiene que poner:
matlab=”matlab”
Después de realizar estos cambios seguía sin completarse la ejecución, puesto que llegaba un momento en el que lanzaba una excepción un tanto extraña, puesto que intentaba acceder a unos datos vacíos. A continuación mostramos el pantallazo:
Matlab trata los datos como matrices, y al intentar acceder a una posición de un array vacío es cuando lanzaba la excepción. Tran un largo rato mirando las funciones .m en las que se lanzaba la excepción descubrimos que ahí no estaba el problema, sino que tenía que ser otra cosa la que fallaba, por lo que decidimos dejarlo para la siguiente sesión.
sábado, 16 de marzo de 2013
Entrada 4: Compilación de herramientas. Intento de ejecución con Octave. - M5/03/2013
Para el procesado de los ficheros de audio, no sólo era necesario usar Matlab/Octave, sino que además necesitamos usar dos toolkits de procesado de audio enfocados al procesado del lenguaje: SPro y Alize.
Las funciones de estos programas son, por un lado preparar las señales que llegan, con herramientas como el detector de energía, que se encargan de eliminar las partes en las que nadie habla, y por otro de generar una serie de datos relevantes de la señal (parametrizar) que permitan posteriormente decidir a partir de estas características cuál es el idioma en el que se está hablando.
Primero instalamos SPro. Nos descargamos la versión 5.0 de la página oficial: https://gforge.inria.fr/frs/?group_id=532. Una vez descargado, seguimos las instrucciones del archivo INSTALL incluido en la carpeta del SPro:
-En una terminal, acceder a la ruta de la carpeta:
El compilador (gcc) no reconocía las funciones sqrt, cos, y sin, correspondientes a la librería matemática. Investigando lo único que encontramos fue que para que gcc importase dicha librería había que añadir al final de los comandos dentro del makefile la opción -lm. Pero eso ya estaba.
Después de un rato intentando solucionarlo, la solución fue compilar el programa en otro ordenador y con otra versión del gcc, donde no dio error, e instalarlo en el servidor. El problema, por lo visto, estaba en la versión de gcc que usamos (gcc 4.7.2), ya que compilándolo con la 4.4 no da ningún problema.
Una vez instalado SPro, pasamos a instalar Alize y LIA_RAL. El procedimiento fue el mismo que antes, utilizando los mismos comandos tras decargarnos las últimas versiones (la 2.0 en ambos) en el sitio web del programa: http://mistral. univ-avignon.fr /download.html. Sin embargo, en este caso no tuvimos ningún problema durante la instalación.
Las funciones de estos programas son, por un lado preparar las señales que llegan, con herramientas como el detector de energía, que se encargan de eliminar las partes en las que nadie habla, y por otro de generar una serie de datos relevantes de la señal (parametrizar) que permitan posteriormente decidir a partir de estas características cuál es el idioma en el que se está hablando.
Primero instalamos SPro. Nos descargamos la versión 5.0 de la página oficial: https://gforge.inria.fr/frs/?group_id=532. Una vez descargado, seguimos las instrucciones del archivo INSTALL incluido en la carpeta del SPro:
-En una terminal, acceder a la ruta de la carpeta:
$ cd ruta-Una vez en la carpeta, ejecutar el fichero de configuración y compilar el paquete:
$ ./configure $ make-Y por último, instalarlo:
$ make installY ya está... O eso parecía, pero al compilar (make), nos salía el siguiente error:
Después de un rato intentando solucionarlo, la solución fue compilar el programa en otro ordenador y con otra versión del gcc, donde no dio error, e instalarlo en el servidor. El problema, por lo visto, estaba en la versión de gcc que usamos (gcc 4.7.2), ya que compilándolo con la 4.4 no da ningún problema.
Una vez instalado SPro, pasamos a instalar Alize y LIA_RAL. El procedimiento fue el mismo que antes, utilizando los mismos comandos tras decargarnos las últimas versiones (la 2.0 en ambos) en el sitio web del programa: http://mistral.
Suscribirse a:
Entradas (Atom)

