KI & Daten

SchlagerAI - Automatische Generierung von Schlagertexten anhand von Sprachmodellen

Wie wir Sprachmodelle zur automatischen Generierung von Schlagertexten eingesetzt haben. Bei unserem internen Hackathon haben wir SchlagerAI entwickelt - lesen Sie, was wir dabei gelernt haben.

August 2021
23
min Lesezeit
Daniel Wessel
Machine Learning Specialist
AI Cluster Lead bei Motius
Diesen Beitrag teilen

Mitte 2019 haben wir einen ersten Versuch unternommen, ein Modell zur Generierung von Schlagertexten zu erstellen. Für diejenigen unter Ihnen, die Schlager nicht kennen: Es handelt sich um einen Stil der europäischen Popmusik, der vor allem in Deutschland bekannt ist. Man findet ihn normalerweise auf dem Oktoberfest, in Après-Ski-Bars und an den Stränden Mallorcas. Er ist lustig, eingängig und hat oft einfache Texte, die Themen wie Liebe, Party und das aktuelle Zeitgeschehen behandeln. Während unseres ersten SchlagerAI-Projekts haben wir uns nicht so sehr auf das eigentliche Modell konzentriert, sondern vielmehr auf den Aufbau einer Trainings-, Evaluierungs- und Einsatzpipeline. In unserer jüngsten Entdeckungssitzung wollten wir unsere Arbeit an SchlagerAI wieder aufgreifen und aktuelle Fortschritte in der natürlichen Sprachgenerierung (NLG) integrieren.

Genauer gesagt, haben wir die im Modell-Repository von HuggingFace veröffentlichten, vortrainierten Sprachmodelle genutzt, um Schlager in deutscher Sprache zu generieren. In den folgenden Abschnitten werde ich dich durch den Prozess der Erstellung deines eigenen Modells zur Generierung von Liedtexten führen.



Schritt 1: Finden eines vortrainierten Modells

In den letzten Jahren hat die Transformers-Bibliothek von HuggingFace durch ihre Open-Source-Implementierungen von State-of-the-Art-Architekturen für die Verarbeitung natürlicher Sprache (NLP) viel an Popularität gewonnen. Darüber hinaus bietet die Bibliothek eine Drehscheibe für die gemeinsame Nutzung von Modellgewichten und Datensätzen, wodurch die Entwicklung von NLP-Anwendungen, die die neuesten Fortschritte nutzen, für Industrie und Forschung gleichermaßen zugänglicher geworden ist.

Aufgrund der riesigen Datenmengen und der hohen Rechenleistung, die für ein adäquates Training eines Sprachmodells erforderlich sind, haben wir uns entschlossen, in der Modell-Drehscheibe nach Implementierungen von Textgenerierungsmodellen zu suchen, die auf einem deutschen Korpus trainiert wurden. Glücklicherweise bietet die Modell-Drehscheibe Filter für Aufgaben (Texterzeugung) und Sprachen (de), so dass es recht einfach war, unser Suchfeld einzugrenzen.

Nachdem wir unsere Optionen geprüft hatten, entschieden wir uns für das Modell dbmdz/german-gpt-2, das vom Team der Digitalen Bibliothek des Digitalisierungszentrums München der Bayerischen Staatsbibliothek (DBMDZ) bereitgestellt wurde. Da wir uns für die Arbeit mit der aitextget-Bibliothek entschieden haben (siehe Schritte 4 und 5), benötigten wir ein gpt-2-Modell, da die aitextgen-Bibliothek gut mit gpt-2-Modellen zusammenarbeitet. Die von DBMDZ zur Verfügung gestellten Modellgewichte wurden durch Training mit "einem aktuellen Wikipedia-Dump, dem EU Bookshop-Korpus, Open Subtitles, CommonCrawl, ParaCrawl und News Crawl" erzeugt. Der Datensatz besteht aus 16 GB Daten und hat über 2 Milliarden Token.

Dieses Sprachmodell dient als Ausgangspunkt für den Aufbau unseres SchlagerAI-Modells. Wenn man das dbmdz/german-gpt-2-Modell nach Text fragt, sieht die Ausgabe derzeit nicht sehr nach einem Schlager aus.  


Aufforderung:

[Intro]
Wir stehen an der Bar

Text:

