Unüberwachte Vokalklassifikation mit
Serial Competition Vektorquantisierung

Bericht zum Praktikum Neuronale Netze im Sommersemester 2000

Universität Osnabrück

Frank Jäkel, Beate Schwichtenberg,

Zusammenfassung:

Wir stellen einen Algorithmus zur unüberwachten Vektorquantisierung vor: Serial Competition Vektorquantisierung. Dieser Algorithmus ist charakterisiert durch serielle Bearbeitung der Codebookvektoren und Codebookvektor-spezifische Lernraten. Wir verwenden ihn zur sprecherabhängigen Klassifizierung von Vokalen. Das Clustering erfolgt im hochdimensionalen Frequenzraum. Wir erhalten überzeugende Ergebnisse.

 

Einleitung

Direkte natürlichsprachliche Eingabe ist die Methode, in der wir mit den Computern der Zukunft kommunizieren werden. Dazu braucht es robuste und sprecherunabängige Spracherkennungssysteme. Lautklassifizierung ist der erste, entscheidende Schritt im Spracherkennungsprozess, denn die folgenden Verarbeitungsschritte (insbesondere die Worthypothesenbildung) basieren darauf, dass die einzelnen Laute möglichst genau erkannt werden. Wir stellen hier ein auf Vektorquantisierung basierendes System zur Vokalklassifizierung vor.

Phonetischer Kurzüberblick

Vokalcharakteristika sind in der Phonetik bereits gut untersucht worden. Die phonetischen Grundlagen zur Wellenstruktur von Vokalen erläutern wir am Beispiel des Vokals a (Bild 1).

Die Schallwelle eines gesprochenen langen a ist sehr regelmäßig. In gleichmäßigen Abständen treten hohe Erhebungen auf, gefolgt von sehr vielen etwas weniger ausgeprägten Erhebungen. Diese Regelmäßigkeit zeigt sich auch in der Spektralansicht: einige Frequenzbänder sind sehr stark ausgeprägt, andere gehen fast völlig unter.

Die Phonetik hat diese auffälligen Strukturen benannt: Die unterste merkliche Erhebung (bei ca. 100 Hz) stellt die Grundfrequenz F0 dar (das akustische Korrelat ist die Stimmhöhe). Die beiden stark ausgeprägten Erhebungen bei ca. 900 Hz und 1300 Hz sind die beiden untersten Formanten (Amplitudenmaxima) F1 und F2. Es gibt bei höheren Frequenzen weitere Formanten, die aber viel weniger stark ausgeprägt sind.

Formanten gibt es bei jedem Vokal. Sie liegen jeweils an einer für den Vokal charakteristischen Stelle, die durch die Form der Artikulationswerkzeuge (Mundraum, Rachenraum, Zunge) festgelegt ist. Die Lage der Formanten ist von Sprecher zu Sprecher relativ gleich. Zwar treten aufgrund der unterschiedlichen Anatomie geringfügig unterschiedliche Formantenlagen auf; diese Unterschiede sind aber nicht groß genug, als dass sie das allgemeine Bild stören würden. Nur der Geschlechterunterschied zeigt sich (aufgrund der höheren Stimme der Frau) deutlich – dort verschieben sich Grundfrequenz und Formanten bei Beibehaltung der Gesamtstruktur insgesamt auf höhere Frequenzen.

In der Phonetik werden die beiden untersten Formanten für die Vokalklassifizierung verwendet.

Klassifizierungsansatz

Herkömmliche automatisierte Verfahren verwenden die Formanten zu Klassifizierung, d.h. die Formanten werden in einem Vorverarbeitungsschritt bestimmt und dienen dann als Eingabedaten zur Vektorquantisierung (oder eines anderen Lernverfahrens).

Wir verzichten auf diesen Vorverarbeitungsschritt, denn auch in den anderen Frequenzen mag entscheidende Information kodiert sein, die wir durch eine Formantenextraktion verlieren. Vor allem ist unser Ansatz somit potentiell auf andere Lautgruppen als Vokale übertragbar, in denen keine Formanten auftreten. Wir verwenden Serial Competition Vektorquantisierung, einen unüberwachten Lernalgorithmus. Das heißt, der Algorithmus muss die Eingabevektoren in der Trainingsphase selbstständig in Klassen einordnen; wir können Fehlklassifizierungen in der Trainingsphase also nicht korrigieren.

Wir erwarten, dass Laute innerhalb der gleichen Klasse zueinander ähnlicher sind als Laute anderer Klassen und dass sich bei der Vektorquantisierung für jeden Laut als Codebookvektor ein für diesen Laut prototypisches Frequenzspektrum ergibt.

Im folgenden stellen wir zunächst den Serial Competition Vektorquantisierungsalgorithmus vor. Diesen Algorithmus verwenden wir für eine Vokalklassifikationsaufgabe und schließen mit einem Ausblick auf die möglichen Erweiterungen unseres Ansatzes.

