[PYTHON] Machen Sie einen idolartigen Tweet mit Keras LSTM (Satzgenerierung)

Artikelinhalt

Ich war an der automatischen Erzeugung von Sätzen mit KI interessiert, also habe ich versucht, Sätze mit Keras zu erzeugen. Was ich tat, war, die Tweets der Idolgruppe zu bekommen, sie lernen zu lassen und Sätze zu bilden.

Referenz

Ich habe auf diesen Artikel verwiesen.

Versuchen Sie, mit Keras LSTM schnell Sätze zu generieren

Der Code ist im Grunde der gleiche, aber ich werde eine Notiz von Teilen hinterlassen, die allein in diesem Artikel etwas schwer zu verstehen waren.

Versuche einen Tweet zu machen

Erfassung von Trainingsdaten

Erstens ist die Erfassung von Trainingsdaten.

import json
import config
from requests_oauthlib import OAuth1Session
from time import sleep
import re
import emoji
from mongo_dao import MongoDAO

# Diesmal nicht verwendet
# Piktogramme entfernen
def remove_emoji(src_str):
    return ''.join(c for c in src_str if c not in emoji.UNICODE_EMOJI)

# API-Schlüsseleinstellung (definiert in einer anderen Datei config.py)
CK = config.CONSUMER_KEY
CS = config.CONSUMER_SECRET
AT = config.ACCESS_TOKEN
ATS = config.ACCESS_TOKEN_SECRET

# Authentifizierungsprozess
twitter = OAuth1Session(CK, CS, AT, ATS)  

# Endpunkt der Zeitleistenerfassung
url = "https://api.twitter.com/1.1/statuses/user_timeline.json"  

# Erwerbskonto
necopla_menber = ['@yukino__NECOPLA', '@yurinaNECOPLA', '@riku_NECOPLA', '@miiNECOPLA', '@kaori_NECOPLA', '@sakuraNECOPLA', '@miriNECOPLA', '@renaNECOPLA']

# Parameterdefinition
params = {'q': '-filter:retweets',
 'max_id': 0, #ID, um zu beginnen
          'count': 200}

 arg1:DB Name
 arg2:Collection Name
mongo = MongoDAO("db", "necopla_tweets")
mongo.delete_many({})

regex_twitter_account = '@[0-9a-zA-Z_]+'

for menber in necopla_menber:
    print(menber)
 del params ['max_id'] # ID löschen, um die Erfassung zu starten
 # Holen Sie sich die letzten 200 Tweets / Holen Sie sich Tweets, die älter als die in params ['max_id'] festgelegte ID sind, ab dem zweiten Mal
    for j in range(100):
        params['screen_name'] = menber
        res = twitter.get(url, params=params)
        if res.status_code == 200:
 #API verbleibende Anzahl
            limit = res.headers['x-rate-limit-remaining']
            print("API remain: " + limit)
            if limit == 1:
                sleep(60*15)
            
            n = 0
            tweets = json.loads(res.text)
 # Verlassen Sie die Schleife, wenn Sie keine Tweets von dem Konto erhalten, das Sie verarbeiten
            if len(tweets) == 0:
                break
 # Per Tweet verarbeiten
            for tweet in tweets:
 # Registrieren Sie die gesamten Tweet-Daten
                if not "RT @" in tweet['text'][0:4]:
                    mongo.insert_one({'tweet':re.sub(regex_twitter_account, '',tweet['text'].split('http')[0]).strip()})
            
                if len(tweets) >= 1:
                    params['max_id'] = tweets[-1]['id']-1

Für die Trainingsdaten in diesem Artikel haben wir Tweets von der Gruppe "// Necopla //" erhalten. Die folgenden Elemente wurden aus den erfassten Tweets gelöscht. ・ Bildlink ・ Konto zum Zeitpunkt der Antwort

Die so zu trainierenden Daten werden in mongoDB abgelegt.

 {"_id": ObjectId ("5e511a2ffac622266fb5801d"), "tweet": "Ich bin zum Karaoke gegangen, um Sololieder zu üben, aber ich habe mir normal die Kehle gebrochen"}
 {"_id": ObjectId ("5e511a2ffac622266fb5801e"), "tweet": "Ich kann immer noch gehen"}