[Intro]
Wir stehen an der Bar:
- Das Lokal ist vollgestopft mit Musik und Getränken, aber wir können auch noch Bier trinken.
Es wird eine Menge neuer Freunde geben...
- Ein Pub hat sich für einen Besuch eingerichtet -
wir werden bald nach London reisen!
Und wo kommt das hin?
- Das Pub ist eine halbe Stunde entfernt von den Theatern in Brighton.
Am Samstag Abend haben wir einen sehr interessanten Vortrag über die Geschichte des Londoner Clubs gehalten;
er war ein hervorragender Redner, er hat alles gegeben, was man sich für Theaterunterricht wünschen konnte.
Das Essen sollte echt toll sein, die Bar wäre super organisiert gewesen und würde uns sicherlich gefallen.
Auf jeden Fall wird es wieder ein Konzert am Sonntag morgen machen.
Mit dem Zug zurück nach London
Als wir die Stadt verlassen, fährt sie Richtung Westen ab:
In dem Viertel von Brighton, das wir "The Roadman" nennen, fahren wir auf die A2 und dann weiter bis zu den U-Bahnhöfen Kensington & Chelsea.
Nach 15 Minuten sind wir auf der Kings Road angekommen.
Hier gibt's eine ziemlich große Auswahl an großartigen Kneipen und Pubs.
Außerdem hat man hier einige der besten Restaurants auf der Welt und



Es ist klar, dass wir etwas tun müssen, damit der generierte Text wie ein Lied aussieht und klingt. In den nächsten Schritten werde ich Sie durch den Prozess der Abstimmung des Modells führen, um Text zu erzeugen, der als Lied durchgehen könnte.


...aber was ist ein Sprachmodell?

In seiner einfachsten Form ist ein Sprachmodell lediglich eine Methode zur Erstellung einer Wahrscheinlichkeitsverteilung über eine Folge von Token. Ein Token kann ein Wort, ein Teilwort oder auch nur ein Zeichen sein. Bei der Verwendung für NLG nimmt ein Sprachmodell eine Folge von Token als Eingabe und gibt eine Wahrscheinlichkeitsverteilung für das nächste Token oder die nächsten Token aus. Diese Verteilung können Sie dann für die stochastische Texterzeugung nutzen (siehe Schritt 5).

Der aktuelle Stand der Technik bei der Erstellung von Sprachmodellen nutzt die Transformer-Architektur (Beispiele sind die BERT- und GPT-Architekturen und ihre Ableitungen). Weitere Informationen darüber, wie sie funktionieren, finden Sie in diesem illustrierten Blog von Jay Alammar, der eine außergewöhnlich gute visuelle Einführung in das Thema bietet.  


Schritt 2: Erstellen eines Feinabstimmungsdatensatzes

Um unsere Ausgabe schlagerähnlicher zu machen, müssen wir einen großen Satz von Schlagertexten sammeln, um unser Modell zu verfeinern. Wenn du jedoch nicht bereits die komplette Diskografie der größten Schlagerhits der letzten Jahrzehnte im Kopf hast, wird es schwierig sein, manuell eine Liste von Liedern zu erstellen, die groß genug ist, um als Datensatz zu funktionieren. Deshalb wenden wir uns an Spotify und Genius, um Hilfe zu bekommen.

Spotify stellt Entwicklern eine Web-API zur Verfügung, die es uns ermöglicht, automatisch Informationen über Wiedergabelisten, Künstler und Lieder abzurufen. Mit spotipy (einem Python-Wrapper um die Entwickler-API) können wir einen Scraper erstellen, der uns dabei hilft, einen Satz von Schlagerkünstlern zu generieren, den wir dann an Genius weitergeben, um mit LyricsGenius die Songtexte ihrer Top-Songs zu erhalten. Im Folgenden wird Schritt für Schritt erklärt, wie man einen eigenen Datensatz für Liedtexte erstellt.


A. Registrieren für Spotify Web API

Registriere dich für die Spotify-Web-API und erstelle eine App, um die Anmeldedaten zu erhalten. Befolge die Schritte in der spotipy-Dokumentation für weitere Informationen.


B. Initialisiere die Spotify-API in einem Python-Skript


spotipy importieren

client_id = ""
geheim = ""

sp = spotipy.Spotify(
    auth_manager=SpotifyClientCredentials(
        client_id=client_id,
        client_secret=secret,
    )
)