Der Serial Competition Vektorquantisierungsalgorithmus

Glücklich ist, wer weiß, wie viele Cluster tatsächlich in den zu lernenden Daten vorhanden sind. Aber selbst wenn man die Anzahl der Cluster kennt ergeben sich beim unüberwachten Clustering Probleme, die nicht nur daher rühren, ob die Cluster in den Daten tatsächlich scharf trennbar sind. In jedem Fall muss man nach dem Lernen überprüfen, welcher der gelernten Codebookvektoren denn welchem Cluster zugeschlagen wurde.

Angenommen, wir wollen die Zentren von zwei Clustern lernen und benutzen einen herkömmlichen Algorithmus zur Vektorquantisierung mit zwei Codebookvektoren. Am liebsten wäre es uns, nun je einen Codebookvektor als Repräsentanten für die Cluster zu haben. Unter ungünstigen Bedingungen kann es aber passieren, dass ein Codebookvektor gar nichts lernt, der andere aber zwischen den beiden Clustern sitzt. Genau so schlimm ist es auch, wenn beide Codebookvektoren das gleiche lernen. Wie kann man also sicherstellen, dass alle Codebookvektoren etwas lernen, aber möglichst nicht mehrere das selbe? Wenn man mehr Codebookvektoren spendiert als Cluster in den Daten sind, werden sich diese Probleme nur schwer vermeiden lassen.

Inspiriert durch diese Problematik und in Anlehnung an bekannte Vektorquantisierungsalgorithmen haben wir einen Algorithmus entworfen, der den oben erwähnten Problemen Rechnung trägt. Die Hauptidee ist für jeden Codebookvektor ci eine eigene Lernrate ri zu benutzen, und diese abhängig vom Lernerfolg zu verringern.

Serielles Ranking

Der Algorithmus bekommt einen Datenpunkt d und ordnet die Codebookvektoren entsprechend ihrem Abstand zu d. Dabei wird jedem Codebookvektor ci entsprechend dem Abstand von d eine Ordnungszahl oi(d) zwischen 1 und der Anzahl der Codebookvektoren zugewiesen. Der dem Datenpunkt am nächsten liegende Codebookvektor erhält die 1. Haben zwei Codebookvektoren ci und ck den gleichen Abstand zu d, erhalten sie seriell ihre Ordnungsnummern: In diesem Fall ist ok(d) = oi(d) + 1 (für k > i).

Änderung der Codebookvektoren

Als nächstes werden alle Codebookvektoren nach der folgenden Regel geändert:

ci := ci + (d - ci) * pow(ri, oi(d)*oi(d))

Somit werden alle Codebookvektoren in Richtung des Eingabevektors d gezogen, wobei die Ordnungszahl quadratisch in den Exponenten der Lernrate eingeht. Jetzt sollte gewährleistet sein, dass kein Codebookvektor armselig an seinem Startpunkt verkümmert. Dafür läuft man jedoch Gefahr, dass alle Codebookvektoren nur von einem Cluster angezogen werden.

Änderung der Lernrate

Deswegen ändern wir nur die Lernrate von dem Codebookvektor, der am nächsten an der Eingabe war.

ri := ri * a, falls oi(d) = 1
ri := ri, sonst

Dabei ist a der Kühlungsfaktor, der bestimmt, wie schnell das Verfahren konvergieren soll (0 < a < 1). Dadurch, dass nur der Codebookvektor, der der Eingabe am nächsten ist, seine Lernrate ändert, ist es auch unproblematisch, dass die anderen Codebookvektoren "irrtümlich" in die Richtung des Eingabevektors gezogen wurden, weil sie ja durch ihre unveränderte Lernrate weiterhin beweglich bleiben.

Voraussetzung: Randomisierung der Daten

Ein Problem ergibt sich trotzdem noch, wenn zwei oder mehrere Codebookvektoren abwechselnd am nächsten zu einem Cluster sind und sich somit fälschlicherweise mehrere Codebookvektoren in der Nähe eines Clusters abkühlen. Um diesen Effekt zu vermeiden, müssen die Daten gut gemischt sein. Im Extremfall zeigt man dem Algorithmus sonst als erstes nur Instanzen eines Clusters, zu dem über kurz oder lang alle Codebookvektoren hingezogen werden und ihre Beweglichkeit dort verlieren.

Versuchsverlauf und Ergebnisse

Wir verwenden die Serial Competition Vektorquantisierung, um die Korrelation zwischen Frequenzspektrum und Lautklasse zu lernen. Wir wollen also für jeden Vokal einen prototypischen Codebookvektor lernen, der die für diesen Laut typische Frequenzverteilung besitzt.

Datengewinnung und Vorverarbeitung

