Florian Steurer

Florian Steurer

Florian ist Softwareentwickler und am liebsten im Backend zu Hause

29.10.2021 | 6 min Lesezeit

Musik komponieren - mit Machine Learning

Musik komponieren - mit Machine Learning blog image

Das machinelle Lernen befasst sich mit der Erstellung von Modellen zur Vorhersage unbekannter Werte durch mathematisch fundierte Verfahren. Was zunächst nach trockener Logik klingt, kann jedoch auch in kreativen Domänen wie der Malerei oder der Dichtung überzeugende Ergebnisse generieren.

In diesem Blog möchten wir Techniken des machinellen Lernens verwenden um Musik zu generieren. Dabei verschaffen wir uns außerdem einen Überblick über den operativen Betrieb von Machine-Learning-Lösungen und über das Azure Machine Learning Studio, welches uns dabei unterstützen soll.

MLOps und Azure Machine Learning Studio

Auch abseits der mathematischen Hintergründe, bringt die Entwicklung und der Betrieb von Machine-Learning-Lösungen einige Herausforderungen mit sich. In der Praxis werden ML-Modelle in einem iterativen Prozess stetig verbessert um kontinuerlich bessere Lösungen bereitstellen zu können. In Anlehnung an DevOps, wird dieser operative Prozess als MLOps bezeichnet. Das Vorgehen dabei, lässt sich im Wesentlichen in folgende Schritte aufteilen

  • Daten sammeln
  • Daten analysieren und vorberarbeiten
  • Trainieren des Modells
  • Evaluation des Modells
  • Deployment des Modells

Mit dem Azure Machine Learning Studio bietet Microsoft eine gehostete Umgebung an, die ihre Nutzer im gesamten Lebenszyklus eines Modells unterstützten soll und zwar zum Großteil ohne Programmcode schreiben zu müssen. Dieses Tool wollen wir auszuprobieren, um einem neuronalen Netz Musik beizubringen.

Formulierung des Problems

Unser Ziel ist es also, Musik mit Hilfe maschinellen Lernens zu generieren. Dazu benötigen wir zunächst eine Formulierung des Problems, auf welche maschinelles Lernen anwendbar ist. Beim maschinellen Lernen wird ein Modell f gesucht, welches aus den sogenannten Features x_i ein Label y vorhersagt.

f(x_1, x_2, ... x_n) = y

Bei den Features handelt es sich also um die Eingaben welche das Modell der Vorhersage y verwendet. In unserem Fall wollen wir aus den letzten Noten x_1 bis x_n eines Lieds die darauf folgende Note x_(n+1) vorhersagen. Die vorangehenden Noten sind also unsere Features, die folgende Note unser Label. Anschließend können wir die Noten x_2 bis x_(n+1) verwenden um die nächste Note x_(n+2) zu bestimmen. Da wir keine beliebigen Zwischentöne zulassen sondern mit diskreten Noten arbeiten, handelt es sich um ein Klassifikationsproblem.

Daten sammeln und vorbearbeiten

Bevor wir uns auf die Suche nach einem Modell machen können, benötigen wir zunächst einmal geeignete Trainingsdaten. In unserem Fall haben wir uns für Notenblätter von Mutopia entschieden, genauer für die Sammlung von Scott Joplins Piano Rags. Die Notenblätter enthalten Noten wie z.B. d4. Hierin sind Tonhöhe (d) sowie Tonlänge (4, also eine Viertelnote) kodiert. Ein anderer Ansatz ist z.B. die Daten aus Midi-Dateien zu extrahieren.

Die Beschränkung auf eine Stilrichtung bzw. einen Komponisten soll die Konsistenz der Daten erhöhen und es dem Modell erleichtern Zusammenhänge zu lernen. Dadurch wird auch die Menge der Trainingsdaten eingeschränkt, was sich negativ auf die Qualität des Ergebnisses auswirken kann. Da wir aber nur mal "reinhören" möchten, haben wir uns für den weniger aufwändigen Weg entschieden.

Um die Konsistenz der Daten weiter zu erhöhen, verwenden wir nur die Melodiestimme der Musikstücke. Außerdem wurden alle Stücke mithilfe von LilyPond in die gleiche Tonart transponiert. Anschließend generieren wir eine Liste aller Noten-Subsequenzen mit Länge 13, um damit unser Machine-Learning Modell trainieren zu können.