Die Quelle der MongoDB-Operation ist hier

Lerne Tweets

Es ist fast das gleiche wie die Quelle, auf die ich mich bezog.

from __future__ import print_function
from keras.callbacks import LambdaCallback
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.layers import LSTM
from keras.optimizers import RMSprop
from keras.utils.data_utils import get_file
 importiere matplotlib.pyplot als plt # add
import numpy as np
import random
import sys
import io
from mongo_dao import MongoDAO

mongo = MongoDAO("db", "necopla_tweets")
results = mongo.find()

text = ''
for result in results:
    text += result['tweet']

chars = sorted(list(set(text)))
print('total chars:', len(chars))
char_indices = dict((c, i) for i, c in enumerate(chars))
indices_char = dict((i, c) for i, c in enumerate(chars))

 cut the text in semi-redundant sequences of maxlen characters
maxlen = 3
step = 1
sentences = []
next_chars = []
for i in range(0, len(text) - maxlen, step):
    sentences.append(text[i: i + maxlen])
    next_chars.append(text[i + maxlen])
print('nb sequences:', len(sentences))

print('Vectorization...')
x = np.zeros((len(sentences), maxlen, len(chars)), dtype=np.bool)
y = np.zeros((len(sentences), len(chars)), dtype=np.bool)
for i, sentence in enumerate(sentences):
    for t, char in enumerate(sentence):
        x[i, t, char_indices[char]] = 1
    y[i, char_indices[next_chars[i]]] = 1
 
 
 build the model: a single LSTM
print('Build model...')
model = Sequential()
model.add(LSTM(128, input_shape=(maxlen, len(chars))))
model.add(Dense(len(chars)))
model.add(Activation('softmax'))
 
optimizer = RMSprop(lr=0.01)
model.compile(loss='categorical_crossentropy', optimizer=optimizer)
 
 
def sample(preds, temperature=1.0):
    # helper function to sample an index from a probability array
    preds = np.asarray(preds).astype('float64')
    preds = np.log(preds) / temperature
    exp_preds = np.exp(preds)
    preds = exp_preds / np.sum(exp_preds)
    probas = np.random.multinomial(1, preds, 1)
    return np.argmax(probas)
 
# Am Ende der Epoche ausführen
def on_epoch_end(epoch, logs):
    # Function invoked at end of each epoch. Prints generated text.
    print()
    print('----- Generating text after Epoch: %d' % epoch)
     
    # start_index = random.randint(0, len(text) - maxlen - 1)
 # start_index = 0 # Satzgenerierung aus "Alter Mann war alt" jedes Mal
 für Diversity in [0.2]: # Diversity = nur 0.2
        print('----- diversity:', diversity)
 
        generated = ''
        # sentence = text[start_index: start_index + maxlen]
 Satz = 'Morgen'
        generated += sentence
        print('----- Generating with seed: "' + sentence + '"')
        sys.stdout.write(generated)
 
        for i in range(120):
            x_pred = np.zeros((1, maxlen, len(chars)))
            for t, char in enumerate(sentence):
                x_pred[0, t, char_indices[char]] = 1.
 
            preds = model.predict(x_pred, verbose=0)[0]
            next_index = sample(preds, diversity)
            next_char = indices_char[next_index]
 
            generated += next_char
            sentence = sentence[1:] + next_char
 
            sys.stdout.write(next_char)
            sys.stdout.flush()
        print()

# Am Ende des Lernens ausführen
def on_train_end(logs):
    print('----- saving model...')
    model.save_weights("necopla_model" + 'w.hdf5')
    model.save("necopla_model.hdf5")

print_callback = LambdaCallback(on_epoch_end=on_epoch_end,
                                on_train_end=on_train_end)
 
history = model.fit(x, y,
                    batch_size=128,
                    epochs=5,
                    callbacks=[print_callback])
 
 Plot Training loss & Validation Loss
loss = history.history["loss"]
epochs = range(1, len(loss) + 1)
plt.plot(epochs, loss, "bo", label = "Training loss" )
plt.title("Training loss")
plt.legend()
plt.savefig("loss.png ")
plt.close()