Die Trainingsdaten für unser Netz sind gesprochene Vokale. Wir haben von einem Sprecher (männlich) jeweils drei Aufnahmen (je ca. 1 Sekunde) eines Vokals zu Trainingszwecken und eine Aufnahme pro Vokal zu Testzwecken aufgezeichnet. Wir nehmen die Sprachdaten mit einer Samplingrate von 8000 Samples/Sekunde und einer Genauigkeit von 16 bit auf. Dabei benutzen wir kein spezielles Mikrophon und haben auch keine besonders ruhige Umgebung, so dass unsere Daten stark verrauscht sind – wie es in der Anwendung auch der Fall sein wird.

Die Daten werden als Wavefiles gespeichert. Mit Hilfe von sox (Sound Exchange Programm) wandeln wir sie in Textfiles um, auf denen die Vorverarbeitung durchgeführt wird. Bei so stark verrauschten Daten ist die Vorverarbeitung ein entscheidender Faktor, von dem der Erfolg des Algorithmus entscheidend abhängt. Deswegen beschreiben wir die Vorverarbeitung hier ausführlicher.

Erster Schritt der Vorverarbeitung ist ein Rauschfilter. Der Algorithmus geht die Daten fensterweise durch, und setzt alle Samples in einem Fenster, dessen durchschnittliche Energie einen Schwellwert unterschreiten, auf 0. Diese Art der Rauschfilterung ist bei unseren Daten sehr zuverlässig, da Vokale als stimmhafte Laute eine insgesamt sehr hohe Energie haben.

In einem Normalisierungsschritt setzen wir die maximale Amplitude auf den Standardwert 1, indem wir alle Samples durch die maximale Amplitude teilen. Dies gleicht Unterschiede in der Lautstärke der Daten aus, die durch unterschiedlichen Abstand zum Mikrophon bei den einzelnen Aufnahmen usw. bedingt sind. Allerdings wird über die gesamte Eingabedatei normalisiert, so dass es immer noch innerhalb eines Vokals zu unterschiedlichen Lautstärken kommen kann.

Mit Hilfe eines FFT-Algorithmus trennen wir die Daten fensterweise in einzelne Frequenzen auf. Das ermöglicht die Analyse des Frequenzspektrums. Entscheidend bei der FFT sind die Wahl der Fenstergröße und der Überlappung der Fenster gegeneinander. Wir haben unser Fenster mit 128 ms eher groß gewählt. Um dennoch genaue Werte zu erhalten, verschieben wir den Fensteranfang jeweils nur um 10 ms.

Diese geringe Verschiebung nutzen wir aus, um die Daten zu glätten: Wir berechnen jeweils den Durchschnitt aus 7 benachbarten Fenstern. Die in einem Fenster berücksichtigten Daten mitteln über 200 ms des Sprachsignals, wobei nur die Werte in einem Intervall von 68 ms mindestens vierfach eingehen. Wir haben also – immer noch mit der gleichen Überlappung wie nach der Fouriertransformation – Durchschnittswerte, die die Ungenauigkeiten der diskreten Fouriertransformation (die von der Lage des Fensters auf den Daten und dem Abstand der einzelnen betrachteten Frequenzen zueinander herrühren) innerhalb eines Vokals gut ausgleichen.

Es hat sich gezeigt, dass die tiefsten Frequenzen (bis ca. 40 Hz) sehr stark ausgeprägt sind. Sie sind nicht interessant für die Vokalerkennung, sondern stellen einen Störeffekt dar (Mikrophonrauschen bzw. Ventilatorgeräusche), der die Klassifizierung erheblich beeinflusst. Deswegen streichen wir alle Frequenzen unter 40 Hz.

Ein letzter Glättungsschritt soll den Frequenzvariationen in der Grundfrequenz, die in gesprochener Sprache als Intonation auftreten, Abhilfe schaffen: Durch Berechnung eines gewichteten Mittels über jeweils 7 benachbarte Frequenzen (ca. 50 Hz) erreichen wir eine Verteilung der ausgeprägten Grundfrequenzamplitude auch auf die umliegenden Frequenzen.

Für das Training der Daten bringen wir die geglätteten Fenster in eine zufällige Reihenfolge. Dadurch haben wir Rauschen und tatsächliche Vokaldaten in beliebiger Reihenfolge. Rauschen macht etwa 50% der Daten aus. Insgesamt haben wir, trotz aller Vorverarbeitung, für unsere Klassifizierung sehr stark verrauschte Daten.

Durchführung

Die Eingabedaten für den Algorithmus bestehen aus 512-dimensionalen Vokalspektren, die wie eben beschrieben aufbereitet sind, wobei jeder Dimension eine Frequenz aus der diskreten Fouriertransformation entspricht. Bei einer Samplingrate von 8000 Hz steht jede Dimension für eine Frequenz zwischen 0 und 4000 Hz.

