5 Pluspunkte 0 Minuspunkte
Wie kann ich ein Model mit Tensorflow und Python erstellen dem ich verschiedene Texte zum trainieren geben kann und das anhand dessen lernt lernt selbst Text zu generieren? Also im Prinzip so wie ChatGPT. Ich weiss das man dazu starke Hardware und Unmengen an Texten braucht, ich möchte aber nur das Konzept verstehen, auch wenn es keine besonders sinnvollen Texte sind.
von  

1 Antwort

4 Pluspunkte 0 Minuspunkte

Mit dem Keras Tokenizer teilst du den Text in einzelne Wörter oder Token und erstellst eine Zuordnung von Wörtern zu einem numerischen Index.

text = "..."

tokenizer = keras.preprocessing.text.Tokenizer()
tokenizer.fit_on_texts([text])
word_index = len(tokenizer.word_index) + 1

Danach erstellst du N-Gramm Sequenzen für jeden Satz oder jede Zeile in deinem Text. "N-Gramm-Sequenzen erstellen" bedeutet, dass du für jeden Satz im Text alle möglichen aufeinanderfolgenden Teilsequenzen von Wörtern erstellst. Angenommen, du hast den folgenden Satz: 

"Das ist ein Beispieltext für Erklärungen."

Um Bigramme zu erstellen, würdest du den Satz in aufeinanderfolgende Paare von Wörtern aufteilen:      

  • "Das ist"
  • "ist ein"
  • "ein Beispieltext"
  • "Beispieltext für"
  • "für Erklärungen"  

Um Trigramme zu erstellen, würdest du den Satz in aufeinanderfolgende Gruppen von drei Wörtern aufteilen:      

  • "Das ist ein"
  • "ist ein Beispieltext"
  • "ein Beispieltext für"
  • "Beispieltext für Erklärungen"  

Dieser Prozess wird für jeden Satz im Text durchgeführt.

input_sequences = []
for line in text.split("\n"):
    token_list = tokenizer.texts_to_sequences([line])[0]
    for i in range(1, len(token_list)):
        n_gram_sequence = token_list[:i+1]
        input_sequences.append(n_gram_sequence)

Die Eingabesequenzen werden auf die maximale Sequenzlänge gepolstert, um ein einheitliches Format zu erhalten.

max_sequence_len = max([len(x) for x in input_sequences])
input_sequences = keras.preprocessing.sequence.pad_sequences(input_sequences, maxlen=max_sequence_len, padding='pre')

Jetzt werden die Eingabesequenzen für das Modell vorbereitet. input_sequences enthält die vorbereiteten N-Gramm Sequenzen, die als Eingabe für das Modell verwendet werden. Die Dimension dieser Sequenzen ist (Anzahl der Sequenzen, maximale Sequenzlänge). Es werden alle Spalten bis auf die letzte in den Sequenzen ausgewählt. Das bedeutet, dass für jede Sequenz nur die ersten Wörter bis zum vorletzten Wort ausgewählt werden. Das entspricht der Eingabe, die das Modell verwendet, um vorherzusagen, welches Wort als nächstes in der Sequenz kommt.

xs = input_sequences[:, :-1]

Ausserdem werden Zielkategorien (Labels) für das Modell erstellt. input_sequences enthält die vorbereiteten N-Gramm-Sequenzen, und die letzten Wörter jeder Sequenz werden ausgewählt. Diese letzten Wörter dienen als Ziel, das das Modell vorhersagen soll. Das Modell soll also anhand der vorhergehenden Wörter das nächste Wort vorhersagen.

labels = input_sequences[:, -1]

Die Zielkategorien (Labels) müssen in ein kategorisches Format umgewandelt. Das bedeutet, dass jedes Label in eine Binärdarstellung umgewandelt wird, in der das Label mit einer Eins und alle anderen Klassen mit Nullen dargestellt werden. Das Ergebnis ist eine Matrix, in der jede Zeile eine kategorische Darstellung des entsprechenden Labels ist.

ys = tf.keras.utils.to_categorical(labels, num_classes=word_index)

Das Modell wird erstellt. Es besteht aus mehreren Schichten: eine Embedding-Schicht, zwei LSTM-Schichten (eine Bidirectional und eine normale), eine Dropout-Schicht und eine Dense-Schicht mit Softmax-Aktivierungsfunktion.

model = keras.models.Sequential()
model.add(layers.Embedding(word_index, 100, input_length=max_sequence_len-1))
model.add(layers.Bidirectional(layers.LSTM(150, return_sequences=True)))
model.add(layers.Dropout(0.2))
model.add(layers.LSTM(100))
model.add(layers.Dense(word_index, activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(xs, ys, epochs=150, verbose=1)

Und natürlich noch ein Beispiel um Text zu generieren.

seed_text = "Alice and the bunny"
seed_text.encode(encoding = 'UTF-8')
next_words = 50

for _ in range(next_words):
    token_list = tokenizer.texts_to_sequences([seed_text])[0]
    token_list = keras.preprocessing.sequence.pad_sequences([token_list], maxlen=max_sequence_len-1, padding='pre')
    predicted = model.predict(token_list, verbose=0)
    predicted_word_index = tf.argmax(predicted, axis=-1).numpy()[0]
    output_word = ""
    for word, index in tokenizer.word_index.items():
        if index == predicted_word_index:
            output_word = word
            break
    seed_text += " " + output_word

print(seed_text)
von (716 Punkte)