Schreiben meines eigenen Spracherkennungscodes [geschlossen]


17

Problembeschreibung

Ich möchte die Spracherkennung als Teil eines Hardwareprojekts verwenden, mit dem ich mich selbstständig machen möchte (ich verwende kleine Geräte mit geringem Stromverbrauch und geringer Geschwindigkeit wie Arduino's und Raspberry Pi's, Kinects usw., auf denen kein herkömmlicher Computer läuft) ein OS ist involviert (also ein geschlossenes / eigenständiges Projekt).

Die Spracherkennung kann je nach gewünschter Komplexität sehr kompliziert sein. Ich habe, wie ich glaube, vergleichsweise einfache Anforderungen. Ich möchte nur meine eigene Stimme erkennen und ich habe ein kleines Wörterbuch mit etwa 20 Wörtern, die ich gerne wiedererkennen würde. Daher benötige ich keine komplexen Spracherkennungs- und Spracherkennungsbibliotheken oder die exzellente Software von Drittanbietern, die ich über Internet-Suchmaschinen finde (es gibt keinen Mangel an diesen!). Ich glaube, meine Anforderungen sind "einfach genug" (im Rahmen der Vernunft), dass ich meine eigene Lösung codieren kann. Ich frage mich, ob jemand seinen eigenen Prozess so geschrieben hat und ob meine Methode massiv fehlerhaft ist? Gibt es einen besseren Weg, dies zu tun, ohne ein hohes Maß an Mathematik zu erfordern oder einen komplexen Algorithmus schreiben zu müssen? Das ist die Lösung, die ich mir unten ausgedacht habe.

Lösungsbeschreibung

Ich werde dies in C schreiben, aber ich möchte einen sprachunabhängigen Prozess diskutieren, der sich auf den Prozess selbst konzentriert. Ignorieren wir das also, wenn wir können.

1. Ich werde mein Wörterbuch vorab aufzeichnen, damit es mit den gesprochenen Wörtern übereinstimmt. Wir können uns vorstellen, dass ich 20 Aufzeichnungen meiner 20 verschiedenen Wörter oder vielleicht kurze Sätze oder Sätze von zwei oder drei Wörtern habe. Ich glaube, dies macht den Vergleich zweier Aufnahmedateien einfacher als die eigentliche Konvertierung des Audios in Text und den Vergleich zweier Zeichenfolgen.

2. Ein Mikrofon ist an mein Hardwaregerät angeschlossen, auf dem mein Code ausgeführt wird. [1] Der Code entnimmt kontinuierlich Abtastwerte mit fester Länge, beispielsweise mit einer Länge von 10 ms, und speichert beispielsweise 10 aufeinanderfolgende Abtastwerte in einem Umlaufprotokollierungsstil. [2] (Ich erfinde diese Figuren aus dem Kopf, so dass sie nur Beispiele sind, um den Prozess zu beschreiben).

[1] Dies würde wahrscheinlich über ein Bandpassfilter und einen Operationsverstärker erfolgen, ebenso wie die Wörterbuchaufnahmen, um die gespeicherten und gesammelten Audio-Samples kleiner zu halten.

[2] Ich weiß nicht genau, wie ich ein Sample nehmen soll. Ich muss jedoch eine Methode ausarbeiten, bei der ich eine numerische Zahl (Integer / Float / Double) erzeuge, die das Audio eines 10-ms-Samples darstellt (möglicherweise ein CRC-Wert) oder MD5-Summe usw. des Audio-Samples) oder ein Strom von Zahlen (ein Strom von Audio-Ablesungen von Frequenzen vielleicht). Letztendlich wird ein "Beispiel" eine numerische Zahl oder Zahlen sein. Dieser Teil wird viel mehr mit Hardware zu tun haben, sodass er hier nicht wirklich zur Diskussion steht.

3 . Der Code prüft, ob er 10 aufeinanderfolgende Samples gespeichert hat, und sucht nach einem Lautstärkeanstieg, um anzuzeigen, dass ein Wort oder eine Phrase gesprochen wird (eine Pause von der Stille). Anschließend erhöht sich die Anzahl der aufeinanderfolgenden Samples, um beispielsweise 500 Samples zu sammeln. Dies würde bedeuten, dass 5 Sekunden Audio in 10-ms-Samples erfasst werden.

