Reconocimiento de voz en SAMSA

 

En setiembre del año pasado, luego de su presentación en el marco de los workshops del 6º Campeonato de Sumo Robótico, todavía no tenía muy claro qué hacer con SAMSA, hacia dónde orientar su programación.

Finalmente decidí que SAMSA tenía que ser un robot capaz de un nivel más sofisticado de sensibilidad auditiva, ya que en mis robots anteriores había experimentado más que nada con diversos tipos de dispositivos ópticos (con mayor o menor suerte), y de emisores de sonido. Esto podría darme la excusa, por ejemplo, para desarrollar un sistema de reconocimiento del ritmo, que le permitiera al robot bailar al compás de la música (y de paso me serviría para el momentáneamente abandonado proyecto Zappator). Por otro lado, me interesaba también experimentar con redes neuronales, ya que suponía que éstas podrían constituir una alternativa a tener que programar línea por línea todo el comportamiento de un robot.

Tal como había publicado en la 1ª etrega de la documentación de SAMSA, la distribución total de tareas del robot a cargo de un sólo y modesto ATmega128 (microcontrolador de 8bit/128KB/16MHz) dejaba, en lo que respecta al audio, tan sólo la posibilidad de medir la intensidad del sonido cada cierto lapso, y ni soñar siquiera con algún tipo de análisis de frecuencias.

La única alternativa parecía ser la de incluir un segundo procesador hardware, exclusivamente dedicado al procesamiento de sonido; pero eso implicaba agregar más componentes, en definitiva, exigirle más al ya sobrecargado sistema electro-mecánico del robot. Era mucho trabajo, y no me convencía.

Se me ocurrió entonces otra solución: al mejor estilo “ZX-81”, el robot entraría temporalmente en un modo “escucha”, durante el cual no podría moverse, mostrar gráficos ni hacer ninguna otra cosa; utilizaría todos sus recursos para “analizar” el audio y actuar en consecuencia. La idea sería aumentar la frecuencia de las interrupciones (a 8KHz, de hecho), y sustituir la actual ISR (interrupt service routine), por otra que sólo procesara audio.

Bien, y cuando decimos “procesar audio”, lo primero que nos viene a la mente es analizar frecuencias. ¿Por qué? Por muchísimas razones, talvez la más importante es que nuestro cerebro mismo percibe el sonido de esa manera. Como no soy para nada experto en FFT, ni estaba seguro de que fuera realmente posible su implementación con estos escasos recursos de cómputo, busqué algún tipo de proceso más liviano, hasta que llegué a un algoritmo que yo mismo bauticé “filtros por correlation recursivos”, que ya debe estar inventado, con otro o con el mismo nombre, y que veremos en breve.

Una vez implementados los 4 filtros de frecuencias fijas (o bandas, no me pregunten.. por cierto, es probable que toda la implementación esté plagada de errores de aliasing y distorsiones de todo tipo; no obstante, contra todo pronóstico, funciona) mirando en la pantalla las gráficas que estos filtros producían, tuve la intuición de que era posible intentar un reconocimiento de palabras, y eso me iba a dar la excusa para “entrarle” a las redes neuronales.

Pasaron un poco más de 6 meses, durante los cuales primero desarrollé la herramienta de diseño y entrenamiento de redes neuronales (Palmer Neural Networks), pero después, al momento de usarla, me daba cuenta de que faltaba algo y no podía avanzar, estaba bloqueado. Por un lado no disponía de mucho tiempo para pensar en esta idea, y por otro lado había empezado a dudar de que fuera posible cumplir con el objetivo. Finalmente a fines de febrero de este año, comencé a dedicarle horas al proyecto, hasta que llegué a este resultado, que dista de ser ideal, pero que nos ilustra claramente qué podemos esperar y qué no, de un sistema con estas características.

Los invito a compartir un viaje por la arquitectura interna de un sistema de reconocimiento de palabras implementado íntegramente en un microcontrolador ATmega128.

Siguiente sección –> Reconocimiento de voz en un ATmega128

 

Be Sociable, Share!

