Escribir mi propio código de reconocimiento de voz [cerrado]

17

Descripción del problema

Quiero usar el reconocimiento de voz como parte de un proyecto de hardware, que me gustaría ser completamente autónomo (estoy usando dispositivos pequeños de baja potencia y baja velocidad como Arduino y Raspberry Pi, Kinects, etc., no tengo una computadora tradicional con un sistema operativo está involucrado. Por lo tanto, un proyecto cerrado / autónomo).

El reconocimiento de voz puede ser muy complicado dependiendo del nivel de sofisticación que desee. Tengo lo que creo que es un conjunto de requisitos relativamente simple. Solo quiero reconocer mi propia voz, y tengo un pequeño diccionario de aproximadamente 20 palabras que me gustaría reconocer. Por lo tanto, no necesito bibliotecas complejas de reconocimiento de voz a texto y voz, ni ninguno de los excelentes software de terceros que encuentro a través de los motores de búsqueda de Internet (¡no hay escasez de estos!). Creo que mis requisitos son "lo suficientemente simples" (dentro de lo razonable) que puedo codificar mi propia solución. Me pregunto si alguien ha escrito su propio proceso de esta manera, ¿y mi método tiene fallas masivas? ¿Hay una mejor manera de hacer esto sin requerir un alto nivel de matemáticas o tener que escribir un algoritmo complejo? Esa es la solución que he tratado de pensar a continuación.

Descripción de la solución

Escribiré esto en C pero deseo analizar un proceso agnóstico del lenguaje, centrándome en el proceso en sí mismo. Así que ignoremos eso si podemos.

1) Pregrabaré mi diccionario de palabras para que coincida con las que se hablan. Podemos imaginar que tengo 20 grabaciones de mis 20 palabras diferentes, o quizás frases cortas u oraciones de dos o tres palabras. Creo que esto hace que el proceso de comparar dos archivos de grabación sea más fácil que convertir el audio en texto y comparar dos cadenas.

2) Hay un micrófono conectado a mi dispositivo de hardware que ejecuta mi código. [1] El código toma continuamente muestras de longitud fija, digamos 10 ms de longitud, por ejemplo, y almacena 10 muestras consecutivas, por ejemplo, en un estilo de registro circular. [2] (Estoy inventando estas cifras de la parte superior de mi cabeza, por lo que son solo ejemplos para describir el proceso).

[1] Esto probablemente se conectaría a través de un filtro de paso de banda y amplificador operacional, como se harían las grabaciones del diccionario, para mantener las muestras de audio almacenadas y recolectadas más pequeñas.

[2] No estoy seguro exactamente cómo tomaré una muestra, aunque necesito elaborar un método si produzco una cifra numérica (entero / flotante / doble) que represente el audio de una muestra de 10 ms (quizás un valor CRC o suma MD5, etc. de la muestra de audio), o una secuencia de figuras (una secuencia de lecturas de audio de frecuencias, tal vez). En última instancia, una "muestra" será una figura numérica o figuras. Esta parte tendrá mucho más hardware involucrado, así que no será realmente una discusión aquí.

3) El código observa que está almacenado 10 muestras consecutivas y busca un aumento de volumen para indicar que se está diciendo una palabra o frase (un descanso del silencio) y luego aumenta la recolección de muestras consecutivas para decir 500 muestras, por ejemplo. Eso significaría que captura 5 segundos de audio en muestras de 10 ms.

Son estas muestras o "cortes" las que se comparan entre el sonido almacenado y el sonido capturado. Si un porcentaje suficientemente alto de muestras capturadas coincide con las almacenadas equivalentes, el código supone que es la misma palabra.

The start of a store recording of the world "hello" for example,
stored words are split into 10 msec samples also

Stored Sample No           | 1| 2| 3| 4| 5| 6| 7|  8|
Stored Sample Value        |27|38|41|16|59|77|200|78|

Incoming audio (me saying "hello") with some "blank" samples
at the start to symbolise silence

Incoming Sample No         | 1| 2| 3| 4| 5| 6| 7| 8| 9|10| 11|12|
Incoming Sample Value      |  |  |  |20|27|38|46|16|59|77|200|78|

4) Una vez que el código ha recopilado una secuencia de muestra completa, corta las muestras en blanco al comienzo para producir la siguiente grabación de audio. También podría mover el conjunto de muestras hacia atrás y hacia adelante algunos lugares para alinearse mejor con la muestra almacenada.

Esto produce un conjunto de muestra como el siguiente:

Stored Sample No           | 1| 2| 3| 4| 5| 6|  7| 8|
Stored Sample Value        |27|38|41|16|59|77|200|78|

Incoming Sample No      |-1| 1| 2| 3| 4| 5| 6|  7| 8|
Incoming Sample Value   |20|27|38|46|16|59|81|201|78|

5) Creo que al tener un valor porcentual de cuán cerca debe estar cada muestra, la muestra 7 difiere en un valor de 1 que es menor que% 1, y un valor porcentual para el número total de muestras que deben estar dentro de su porcentaje de coincidencia de muestra , el código tiene un nivel de precisión fácilmente ajustable.

Nunca antes había hecho algo así con audio, podría ser mucho trabajo. Es por eso que estoy haciendo esta pregunta, si tal vez ya sabes que la respuesta a esta pregunta es obvia (cualquiera que sea esa respuesta). Espero que esto no sea una tarea computacionalmente masiva, ya que parte del hardware que usaré será de poca seguridad. En los cientos de megahercios (tal vez 1 Ghz usando un Rasp Pi con exceso de reloj). Por lo tanto, esta es una forma bastante cruda de hacer coincidir las muestras de audio con una potencia de cálculo más baja. No busco resultados instantáneos, pero menos de 30 segundos para una prueba de concepto decente.