Die Änderungen sind wie folgt.

Der erste Punkt ist, dass ich den Schmerz sah, dass die Trainingsdaten, die über einen ganzen Tag verschoben wurden, nicht gespeichert wurden, also habe ich einen Speicherprozess hinzugefügt. Der zweite Punkt war das Lernen mit 8 Zeichen, und als ich aus den Lerndaten einen Satz vorhersagte, der mit einem 3-stelligen Wort wie "Morgen" begann, funktionierte dies nicht gut. Seit ich Tweets gemacht habe, habe ich gelernt, mit kurzen Worten zu beginnen.

Der Lernprozess sieht so aus.

Epoch 1/5
663305/663305 [==============================] - 401s 605us/step - loss: 3.5554

----- Generating text after Epoch: 0
----- diversity: 0.2
 ----- Mit Samen erzeugen: "Morgen"
 Morgen! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !!
 Ich freue mich darauf, mit Dir zu arbeiten! !! !!

 "Nekopura // Nekopura
# Nekopura
# Nekopura // Nekopura // Nekopura // Nekopura // Nekopura
# Nekopura
# Nekopura // Ich bevorzuge Nekopura
Epoch 2/5
663305/663305 [==============================] - 459s 693us/step - loss: 3.2893

----- Generating text after Epoch: 1
----- diversity: 0.2
 ----- Mit Samen erzeugen: "Morgen"
 Morgen hier! !!

# Es ist eine Live-Aufführung von Nekopura!

# Es gibt eine Live-Aufführung von Nekopla! !!

# Vielen Dank für Nekopura! !! !!

# Vielen Dank für alle Informationen über Nekopura! !!

# Ich würde mich freuen, wenn es ein Katzenplastik gäbe ...

# Katze
Epoch 3/5
663305/663305 [==============================] - 492s 742us/step - loss: 3.2109

----- Generating text after Epoch: 2
----- diversity: 0.2
 ----- Mit Samen erzeugen: "Morgen"
 Morgen hier! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Epoch 4/5
663305/663305 [==============================] - 501s 755us/step - loss: 3.1692

----- Generating text after Epoch: 3
----- diversity: 0.2
 ----- Mit Samen erzeugen: "Morgen"
 Morgen hier! !!






# Nekopura
# Nekopura
# Ich bin froh, dass du zu den Katzenplastikleuten gekommen bist! !!



# Nekopura
# Nekopura
# Über Nekopura Mehr Mehr Mehr Mehr Mehr Mehr Mehr Mehr Mehr Mehr Mehr Mehr Mehr
Epoch 5/5
663305/663305 [==============================] - 490s 739us/step - loss: 3.1407

----- Generating text after Epoch: 4
----- diversity: 0.2
 ----- Mit Samen erzeugen: "Morgen"
 Komm morgen zu mir! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Zusätzliches Lernen

Weiterbildung mit den gespeicherten Trainingsdaten Laden Sie einfach die Trainingsdaten, die nach dem Erstellen des Modells gespeichert wurden.

Der Code lautet hier

print('Build model...')
model = Sequential()
model.add(LSTM(128, input_shape=(maxlen, len(chars))))
model.add(Dense(len(chars)))
model.add(Activation('softmax'))
 
optimizer = RMSprop(lr=0.01)
model.compile(loss='categorical_crossentropy', optimizer=optimizer)
model.load_weights("necopla_modelw.hdf5")

Machen Sie einen Tweet mit den gelernten Daten

Als ich diesen Prozess durchführte, dachte ich über die Bedeutung jedes Codes nach. (langsam··.) Der Prozess von "on_epoch_end" wird am Ende der Lernepoche aufgerufen, aber hier werden zum Zeitpunkt des Epochenendes Sätze unter Verwendung der Lerndaten zu diesem Zeitpunkt erstellt. Daher können Sie beim Erstellen eines Tweets diesen Prozess grundsätzlich nachahmen.

Der Code lautet hier