Wir trainieren unser Netz in 20 Trainingszyklen mit 6 Codebookvektoren: je einer pro Vokal und einer für das Rauschen. Der Kühlungsfaktor ist mit 0.99 vorgegeben.

Ergebnisse

Wir können im folgenden keine genaue Abschätzung des Fehlerverlaufs bieten. Das liegt in der Natur eines nicht überwachten Lernalgorithmus: wir kennen zwar unsere Erwartung für die Ergebnisse und können entscheiden, ob das Netz Eingabedaten unseren Erwartungen entsprechend klassifiziert, aber wir wissen nicht, welche Merkmale das Netz tatsächlich zur Klassifizierung verwendet. Deshalb im folgenden keine Prozentzahlen, sondern nur eine visuelle Aufbereitung der Lernergebnisse.

Auf den Trainingsdaten stellt sich eine sehr gute Klassifizierungsleistung des Netzes heraus. Die Codebookvektoren wurden von uns per Hand aufgrund der Trainingsergebnisse den Vokalklassen zugeordnet. Für jeden Vokal ist ein eigener Codebookvektor zuständig, der sechste Codebookvektor detektiert Rauschen. Allein der Vokal u (mit dem wir in jedem Trainingsverlauf Schwierigkeiten hatten – liegt das an den Daten?) ist in wenigen Fällen als i klassifiziert worden.

Beim Test des Netzes auf untrainierten Daten zeigt sich das gleiche Bild (siehe Bild 2): Die Codebookvektoren klassifizieren auch ungelernte Daten einwandfrei. Kleine Fehler ergeben sich bei der Klassifizierung von o und u, die aber das gesamte Bild nicht stören.

Wenn man einen Codebookvektor (zum Beispiel für das e, siehe Bild 3), mit einem typischen Eingabefrequenzspektrum vergleicht stellt man fest, dass die Kurvenverläufe fast identisch sind. Der Algorithmus hat – unseren Erwartungen entsprechend – prototypische Laute als Codebookvektoren erzeugt. Insgesamt haben wir also sehr gute Klassifikationsergebnisse erhalten.

Diskussion

Wir haben ein Vokalklassifikationssystem entwickelt, dass wir durch unüberwachtes Lernen trainieren. Wir haben dabei trotz der Schwierigkeit, mit stark verrauschtem Datenmaterial und in einem hochdimensionalen Vektorraum arbeiten zu müssen, gute Ergebnisse erzielt. Unser Ansatz ist insofern neu, als dass wir nicht auf die Annahme zurückgreifen müssen, die beiden Formanten F1 und F2 alleine enthielten alle für die Klassifikation notwendigen Informationen.

Serial Competition Vektorquantisierung liefert bereits überzeugende Resultate. Einige Optimierungsmöglichkeiten sind aber dennoch gegeben:

Unser Ansatz funktioniert erst ansatzweise mit Daten in unterschiedlicher Lautstärke. Insbesondere ist es problematisch, wenn sich innerhalb eines Vokals die Lautstärke ändert, so dass der Lautstärkenormalisierungsschritt in der Vorverarbeitung nicht greift.

In der Vektorquantisierung wird üblicherweise mit dem euklidischen Abstand gearbeitet. In dieser Metrik haben alle Dimensionen den gleichen Unterschied zueinander. Das heißt es spielt in der Abstandsmessung keine Rolle, ob zwei Maxima in benachbarten Frequenzen oder weit voneinander entfernt auftreten. Das stimmt mit unserem Datenmaterial aber nicht gut überein: Ein Formant tritt nicht immer genau an der gleichen Stelle auf. Eine Schwankung um einige Hertz ist für Sprachdaten normal. Es wäre zu überlegen, ein anderes Abstandsmaß zu verwenden, in dem die Frequenz mit in die Abstandsberechnung eingeht.

Es bleibt zu testen, ob Serial Competition Vektorquantisierung auch andere Laute (stimmhafte und insbesondere stimmlose Konsonanten) genauso gut klassifiziert und somit als Eingabemodul in einem Spracherkennungssystem dienen kann.

Literatur

Hammer, Barbara (1999). WS 1999 Vorlesung und Skript zur Vorlesung "Neuronale Netze", Uni Osnabrück.

Jurafsky, Daniel & Martin, James (Draft of June 1999). Speech and Language Processing. New Jersey: Prentice Hall.

Langer, Hagen (1999). Vorlesung Einführung in die Computerlinguistik, Uni Osnabrück und persönliche Kommunikation.

Machelett, K. & Tillmann, H.G.. Das Lesen von Sonagrammen V0.2 http://www.phonetik.uni-muenchen.de/SGL

Zell, Andreas (1997). Simulation Neuronaler Netze. München: Oldenbourg Verlag.

Bild 1

Bild 2

Bild 3