C. Eine Wiedergabeliste auf Spotify finden und die Wiedergabelisten-ID abrufen

Navigiere im Spotify-Webplayer zu der Wiedergabeliste, die du scrapen möchtest.

---> open.spotify.com / playlist / < playlist_id >.


D. Titel und Interpreten aus einer Wiedergabeliste abrufen


def scrape_spotify_playlist(playlist_id):
    pl = sp.playlist(playlist_id)

    songs = []
    for item in pl["tracks"]["items"]:
        if not item["track"]["track"]:
            continue
        songs.append(
            {
                "artists": [artist["name"] for artist in item["track"]["artists"]],
                "name": item["track"]["name"],
            }
        )

    return songs

songs = scrape_spotify_playlist("<insert_playlist_id>")
</insert_playlist_id>


E. Registrierung für Genius API

Registriere dich, um deine Zugangstoken unter https://genius.com/api-clients zu erhalten.


F. Initialisieren


von lyricsgenius importieren Genius

token = ""

genius = Genius(token)
genius.skip_non_songs = True
genius.timeout = 10
genius.retries = 3


G. Scrape Songs für einen Künstler


def scrape_genius_artist(artist_name, num_songs=7):
    artist = genius.search_artist(
        artist_name,
        max_songs=num_songs,
        include_features=False,
        get_full_info=False,
    )

    for song in artist.songs:
        song.save_lyrics(f"data/raw/{song.id}", sanitize=False, overwrite=True)

artists = {song["artists"][0] for song in songs}
for artist_name in artists:
    scrape_genius_artist(artist_name)


Am Ende haben wir einen Datensatz unter data/raw, der aus jsons des folgenden Formats besteht (plus andere unnötige Schlüssel):


{
 "title": "Johnny D\u00e4pp (Ich will Mallorca zur\u00fcck)",
 "artist": "Lorenz B\u00fcffel",
 "lyrics": "[Refrain/Drop]\nD\u00e4pp, D\u00e4pp, D\u00e4pp, ..."
}


... aber was macht einen guten Datensatz aus?

  • Relevanz. Die Texte sollten aus deutschen Schlagern stammen. Natürlich gibt es auch Schlager, die Zeilen/Phrasen in anderen Sprachen enthalten, daher ist es nicht schlimm, wenn es einige Lieder mit englischer/anderer Sprache gibt. Dennoch solltest du keine Texte aus anderen Genres wie deutschem Metal oder schwedischer Volksmusik einbinden, da sie nicht repräsentativ für Schlagertexte sind.
  • Menge. Im Bereich der ML gibt es eine grobe Faustregel, die besagt, dass Ihr Modell mindestens eine Größenordnung mehr Beispiele trainieren sollte, als es trainierbare Parameter hat. Für unser Problem ist dies eine Herausforderung, da unser dbmdz/german-gpt-2-Modell über 125 Millionen trainierbare Parameter hat. Da das Modell bereits auf einem Datensatz von über 2 Milliarden Token trainiert wurde, kann der Datensatz für die Feinabstimmung glücklicherweise um Größenordnungen kleiner sein, wenn wir genügend Parameter in unserem Modell einfrieren (siehe Schritt 4 für eine Einführung in die Feinabstimmung). Wenn Sie jedoch die anderen Regeln zur Qualität des Datensatzes befolgen, wird ein größerer Datensatz die Leistung des endgültigen Modells nicht beeinträchtigen.
  • Breite. Nur Lieder eines bestimmten Künstlers zu haben, wäre interessant, wenn wir ein Modell für einen einzelnen Künstler bauen würden. Aber dieses Projekt heißt SchlagerAI, nicht HeleneFischerAI. Deshalb brauchen wir Beispiele von vielen verschiedenen Künstlern, um die Branche als Ganzes zu imitieren.


Schritt 3: Bereinigung unseres Datensatzes

Da wir nun die Texte aller Top-Schlager haben, müssen wir unseren Datensatz bereinigen, um qualitativ hochwertige Ergebnisse zu erhalten.  


A. JSON zu Text

Unsere Modelle können keine rohen JSONs als Eingabe verwenden, daher müssen wir einige Transformationen vornehmen, um sie besser nutzbar zu machen.


from pathlib import Pfad