def evaluate_tweet():
 für Diversity in [0.2]: # Diversity = nur 0.2
        print('----- diversity:', diversity)
 
        generated = ''
 Satz = 'Morgen'
        generated += sentence
        print('----- Generating with seed: "' + sentence + '"')

        sameCharCount = 0
        for i in range(120):
            x_pred = np.zeros((1, maxlen, len(chars)))

            for t, char in enumerate(sentence):
                x_pred[0, t, char_indices[char]] = 1.

            preds = model.predict(x_pred, verbose=0)[0]
            next_index = sample(preds, diversity)
            next_char = indices_char[next_index]

            if next_char == generated[-1]:
                sameCharCount += 1
                if sameCharCount >= 3: 
                    continue
            elif sameCharCount != 0:
                sameCharCount = 0
            generated += next_char
            sentence = sentence[1:] + next_char

    return generated

for i in range(10):
    tweet = evaluate_tweet()
 print ('----------------' + str (i + 1) + 'th time ----------------')
    print(tweet)

Wenn beim Erstellen eines Tweet-Satzes dasselbe Zeichen für 3 oder mehr Zeichen fortgesetzt wird, werden die Zeichen nicht verbunden. Tweets werden mit Sätzen erstellt, die mit den Worten "Tomorrow is" beginnen.

Das Ausgabeergebnis sieht folgendermaßen aus.

 ---------------- Erstes Mal ----------------
 Morgen hier! !! !!
 ---------------- Zweites Mal ----------------
 Morgen hier! !! !!
 ---------------- Drittes Mal ----------------
 Ich frage mich, ob wir uns morgen treffen können! !! !!
 ---------------- 4. ----------------
 Morgen hier! !! !!
 ---------------- 5. Mal ----------------
 Morgen hier! !! !!
 ---------------- 6. Mal ----------------
 Morgen hier! !! !!
 ---------------- 7. Mal ----------------
 Morgen hier! !! !!
 ---------------- 8. Mal ----------------
 Morgen hier! !! !!
 ---------------- 9. Mal ----------------
 Morgen hier! !! !!
 ---------------- 10. Mal ----------------
 Morgen hier! !! !!

Irgendwie konnte ich so etwas schaffen.

Impressionen

Ich habe das gleiche mit Chainer gemacht, aber mit Keras ist es definitiv immer einfacher. Das Ausgabeergebnis ist ein kurzer Satz, da die Anzahl der Lernvorgänge gering ist. Daher werde ich versuchen, das Ergebnis zu sehen, während ich zusätzliches Lernen durchführe.

Ich denke, dass die Lernmethode anders sein wird, wenn es sich um eine Methode des Lernens durch Teilen handelt, also werde ich das auch versuchen.

Recommended Posts

Machen Sie einen idolartigen Tweet mit Keras LSTM (Satzgenerierung)
Satzerzeugung mit GRU (Keras)
Multivariates LSTM mit Keras
Erstellen Sie eine Umgebung mit virtualenv
Erstellen Sie eine API mit Django
Implementieren Sie Keras LSTM Feed Forward mit Numpy
Anfänger RNN (LSTM) | Versuchen Sie es mit Keras
Erstellen Sie eine Altersgruppe mit Pandas
Ich habe versucht, Sätze mit GPT-2 zu generieren
Erstellen Sie eine Anwendung, indem Sie mit Pygame klassifizieren
Erstellen Sie mit python3 eine Wortwolke aus Ihrem Tweet
Erstellen Sie mit PySimpleGUI einen Bildverarbeitungs-Viewer
Erstellen Sie schnell eine Excel-Datei mit Python #python
Erstellen Sie mit Django Updateview einen Update-Bildschirm
[Python] Erstellen Sie schnell eine API mit Flask
Generieren Sie eine add-in-fähige Excel-Instanz mit xlwings
Erstellen Sie eine englische Wort-App mit Python
Erstellen Sie mit cx_Freeze eine aktualisierbare MSI-Datei
Erstellen Sie eine App, die Schüler mit Python errät
Erstellen Sie ein akademisches Programm mit Kombinationsoptimierung
Erstellen Sie eine Bildkompositions-App mit Flask + Pillow
Erstellen Sie ein Bild mit Zeichen mit Python (Japanisch)
Erstellen Sie schnell einen API-Server mit Python + Falcon