6 Comentarios »

  1. avatar Matias Dice:

    Que tal Pablo… Estuve leyendo tu articulo y me parecio muy interesante, felicitaciones.

    Te molestaba porque estoy desarrollando un sistema domotico controlado, por ahora, con un Arduino Duemilanove y me parece una buena idea incorporar reconocimiento de ciertos comandos por voz que no dependa de la PC. Por ejemplo, “encender cocina”, “apagar living”.

    Queria consultarte si tenes a mano alguna pagina o paper que me pueda servir para profundizar el desarrollo tanto del hardware (supongo que la señal de entrada viene de preamplificar un microfono, pero antes de ingresarla la filtras por hardware?) como software (redes neuronales programadas en C aplicadas a la comparacion de señales analogicas digitalizadas).

    Para tener una idea si da abasto la memoria del micro, cuanto pesa un comando de voz de 1seg a un muestreo de 8KHz?

    Saludos!

  2. avatar pabloxid Dice:

    Hola Matías, muchas gracias.

    El problema de la Arduino es que creo que tiene 2K de SRAM, contra los 4K de la Wiring. La red neuronal te come mucha memoria, no el audio digitalizado porque, como viste en el artículo, yo lo voy procesando a medida que llega, jamás almaceno audio digital propiamente dicho.

    Existen muchos papers sobre reconocimiento de voz, pero todas las implementaciones prácticas que existen son demasiado pesadas como para correr en un micro de 8 bits. Tengo muchos papers bajados, pero no recuerdo de dónde fue que los obtuve, dejame ordenarlos un poco y te contesto con más detalle.

    En mi sistema, el micrófono está conectado a un operacional (LM324) y nada más, ningún filtro por hardware, los filtros son por software (son 4 filtros de frecuencias fijas, y al igual que en el TinyVoice, los agudos están enfatizados).

    En el artículo está prácticamente todo el código que usé, excepto la red neuronal. Lo que sí puedes bajarte es el programa de entrenamiento, en la sección descargas, el PNN, un programa que yo mismo hice y que dio buen resultado para esto. La implementación de red neuronal en el micro es trivial, se reduce a una fórmula para calcular las salidas en función de las entradas y los pesos, básicamente es cada entrada multiplicada por cada peso y todo sumado pasado por la función sigmoide, eso en cada nodo. Para generar los ejemplos, lo único que hago es mandar los 8 datos por serial y los capturo con el Putty y así como salen los cargo en el PNN.

    Lo importante es que no puedes ingresar el audio digital directamente a la red neuronal, antes tienes que extraer la “firma”, de eso se trata todo el artículo.

    1seg de audio muestreado a 8KHz son 16KB, o sea, imposible almacenarlo en la memoria del micro, por eso te repito lo de arriba, hay que hacer un procesamiento real-time, no almacenar y luego procesar.

    Gracias por tu comentario, seguimos en contacto, veré de ampliar con más información ni bien tenga tiempo.

    Saludos,
    P.G.

  3. avatar josealfredo Dice:

    es algo muy interesante para el desarrollo de proyectos

  4. avatar johnson & johnson Dice:

    Took me time to read the whole article, the article is great but the comments bring more brainstorm ideas, thanks.

    – Johnson

  5. avatar Ani Dice:

    Hola Pablo, me ecuentro buscando información para realizar un reconocedor de voz, y bueno me topé con tu blog, comentas que en el artículo se encuentra el código que empleaste, pero no logro  verlo, si tienes más información sobre esto me la podrías facilitar?. Mi reconocedor quiero implementarlo con un dspic debido a la capacidad de procesamiento de señales. Por cierto Te felicito, me parece muy bueno tu desarrollo!

  6. avatar pabloxid Dice:

    Hola Ani, muchas gracias por tu comentario.
    El código se encuentra más adelante si sigues leyendo el artículo, concretamente aquí: http://www.pablogindel.com/informacion/reconocimiento-de-voz-cont/
    Ahí está expuesto y analizado todo el código que usé excepto el runtime de la red neuronal, que es trivial (es decir la parte que no es el entrenamiento). El entrenamiento está hecho fuera del micro, con el programa descrito en este otro artículo: http://www.pablogindel.com/2009/12/palmer-neural-networks/, cuyo código también puedes bajar en la sección descargas.
    Cabe destacar que los "filtros por correlation recursivos" están mal implementados, como me hizo notar un amigo con razón, puesto que no tienen en cuenta la fase, y de hecho pueden estar dando un resultado equivocado.
    Tengo planeado hacer todo esto de nuevo pero bien hecho, en un ARM Cortex-M3, es decir en una mbed, hace mucho que lo tengo planeado, pero no lo he hecho aun.
    Saludos,
    P.G.

RSS alimentación de los comentarios de esta entrada. TrackBack URL

Dejar un comentario