raw_dir = Path("data/raw")
for filename in raw_dir.glob("*.json"):
    with open(filename) as f:
        print()
        Lied = json.load(f)
        lyrics = song["lyrics"]

        print(lyrics)


Alle Liedtexte in einer einzigen txt-Datei speichern: python clean.py > data/clean/lyrics.txt

Ein Lied sieht folgendermaßen aus:


[Songtext zu "Ischgl-Fieber (Husti Husti Heh!)"]

[Intro]
Holla-ladi, jadi-jodi-jäh
Holla-ladi, jodi-jäh
Holla-ladi, jadi-jodi-jäh
Holla-ladi, jodi-jäh

[Strophe 1]
Komm, Baby, gib mia an Zung-Zung-Zungenkuss
Hier in Tirol gibt's koa Sünd', do ist niemals Schluss
Hey Schatz, Dirty Dancing all night long
Ich bin deine Kontaktperson
Paznaun-Mädel, i leck di ob
I hob di lieb bis nei ins Grob
Im Lift zum Greitspitz is's passiert
Du host mi sexy infiziert

[Pre-Refrain]
Hey DJ, leg des Liadl auf
A Jeda hot es eh, husti-husti-heh!
41 Grad, Schatzi, mir wird wurm
Und jetzt steckt ma olle an
...


B. Saubere Tags

Wie im obigen Lied zu sehen ist, fügt Genius manchmal Überschriften am Anfang jedes Abschnitts des Liedes hinzu, die angeben, ob es sich um eine Strophe, einen Refrain, eine Bridge usw. handelt. Genius ist jedoch nicht konsistent bei der Kennzeichnung der verschiedenen Abschnitte. Zum Beispiel verwenden einige Songs [Strophe] und andere [Verse]. Dadurch ist es für das Modell schwieriger, die Verbindung zwischen den verschiedenen Abschnitten zu erkennen. Daher versuchen wir, die verschiedenen Tags mithilfe von Regex-Ersetzungen zu standardisieren.



Importware

# Tags säubern
lyrics = re.sub(
    r"^(\[|\(|).*(Strophe|Stophe|Strofa|Strohe|Schtrofä|Verse|Vers).*(\]|\)|:)",
    "[Strophe]",
    lyrics,
    flags=re.MULTILINE,
)
lyrics = re.sub(
    r"^(\[|\(|).*(Bridge|Brdge|Brugg).*(\]|\)|:)", "[Bridge]", lyrics, flags=re.MULTILINE
)


Wir verwenden viel mehr Regex-Ausdrücke als hier gezeigt werden. In unserem Quellcode finden Sie eine ganze Reihe von Beispielen.


C. Lyrische Überschriften entfernen

Genius fügt manchmal Lyrics zu "Songtitel" an den Anfang eines Songs. Das wollen wir in unseren Trainingsdaten nicht, also verwenden wir auch Regex, um solche Instanzen zu entfernen.

Wir haben nun einen sauberen Datensatz, der im nächsten Schritt für die Feinabstimmung des Modells verwendet werden kann.

... aber warum müssen wir den Datensatz bereinigen?

Rohdaten, die du aus externen Quellen sammelst, sind nicht immer sofort für ein Modell verwendbar. Normalerweise musst du die Daten vorverarbeiten, um sie in ein Standardformat zu bringen, das vom Modell erwartet wird. Die meisten Modelle funktionieren zum Beispiel nur mit realwertigen Eingaben. Außerdem kannst du dem Modell das Lernen mit deinem Datensatz erleichtern, indem du etwas Varianz/Rauschen aus dem Datensatz entfernst, bevor du ihn durch das System leiten.

Durch die Standardisierung der Song-Tags in den obigen Reinigungsschritten konnten wir beispielsweise unser Fachwissen nutzen, um dem Modell das Lernen zu erleichtern, dass [Strophe] und [Vers] oder [Refrain] und [Chorus] sich auf ähnliche Konzepte beziehen. Anstatt zuerst die Verbindung zwischen [Strophe] und [Vers] lernen zu müssen und dann die verschiedenen Verse miteinander zu verbinden, konnte sich das Modell darauf konzentrieren, die Struktur der verschiedenen Verse zu lernen.


Schritt 4: Feinabstimmung des Modells anhand unseres Datensatzes