PD : No tengo el representante para etiquetar esto con una nueva etiqueta como "audio", "reconocimiento de audio", "voz", "reconocimiento de voz", etc.

jwbensley
fuente
17
La realidad virtual es bastante compleja, y dudo que alguien sin conocimiento en el campo pueda avanzar mucho sin mucha lectura. Lo primero que me sorprende de su algoritmo es que no manejará las diferencias en la rapidez con que se pronuncia una palabra. Incluso la realidad virtual simple tardó años en acertarse.
Gort the Robot
44
En efecto. Usted, a menos que le importe años de desarrollo, puede que desee buscar bibliotecas que pueda compilar a su objetivo. Estoy seguro de que existen.
Plataforma
66
Sugeriría un paso adicional: hacer una transformación de Fourier de cada muestra. Esto le proporciona la intensidad de cada frecuencia de audio a lo largo del tiempo, en lugar de tratar directamente con las muestras. Habrá una frecuencia fundamental razonablemente consistente para las vocales que normalmente hablas y que puedas detectar. Debes observar las características específicas del habla, no solo el audio. Como han dicho otros, esta es una tarea difícil.
Paul Anderson el
1
Te sugiero que intentes jugar con algunas bibliotecas de reconocimiento de voz, incluso si no puedes usarlas para el producto final. Serían útiles para crear una prueba de concepto.
Sav

Respuestas:

3

Bueno, no creo que el Arduino tenga el poder de caballo para hacer esto. está funcionando a 16Mhz Un Arduino tiene aproximadamente 32K de memoria. Incluso 20 palabras muestreadas en Mp3 (más pequeñas que wav) no encajarían en él, a pesar de que es solo su propia voz.

El rasberi pi puede hacer el truco, está operando a 700Mhz dependiendo de la versión que tenga 512MB de memoria. Eso todavía no es mucha masa.

Es posible que necesite un fourier ( http://www.drdobbs.com/cpp/a-simple-and-efficient-fft-implementatio/199500857 )

O si tiene la intención de usar el volumen, haga algunos promedios con muestras anteriores como
x = (x + x [n-1] + x [n-2] + x [n-3]) / 4 // eso es bastante simple necesitar más

Lo siguiente que debe hacer es pensar si trazaría estos valores de X Entonces necesitará algún tipo de detección de pendiente de esa línea Porque detectar comandos basados ​​en el volumen depende de lo contrario mucho de la distancia Mientras que preferiría detectar el patrón de las palabras

Luego, depende un poco cómo registrar la pendiente para que el patrón se ajuste en otro momento. Quiero decir, uno no habla en el tiempo exacto que una computadora puede igualar y la pendiente puede ser un poco más pronunciada. Al final, creo que esto es un poco cuán empinadas son esas líneas y su longitud y eje, debe estar dentro de algún promedio

usuario613326
fuente
1
  1. Arduino y Raspberry Pi son tableros de prototipos con pequeños chips en ellos. Debes concentrarte primero en el chip. Busque algo con una caja de herramientas DSP (procesamiento de señal digital), tal vez ya tenga una caja de herramientas DSP y no lo sepa. Las cajas de herramientas DSP tienen algoritmos de llamada como fft (transformada rápida de Fourier) e ifft (fft inverso) para análisis de dominio de frecuencia rápida.

  2. Concéntrese en su estilo programático: ¿Sus muestras están en una pila o en una cola? Querrá una cola para este tipo de datos. Una cola se ve así:

    Position NO --|1|2|3|4|5|6|7|8|
    Sample Value  |5|7|9|1|2|2|9|8|
    

    Próxima iteración:

    Position NO --|1|2|3|4|5|6|7|8|
    Sample Value  |0|5|7|9|1|2|2|9|
    ->  First in First out (FIFO)
    

    ¿Notan cómo las cosas cambian hacia la 'derecha'? Creo que describiste un algoritmo "circular". Simplemente sobrescriba las muestras más antiguas con las segundas muestras más antiguas, luego sobrescriba las segundas muestras más antiguas con la tercera más antigua, ..., hasta el comienzo de la cola donde inserta sus datos más nuevos.

  3. "El código toma continuamente muestras de longitud fija, digamos 10 ms" <- incorrecto Piense de esta manera: el código toma discretamente muestras cuantificadas (altura), a una velocidad de muestreo de 10000 muestras por segundo, lo que hace que cada muestra se separe 0.1 ms.

    ¿Cuál es su frecuencia de muestreo? ¿Cuál es la tasa de bits en su cuantizador? Los números más bajos lo ayudarán a liberar memoria. Sugeriría una tasa de muestreo baja como 6600 muestras por segundo (Nyquist). Sospecho que 4 bits (16 niveles) serían suficientes para el reconocimiento. Eso es 3300 bytes de grabación por segundo. Ahora haga fft y elimine todo por encima de 3300 Hz (filtro de telefonía). Ahora tiene 1650 bytes utilizados para un segundo de sonido. Estos trucos DSP ahorrarán mucha memoria.

    No sé quién piensa que 512 MB es pequeño. Con la información anterior que es más de 300,000 segundos de grabación ... durante 3 días seguidos.

  4. Creo que el dominio de frecuencia (mediante el uso de fft) es un mejor entorno para realizar el reconocimiento de voz.

Espero no confundirte peor :)

este chico
fuente