Écrire mon propre code de reconnaissance vocale [fermé]

17

Description du problème

Je souhaite utiliser la reconnaissance vocale dans le cadre d'un projet matériel, que j'aimerais être complètement autonome (j'utilise de petits appareils à faible puissance et à faible vitesse tels que Arduino et Raspberry Pi, Kinects, etc., sans ordinateur traditionnel avec un OS est impliqué. Donc un projet fermé / autonome).

La reconnaissance vocale peut être très compliquée selon le niveau de sophistication que vous désirez. J'ai ce que je crois un ensemble d'exigences relativement simple. Je veux seulement reconnaître ma propre voix, et j'ai un petit dictionnaire d'une vingtaine de mots que j'aimerais reconnaître. Ainsi, je n'ai pas besoin de bibliothèques complexes de reconnaissance vocale ou vocale ou de l'un des excellents logiciels tiers que je trouve via les moteurs de recherche Internet (ils ne manquent pas!). Je crois que mes exigences sont "assez simples" (dans des limites raisonnables) pour que je puisse coder ma propre solution. Je me demande si quelqu'un a écrit son propre processus comme celui-ci, et ma méthode est-elle massivement défectueuse? Y a-t-il une meilleure façon de le faire sans nécessiter un niveau élevé de mathématiques ou avoir à écrire un algorithme complexe? C'est la solution que j'ai essayé de trouver ci-dessous.

Description de la solution

Je vais écrire ceci en C mais je souhaite discuter d'un processus indépendant du langage, en se concentrant sur le processus lui-même. Ignorons donc cela si nous le pouvons.

1 . Je vais pré-enregistrer mon dictionnaire de mots pour correspondre à ceux parlés. Nous pouvons imaginer que j'ai 20 enregistrements de mes 20 mots différents, ou peut-être de courtes phrases ou phrases de deux ou trois mots. Je crois que cela rend le processus de comparaison de deux fichiers d'enregistrement plus facile que la conversion de l'audio en texte et la comparaison de deux chaînes.

2. Un microphone est connecté à mon périphérique matériel exécutant mon code. [1]. Le code prend continuellement des échantillons de longueur fixe, disons 10 ms de longueur par exemple, et stocke 10 échantillons consécutifs par exemple, dans un style d'enregistrement circulaire. [2]. (J'invente ces chiffres du haut de ma tête donc ce ne sont que des exemples pour décrire le processus).

[1] Celui-ci serait probablement connecté via un filtre passe-bande et un ampli-op, tout comme les enregistrements de dictionnaire, afin de réduire la taille des échantillons audio stockés et collectés.