Da wir nun einen qualitativ hochwertigen Datensatz von Schlagertexten haben, können wir endlich mit der Feinabstimmung unseres Modells beginnen. Für diesen Prozess wenden wir uns an die Bibliothek aitextgen, die auf HuggingFace Transformers, PyTorch und PyTorch-Lightning aufbaut.


from aitextgen importieren aitextgen
von pytorch_lightning.loggers importieren TensorBoardLogger

hf_model = "dbmdz/deutsch-gpt2"

# Modell mit aitextgen laden
ai = aitextgen(model=hf_model, verbose=True)
ai.to_gpu()

out_dir = "ergebnisse/"

ai.train(
    train_data,
    n_gpu=1,
    seed=27,
    num_steps=5000,
    generate_every=100,
    output_dir=out_dir,
    loggers=[TensorBoardLogger(out_dir)],
    freeze_layers=True,
    num_layers_freeze=10, # 12 Schichten im GPT-2 Modell
    line_by_line=False,
    header=False,
)


Abhängig von deinen Feinabstimmungsdaten musst du vielleicht mit den Hyperparametern herumspielen, wie z.B. der Anzahl der Schritte, der Anzahl der einzufrierenden Schichten, usw. Verwende den TensorBoardLogger, um die verschiedenen Experimente zu verfolgen und das Modell zu behalten, das am besten abschneidet.

... aber was ist Feinabstimmung?

Ein Modell von Grund auf nur mit Schlagertexten zu trainieren, ist eine Herausforderung, zumal Deutsch eine komplizierte Sprache mit vielen verschiedenen Syntax- und Grammatikregeln ist. Sie müssen Ihr Modell Milliarden von Beispielen der deutschen Sprache aussetzen, um all diese Regeln zu lernen. Wenn man jedoch einen Datensatz erstellt, der nur aus deutschen Schlagern besteht, erhält man nicht genügend Beispiele, mit denen man arbeiten kann, und die Vielfalt reicht möglicherweise nicht aus, damit das Modell die subtileren Nuancen der Sprache erfassen kann. Glücklicherweise gibt es einen Ansatz, der Transferlernen genannt wird und der bei diesem Problem helfen kann.

Die Idee des Transfer-Lernens besteht darin, dass wir Ihr Modell zunächst auf einem allgemeineren, universell einsetzbaren Datensatz aus einer Vielzahl von Quellen trainieren. In unserem Fall hilft dies dem Sprachmodell, ein solides Grundverständnis der Sprache zu entwickeln. Anhand dieses vorab trainierten Modells können wir es dann durch weiteres Training auf einem aufgabenspezifischeren Datensatz feinabstimmen. Auf diese Weise können wir die Ausgabe so gestalten, dass sie sich auf unseren Bereich konzentriert, ohne dass das zugrunde liegende Verständnis der Sprache verloren geht.

Normalerweise wird dieser Prozess dadurch erreicht, dass die meisten der unteren Schichten des Netzes eingefroren werden und nur die Gewichte in den oberen paar Schichten während der Feinabstimmung angepasst werden. Das Ergebnis ist ein viel leistungsfähigeres Modell, als wenn wir es von Grund auf mit unserem eigenen Datensatz trainieren würden; ganz zu schweigen davon, dass wir viel Zeit und Rechenressourcen sparen.


Schritt 5: Text generieren

Mit unserem fein abgestimmten Modell können wir wieder die aitextgen-Bibliothek zur schnellen und einfachen Texterstellung verwenden.


from aitextgen import aitextgen

out_dir = "results/"

ai = aitextgen(model_folder=out_dir, verbose=True)
# ai = aitextgen(model="dbdmz/german-gpt2", verbose=True) # HuggingFace Model
ai.to_gpu()

prompt = input("Prompt:\n\n[Intro]\n")

output = ai.generate(
    prompt="[Intro]\n" + prompt,
    seed=27,
    # Model params
    n=10,
    min_len=None,
    max_len=256,
    temperature=0.8,
    do_sample=True,
    use_cache=True,
    # Custom model params
    early_stopping=False,    # whether to stop beam search when at least num_beams sentences are finished
    num_beams=1,             # num beams for beam search, 1 = no beam search
    top_k=50,                # num highest probaba tokens to keep for top-k filtering
    top_p=0.95,              # float < 1 if most probable tokens with probs that add up to top_p are kept for generation
    repetition_penalty=1.2,  # penalty for repetition. 1.0 = no penalty
    length_penalty=1.0,      # < 1.0 shorter, > 1.0 longer
    no_repeat_ngram_size=0,  # > 0, all ngrams of that size can only occur once.
    num_beam_groups=1,       # num groups to divide num_beams into to ensure diversity
    diversity_penalty=0.0,   # value subtracted from beamscore if generates token same as any beam from other group
    remove_invalid_values=True,
    # output
    return_as_list=True,
    lstrip=False,
    skip_special_tokens=False,
)