Es sind diese Samples oder "Slices", die zwischen dem gespeicherten Sound und dem aufgenommenen Sound verglichen werden. Wenn ein ausreichend hoher Prozentsatz der erfassten Proben mit den entsprechenden gespeicherten übereinstimmt, nimmt der Code an, dass es sich um dasselbe Wort handelt.

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. Sobald der Code einen vollständigen Sample-Stream gesammelt hat, schneidet er die leeren Samples zu Beginn ab, um die folgende Audioaufnahme zu erstellen. Es könnte auch das Sample-Set einige Stellen vor- und zurückbewegen, um eine bessere Ausrichtung mit dem gespeicherten Sample zu erzielen.

Dies erzeugt ein Beispielset wie das folgende:

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. Meiner Meinung nach unterscheidet sich Stichprobe 7 durch einen Prozentwert, der angibt, wie nahe jede Stichprobe sein muss, um einen Wert von 1, der unter% 1 liegt, und einen Prozentwert für die Gesamtzahl der Stichproben, die innerhalb des Prozentsatzes für die Stichprobenübereinstimmung liegen müssen hat der Code eine leicht einstellbare Genauigkeit.

Ich habe so etwas noch nie mit Audio gemacht, es könnte eine Menge Arbeit sein. Deshalb stelle ich diese Frage, wenn Sie vielleicht bereits wissen, dass die Antwort auf diese Frage offensichtlich ist (was auch immer diese Antwort sein mag). Ich hoffe, dass dies keine rechenintensiven Aufgaben sein werden, da ein Teil der Hardware, die ich verwenden werde, Low-Sec-Teile sein werden. In den Hunderten von Megahertz (vielleicht 1 GHz mit einem übertakteten Rasp Pi). Dies ist also eine ziemlich grobe Methode, um Audio-Samples mit geringerer Rechenleistung abzugleichen. Ich strebe keine sofortigen Ergebnisse an, sondern weniger als 30 Sekunden für einen anständigen Proof of Concept.

PS Ich habe keinen Mitarbeiter, der dies mit einem neuen Tag wie "Audio", "Audioerkennung", "Stimme", "Spracherkennung" usw. kennzeichnet.


17
VR ist verdammt komplex und ich bezweifle, dass jemand ohne Fachkenntnisse in der Lage sein wird, viel voranzukommen, ohne viel zu lesen. Das Erste, was mir an Ihrem Algorithmus auffällt, ist, dass er keine Unterschiede in der Sprachgeschwindigkeit eines Wortes berücksichtigt. Sogar einfache VR brauchte Jahre, um richtig zu werden.
Gort the Robot

4
Tatsächlich. Sie möchten, sofern Sie sich nicht um Jahre in der Entwicklung gekümmert haben, möglicherweise nach Bibliotheken suchen, die Sie für Ihr Ziel kompilieren können. Ich bin sicher, dass sie existieren.
Rig

6
Ich würde einen zusätzlichen Schritt vorschlagen - machen Sie eine Fourier-Transformation von jedem Sample. Dies gibt Ihnen die Intensität jeder Audiofrequenz über die Zeit, anstatt sich direkt mit den Samples zu befassen. Es wird eine einigermaßen konsistente Grundfrequenz für Vokale geben, mit der Sie normalerweise sprechen und die Sie erkennen können. Sie müssen die spezifischen Merkmale der Sprache betrachten, nicht nur die der Audiodaten. Wie andere gesagt haben, ist dies eine schwierige Aufgabe.
Paul Anderson

1
Ich würde vorschlagen, dass Sie versuchen, mit einigen Spracherkennungsbibliotheken herumzuspielen, auch wenn Sie sie nicht für das Endprodukt verwenden können. Sie wären nützlich, um einen Proof of Concept zu erstellen.
15.

Antworten:


3

Nun, ich glaube nicht, dass der Arduino die Pferdestärke hat, um dies zu tun. Sein Betrieb bei 16 MHz Ein Arduino verfügt über etwa 32 KB Speicher. Sogar 20 in Mp3 gesampelte Wörter (kleiner als wav) würden nicht hineinpassen, obwohl es nur Ihre eigene Stimme ist.