[2] Je ne sais pas exactement comment je vais prendre un échantillon, je dois trouver une méthode, mais si je produisais un chiffre numérique (entier / flottant / double) qui représente l'audio d'un échantillon de 10 ms (peut-être une valeur CRC ou MD5 somme etc. de l'échantillon audio), ou un flux de chiffres (un flux de lectures audio de fréquences peut-être). En fin de compte, un "échantillon" sera une ou plusieurs figures numériques. Cette partie va impliquer beaucoup plus de matériel, donc pas vraiment pour la discussion ici.

3. Le code regarde qu'il est stocké 10 échantillons consécutifs et recherche une augmentation de volume pour indiquer qu'un mot ou une phrase est en train d'être dit (une pause dans le silence), puis augmente la collecte d'échantillons consécutifs pour dire 500 échantillons par exemple. Cela signifierait qu'il capture 5 secondes d'audio dans des échantillons de 10 ms.

Ce sont ces échantillons ou "tranches" qui sont comparés entre le son stocké et le son capturé. Si un pourcentage suffisamment élevé d'échantillons capturés correspond aux échantillons stockés équivalents, le code suppose qu'il s'agit du même mot.

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. Une fois que le code a collecté un flux d'échantillons complet, il coupe ensuite les échantillons vides au début pour produire l'enregistrement audio suivant. Il pourrait également déplacer le jeu d'échantillons vers l'arrière et vers l'avant à quelques endroits pour mieux l'aligner avec l'échantillon stocké.

Cela produit un ensemble d'échantillons comme ci-dessous:

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. Je crois qu'en ayant une valeur en pourcentage pour la proximité de chaque échantillon, l'échantillon 7 diffère donc d'une valeur de 1 qui est inférieure à% 1 et d'une valeur en pourcentage pour le nombre total d'échantillons qui doit être dans leur pourcentage d'appariement d'échantillon , le code a un niveau de précision facilement réglable.

Je n'ai jamais rien fait de tel avec l'audio auparavant, cela pourrait demander beaucoup de travail. C'est pourquoi je pose cette question, si vous savez peut-être déjà que la réponse à cette question est évidente (quelle que soit cette réponse). J'espère que ce ne sera pas une tâche de calcul énorme car certains des matériels que j'utiliserai seront des trucs à faible sec. Dans les centaines de mégahertz (peut-être 1 GHz en utilisant un Rasp Pi overclocké). C'est donc une façon assez grossière de faire correspondre des échantillons audio en utilisant une puissance de calcul inférieure. Je ne vise pas des résultats instantanés, mais moins de 30 secondes pour une preuve de concept décente.

PS Je n'ai pas le représentant pour marquer cela avec un nouveau tag comme "audio", "reconnaissance audio", "voix", "reconnaissance vocale" etc.

jwbensley
la source
17
La VR est sacrément complexe, et je doute que quelqu'un sans connaissances dans le domaine puisse faire beaucoup de progrès sans beaucoup de lecture. La première chose qui me frappe à propos de votre algorithme est qu'il ne gérera pas les différences de vitesse de prononciation d'un mot. Même la réalité virtuelle simple a mis des années à se réaliser.
Gort the Robot
4
En effet. À moins que cela ne vous dérange des années de développement, vous voudrez peut-être examiner les bibliothèques que vous pouvez compiler pour votre cible. Je suis sûr qu'ils existent.
Rig
6
Je suggérerais une étape supplémentaire - faire une transformation de Fourier de chaque échantillon. Cela vous donne l'intensité de chaque fréquence audio au fil du temps, plutôt que de traiter directement les échantillons. Il y aura une fréquence fondamentale raisonnablement cohérente pour les voyelles que vous parlez normalement à laquelle vous pourriez détecter.Vous devez examiner les caractéristiques spécifiques de la parole, pas seulement l'audio. Comme d'autres l'ont dit, c'est une tâche difficile.
Paul Anderson
1
Je vous suggère d'essayer de jouer avec certaines bibliothèques de reconnaissance vocale, même si vous ne pouvez pas les utiliser pour le produit final. Ils seraient utiles pour créer une preuve de concept.
enregistrer

Réponses:

3

Eh bien, je ne crois pas que l'Arduino ait la puissance nécessaire pour le faire. son fonctionnement à 16Mhz Un Arduino a environ 32K de mémoire. Même 20 mots échantillonnés en Mp3 (plus petits que wav) ne rentreraient pas dedans, malgré sa seule voix.

Le rasberi pi pourrait faire l'affaire, son fonctionnement à 700Mhz selon la version, il pourrait avoir 512 Mo de mémoire. Ce n'est pas encore beaucoup de pâte.

Vous pourriez avoir besoin d'un fourier ( http://www.drdobbs.com/cpp/a-simple-and-efficient-fft-implementatio/199500857 )

Ou si vous avez l'intention d'utiliser le volume, faites quelques moyennes avec les échantillons précédents comme
x = (x + x [n-1] + x [n-2] + x [n-3]) / 4 // c'est assez simple pourrait besoin de plus

Une prochaine chose que vous devez faire est que je pense que si vous voulez tracer ces valeurs X, alors vous avez besoin d'une sorte de détection de pente de cette ligne Parce que la détection des commandes en fonction du volume dépend autrement beaucoup de la distance Alors que vous préférez détecter le modèle de les mots

Ensuite, cela dépend un peu de la façon d'enregistrer la pente afin que le motif s'adapte une autre fois. Je veux dire que l'on ne parle pas dans le tempo exact qu'un ordinateur peut correspondre et la pente peut être un peu plus raide. En fin de compte, je pense que c'est un peu la pente de ces lignes et leur longueur sur l'axe y, devrait être dans une moyenne

user613326
la source
1
  1. Arduino et Raspberry Pi sont des cartes de prototypage avec de petites puces dessus. Vous devez d'abord vous concentrer sur la puce. Recherchez quelque chose avec une boîte à outils DSP (traitement numérique du signal), peut-être avez-vous déjà une boîte à outils DSP et ne la connaissez pas. Les boîtes à outils DSP ont des algorithmes sur appel comme fft (transformée de Fourier rapide) et ifft (fft inverse) pour une analyse rapide du domaine fréquentiel.

  2. Concentrez-vous sur votre style programmatique: vos échantillons sont-ils dans une pile ou une file d'attente? Vous voudrez une file d'attente pour ce type de données. Une file d'attente ressemble à:

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

    Prochaine itération:

    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)
    

    Remarquez comment les choses évoluent vers la «droite»? Je pense que vous avez décrit un algorithme "circulaire". Remplacez simplement les échantillons les plus anciens par les seconds échantillons les plus anciens, puis remplacez les deuxièmes échantillons les plus anciens par le troisième, ..., jusqu'au début de la file d'attente où vous insérez vos données les plus récentes.

  3. "Le code prélève continuellement des échantillons de longueur fixe, disons 10 msec" <- incorrect Pensez comme ceci: Le code prélève discrètement des échantillons quantifiés (hauteur), à une fréquence d'échantillonnage de 10000 échantillons par seconde, ce qui fait que chaque échantillon est à 0,1 ms d'intervalle.

    Quelle est votre fréquence d'échantillonnage? Quel est le débit sur votre quantificateur? Des nombres inférieurs vous aideront à libérer de la mémoire. Je suggérerais un faible taux d'échantillonnage comme 6600 échantillons par seconde (Nyquist). Je soupçonne que 4 bits (16 niveaux) seraient suffisants pour la reconnaissance. C'est donc 3300 octets d'enregistrement par seconde. Maintenant, faites fft et supprimez tout ce qui dépasse 3300 Hz (filtre de téléphonie). Vous disposez maintenant de 1650 octets pour une seconde de son. Ces astuces DSP économiseront beaucoup de mémoire.

    Je ne sais pas qui pense que 512 Mo est petit. Avec les informations ci-dessus, plus de 300 000 secondes d'enregistrement ... sur 3 jours solides.

  4. Je pense que vous trouverez que le domaine fréquentiel (en utilisant fft) est un meilleur environnement pour effectuer la reconnaissance vocale.

J'espère que je ne vous ai pas confondu pire :)

ce gars
la source