for i, text in enumerate(output):
    print("\n==============")
    print(f"Text: {i}\n\n")
    print(text)

print("\n==============")
print("==============\n")

Mit dem obigen Codeschnipsel können wir Ergebnisse wie das folgende generieren, das viel mehr wie ein echter Song aussieht:


Aufforderung:

[Intro]
Wir stehen an der Bar

Text:

[Intro]
Wir stehen an der Bar, tanzen in der Nacht bis alles rein brennt
Doch dann feiern wir noch lange auf die Party drauf
Und vergessen all den alten Scheiß
Er ist gut und drüber weg
Nur du weißt, wie schön das Leben ist
Ich seh' nur dich, nur dich

(Refrain)
Wie immer freut er sich darauf!
Wenn ich am Boden liege
Bis gestern waren'n wir Freunde
Haben soviel durchgemacht und viel verlor'n
Alles kann man nur so sparen
Das Schlimmste sind wir hier
Alle Sachen hat sie gesehn
Die Achtung vor jedem einzelnenBeat
Verzweifelt sie niemals sich im Kreise drehen
Wenn sie ihre alten Lieder hört
Dann glaub'n sie mit uns zusammen

[Brücke]
Man sagt dir helle Augen
Du siehst aus wie ein Sternenzelt
Dein wunderschöner Mund der mir sagt: "Was soll's?" Wir sehen beides
Ganz einfach und charmant aus

(Refrain)
Wie immer gefreut er sich auf jeden Fall
Wenn ich am Boden lag
Bis heute war'n wir Freunde
Haben viel riskiert und viel verloren
Alles kann man nur so sparen
Das Schlimmste sind wir hier
Alle Dinge sind siegesgewiss


Hinweis: Aufgrund eines Fehlers, den wir im dbmdz/german-gpt-2-Modell gefunden haben, wurde unser Basismodell nicht richtig mit dem EOS-Token trainiert, was bedeutet, dass das Modell nie weiß, wann es aufhören soll, Text zu erzeugen. Aufgrund dieses Problems konnte unser Endprodukt am Ende der viertägigen Discovery-Sitzung jedoch nur entweder nie endende Lieder oder Lieder, die nach Erreichen einer Token-Grenze mitten im Satz abrupt aufhören, produzieren.

... aber wie erzeugt man Text mit Hilfe eines Sprachmodells?

Wie bereits erwähnt, ist die Ausgabe von Sprachmodellen eine Wahrscheinlichkeitsverteilung über die verschiedenen Token im Vokabular. Um Text zu erzeugen, folgen wir einer einfachen Schleife.

In der Schleife wird die Eingabeaufforderung zunächst durch einen Tokenizer geleitet, und die Ausgabe wird dann an das Sprachmodell weitergegeben, was zu einer Wahrscheinlichkeitsverteilung führt. Anschließend wird die Verteilung dekodiert (d. h. das nächste Token ausgewählt) und das neue Token an die Sequenz angehängt. Der Prozess wird so lange wiederholt, bis ein Endkriterium erreicht ist.