Das rasberi pi könnte den Trick machen, es arbeitet mit 700 MHz, abhängig von der Version, in der es 512 MB Speicher hat. Das ist immer noch nicht viel Teig.

Möglicherweise benötigen Sie einen Fourier ( http://www.drdobbs.com/cpp/a-simple-and-efficient-fft-implementatio/199500857 )

Oder wenn Sie beabsichtigen, Volumen zu verwenden, machen Sie ein paar Mittelwerte mit vorherigen Stichproben wie
x = (x + x [n-1] + x [n-2] + x [n-3]) / 4 // das ist vielleicht ganz einfach brauche mehr

Als Nächstes müssen Sie diese X-Werte zeichnen. Dann benötigen Sie eine Art Neigungserkennung für diese Linie, da das Erkennen von Befehlen basierend auf der Lautstärke ansonsten stark von der Entfernung abhängt die Wörter

Dann kommt es ein bisschen darauf an, wie man die Steigung aufzeichnet, damit das Muster zu einem anderen Zeitpunkt passt. Ich meine, man spricht nicht in dem exakten Tempo, mit dem ein Computer mithalten kann, und die Steigung kann etwas steiler sein. Am Ende denke ich, dass dies ein bisschen ist, wie steil diese Linien sind und ihre Länge y-Achse sollte innerhalb eines Durchschnitts liegen


1
  1. Arduino und Raspberry Pi sind Prototyping-Boards mit kleinen Chips. Sie sollten sich zuerst auf den Chip konzentrieren. Suchen Sie nach etwas mit einer DSP-Toolbox (Digital Signal Processing). Vielleicht haben Sie bereits eine DSP-Toolbox und wissen es nicht. DSP-Toolboxen verfügen über Algorithmen wie fft (Fast Fourier Transformation) und ifft (Inverse Fft) zur schnellen Frequenzbereichsanalyse.

  2. Konzentrieren Sie sich auf Ihren programmatischen Stil: Befinden sich Ihre Samples in einem Stapel oder in einer Warteschlange? Sie benötigen eine Warteschlange für diesen Datentyp. Eine Warteschlange sieht folgendermaßen aus:

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

    Nächste Iteration:

    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)
    

    Beachten Sie, wie sich die Dinge nach rechts verschieben? Ich denke, Sie haben einen "zirkulären" Algorithmus beschrieben. Überschreiben Sie einfach die ältesten Samples mit den zweitältesten Samples und überschreiben Sie dann die zweitältesten Samples mit den drittältesten ... bis zum Anfang der Warteschlange, an der Sie Ihre neuesten Daten einfügen.

  3. "Der Code entnimmt kontinuierlich Abtastwerte fester Länge, beispielsweise 10 ms" <- falsch Gehen Sie folgendermaßen vor: Der Code entnimmt diskret quantisierte (Höhen-) Abtastwerte mit einer Abtastrate von 10000 Abtastwerten pro Sekunde, wodurch jeder Abtastwert einen Abstand von 0,1 ms aufweist.

    Was ist Ihre Abtastfrequenz? Wie hoch ist die Bitrate Ihres Quantisierers? Niedrigere Zahlen helfen Ihnen dabei, Speicher freizugeben. Ich würde eine niedrige Abtastrate wie 6600 Abtastungen pro Sekunde (Nyquist) vorschlagen. Ich vermute, dass 4 Bit (16 Stufen) für die Erkennung ausreichen würden. Das sind also 3300 Bytes Aufnahme pro Sekunde. Jetzt mach fft und lösche alles über 3300 Hz (Telefoniefilter). Jetzt haben Sie 1650 Bytes für eine Sekunde Sound. Diese DSP-Tricks sparen viel Speicher.

    Ich weiß nicht, wer 512 MB für klein hält. Mit den oben genannten Informationen, die 300.000+ Sekunden der Aufnahme sind ... über 3 Tage hinweg solide.

  4. Ich denke, Sie werden feststellen, dass der Frequenzbereich (mithilfe von fft) eine bessere Umgebung für die Spracherkennung darstellt.

Ich hoffe, ich habe dich nicht noch schlimmer verwirrt :)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.