Den Datensatz laden wir im Machine-Learning Studio hoch. Interessant ist auch die Möglichkeit z.B. eine SQL-Datenbank anzubinden, sodass neue Datensätze bei jeder Iteration automatisch in das Training des Modells einfließen.

Trainieren des Modells

Um die Klassifikation der Notensequenzen durchzuführen, entscheiden wir uns für ein neuronales Netz. Im Pipeline Designer bauen wir eine einfache Trainingspipeline, die unser Modell mit den Daten trainiert. Der Tune Model Hyperparameter Schritt erlaubt es mehrere Modelle mit verschiedenen Lernraten und Anzahl Lerniterations zu trainieren und beste auszuwählen. Negativ fällt auf, dass sich die Anzahl der Neuronen und verstecken Schichten im Designer nicht variieren lässt.

Training Pipeline

Die Auswahl des besten Modells erfolgt dann anhand einer Metrik wie z.B. Accuracy, also das Verhältnis von korrekten Vorhersagen zu allen Vorhersagen. Da wir allerdings Musik generieren, sind diese Metriken nur bedingt aussagekräftig, denn guter Klang lässt sich kaum quantifizieren ;)

Deployment des Modells

Das fertige Modell kann mithilfe von Azure Machine Learning Studio mit ein paar Klicks auf eine Container-Instanz deployed werden. Auch Azure Kubernetes Cluster ist als alternatives Deployment-Ziel verfügbar. Das Modell als Service kann anschließend sehr einfach aufgerufen werden.

In einem Softwareprojekt ist ein Modell allerdings meist nur eine Komponente unter vielen. Um das Deployment des Modells nicht separat von anderen Komponenten verwalten zu müssen, bietet sich z.B. eine Integration in Azure DevOps an.

Beispiel Musik

Und wie hört sich nun das Ergebnis an?

Gar nicht so schlecht! Man erkennt das zugrunde liegende Genre und auch die Anzahl schiefer oder deplatzierter Töne hält sich in Grenzen. Das Ganze klingt allerdings noch sehr uninspiriert. Vielleicht lässt sich das Ergebnis ja noch verbessern.

Der obere Song-Schnipsel wurde von einem neuronalen Netz mit 50 Neuronen generiert. Als Trainingsdaten wurden Sequenzen der Länge 13 (12 Features + Label) genutzt. Was passiert wenn wir stattdessen 250 Neuronen und Sequenzen der Länge 37 zum Training verwenden?

Dieser Song hört sich schon "kreativer" an. Man erkennt allerdings auch das bestimmte Sequenzen aus den Trainingsdaten reproduziert wurden, so erinnert der Anfang z.B. an das Lied "Entertainer". Hier zeigt sich, die Schwierigkeit die Parameter des Modells so zu wählen, dass es nicht nur die Trainingsdaten auswendig lernt (Overfitting), sondern aus den Zusammenhängen in den Daten Neues generieren kann.

Fazit

Azure Machine Learning Studio eignet sich gut zur schnellen Durchführung kleinerer Experimente. Über einen Designer lassen sich Trainings- und Interferenzpipelines erstellen, mit deren Hilfe einfache Probleme ohne Programmcode gelöst werden können. Es ist jedoch fraglich, ob sich dieser Ansatz auch für komplexere Projekte bewährt. Vermutlich wird man eigenen Programmcode zur Datenverarbeitung, Training und Evaluation nicht vermeiden können. Dafür wurden Jupypter Notebooks integriert. Auch die Dokumentation lässt manchmal zu wünschen übrig, sobald die Probleme ins Detail gehen. Desweiteren gibt es keine Versionierung der Pipelines über die Oberfläche.

Dennoch hat die Verwaltung des gesamten Modelllebensyzyklus im Sinne von MLOps großes Potenzial. Hoffentlich schafft es das Machine Learning Studio dieses Potenzial in Zukunft voll auszuschöpfen und sich so im Azure Kosmos als wichtiges Werkzeug zu etablieren.

Die generierte Musik klingt überraschend gut. Komplexere Eigenschaften wie Songstruktur, Stimmungs- oder Tonartwechsel konnte die KI, auch durch die geringe Menge an Trainingsdaten, nicht erfassen. Außerdem stellt sich natürlich Frage wieviel "Kreativität" oder "Neues" in den Songschnipseln steckt. Für mich persönlich ein spannendes Projekt, bei dem ich einiges über Musik und Machine Learning lernen konnte.