Es gibt viele Möglichkeiten, die Wahrscheinlichkeitsverteilung zu entschlüsseln, die von einfach bis sehr komplex reichen. Einige der gängigsten Ansätze sind die folgenden:

  • Gierig. Das nächste Token wird anhand des Argmax der Wahrscheinlichkeitsverteilung ausgewählt (Auswahl des Tokens mit der höchsten Wahrscheinlichkeit). Dies ist der einfachste Ansatz und führt zu einer deterministischen Ausgabe.
  • Balkensuche. Sie behalten eine Reihe von "wahrscheinlichsten" Sequenzen und wählen am Ende diejenige mit der höchsten Wahrscheinlichkeit aus. Dieser Ansatz kann verbessert werden, indem man die Vielfalt der verschiedenen Sequenzen erzwingt. Wie bei der gierigen Suche sind die Ergebnisse auch hier deterministisch.
  • Stichprobenverfahren. Nehmen Sie eine Zufallsstichprobe der Wahrscheinlichkeitsverteilung. Sie können die Wahrscheinlichkeitsverteilung auch mit einem Temperaturparameter formen, um die Verteilung flacher (hohe Temperatur) oder spitzer (niedrige Temperatur) zu machen.
  • Top-K. Zufallsstichprobe der obersten K Wahrscheinlichkeiten in der Verteilung. Macht die Ausgabe besser vorhersehbar, allerdings ist es schwierig, einen Wert K zu wählen, der für jede Verteilung funktioniert.
  • Top-P. Es werden zufällig die Token ausgewählt, deren Wahrscheinlichkeiten sich zu den Top-P%-Wahrscheinlichkeiten in der Verteilung summieren. Dies hilft bei der Lösung der Probleme, die Top-K mit sehr spitzen oder sehr flachen Verteilungen hat.

Außerdem kannst du eine benutzerdefinierte Dekodierungsmethode erstellen, indem du die Wahrscheinlichkeitsverteilung anpassen, um domänenspezifisches Wissen zu kodieren. Einige Anwendungen dieser Methode in SchlagerAI sind im nächsten Abschnitt zu sehen.


Die Zukunft von SchlagerAI

Nachdem wir 4 Tage lang an der Entwicklung von SchlagerAI gearbeitet haben, waren die Ergebnisse recht vielversprechend, aber es ist noch ein weiter Weg bis zur perfekten Künstlichen Intelligenz für das Songwriting. Zu den Verbesserungen gehören die folgenden:

  • Bessere Integration der Songstruktur in die Generierungsmethode. Dank der von Genius bereitgestellten Tags scheint unser Modell die Ideen einer [Strophe] oder eines [Refrains] zu verstehen, aber es gibt noch viel mehr Expertenwissen, das wir ihm zur Verfügung stellen können. So wissen wir zum Beispiel, dass ein [Pre-Refrain] immer vor einem [Refrain] stehen sollte oder dass ein [Refrain] in der Regel mehrfach mit ähnlichen Texten auftaucht.
  • Reim und Metrum. Um musikalisch zu passen, folgen die verschiedenen Zeilen eines Liedes normalerweise einer Art Metrum/Silbenstruktur. Es gibt auch Reimschemata, um das Lied besser zusammenfließen zu lassen. Wir können dieses Wissen in unsere Generierungsmethode einfließen lassen, indem wir die Wahrscheinlichkeiten von Token anpassen, wenn sie in die vordefinierten Strukturen des Liedes passen. Ein Beispiel für diesen Ansatz finden Sie unter https://github.com/summerstay/true_poetry.
  • Themen setzen. Wie bereits in der Einleitung erwähnt, folgt die Schlagermusik normalerweise bestimmten Themen. Wir können dazu beitragen, die Generierungsausgabe in diese Richtungen zu lenken, indem wir die Schlüsselwortgenerierung integrieren, ein Beispiel dafür finden Sie unter https://github.com/minimaxir/gpt-2-keyword-generation.  
  • Integration des Zeitgeschehens. Schlager nehmen in ihren Texten manchmal Bezug auf aktuelle Ereignisse. Unsere Modelle werden auf einem statischen, nicht so aktuellen Datensatz trainiert, d.h. sie haben keine Kenntnis von aktuellen Ereignissen. Facebook AI hat kürzlich BlenderBot 2.0 angekündigt, der Informationen aus aktuellen Ereignissen/Internetsuchen in den Textgenerierungsprozess integrieren kann. Es könnte möglich sein, einige Ideen aus dieser und ähnlicher Forschung zu übernehmen, um die generierten Texte aktueller zu gestalten.

Du kannst den Code in unserem GitHub-Repository finden, wenn du einen tieferen Einblick in die Entwicklung von SchlagerAI erhalten möchtest.

Wenn du diesen ausführlichen Artikel über SchlagerAI interessant fandest, dann sehe dir den aufgezeichneten Clip der Live-Präsentation von SchlagerAI auf unserer letzten Discovery Conference an!


Bereit durchzustarten?

Lass uns austauschen und gemeinsam ein Projekt beginnen.

Arbeiten in einem Technologieunternehmen | Motius