[PYTHON] Eine einjährige Geschichte des Betriebs eines Chatbots

Dieser Artikel ist der 7. Tag von My Navi Advent Calendar 2019!

Normalerweise beschäftige ich mich mit Big Data und KI und bin hauptsächlich auf die Verarbeitung natürlicher Sprache spezialisiert. Dieses Mal werde ich viel Zeit damit verbringen, über das Spielen mit dem Chatbot zu sprechen, der in der Firma Slack entfesselt ist.

Überblick

Ein Bot mit hoher Fanning-Leistung läuft unter AWS. Manchmal bekomme ich von meinem Senior bei der Arbeit einen Injektionsangriff, aber mir geht es gut. Ich bedauere, dass es besser gewesen wäre, eine einzelne Cloud anstelle einer Multi-Cloud zu haben.

Unten sehen Sie ein Bild davon, wie Sie tatsächlich mit dem Chatbot spielen.

スクリーンショット 2019-12-04 11.59.38.png

Hmmm, was für ein Gesicht für meine Eltern ...

Einführung

Hintergrund wollte ich erstellen

Alle Menschen leben mit dem Wunsch, Chatbots zu machen. Zumindest bin ich es, also bin ich mir sicher, dass es andere sind. In der Zwischenzeit wurde weltweit ein Artikel über Microsofts Highschool-Mädchen AI "Rinna" veröffentlicht (2016).

süß

Ich muss das machen ... (2 Jahre sind vergangen)

Über Slack

Ich benutze Slack als mein Hauptkommunikationswerkzeug. Allein auf dem öffentlichen Kanal waren 677. Ich bin mir nicht sicher, ob es mehr oder weniger ist: Denken:

Da die Kultur der Zeit verwurzelt ist, besteht der Zweck dieses Chatbots darin, ihn zu meiner eigenen Zeit zu betreiben und "alle zum Lächeln zu bringen". Das Gebet, dass ich ein solcher Dialogbot werde, ist enthalten. Ich war da. Der Name ist übrigens "Natsu-chan", weil es im Sommer veröffentlicht wurde. Jedes Mal, wenn die Version veröffentlicht wird, wird die Saison zu diesem Zeitpunkt benannt.

Die verwendete Slack-API ist die Ereignis-API (https://api.slack.com/events-api). Ich vergesse nicht, die Berechtigungen auf API-Aufrufe nur zu beschränken, wenn dies erwähnt wird.

Ergebnisse

Chatbot-Konfigurationsdiagramm

Ich habe es schnell geschafft.

Das Konfigurationsdiagramm des Chatbots ist unten dargestellt.

春ちゃん構成図_2 (2).png

Eigentlich habe ich mein Bestes gegeben.

Zuerst gab ich einem einzelnen EC2 eine elastische IP, speicherte die Sitzung mit dem Befehl Screen und verknüpfte sie mit Slack. Es gab jedoch die Ankündigung eines Gottes, dass "es keinen Wert hat, AWS zu verwenden", und ich dachte, dass dies der Fall ist, und ich hatte viel Spaß damit.

Systemkonfigurationsprobleme

Ich werde die Probleme der aktuellen Konfiguration auf meine eigene Weise auflisten.

Über den Chatbot-Algorithmus

Dieses Mal habe ich es mit Seq2Seq + Attention + Satz implementiert. Die spezifische Technologiegruppe ist unten dargestellt.

Artikel Inhalt
Lernalgorithmus Seq2Seq (4-Schicht-LSTM)+ Global Attention
Tokenizer Sentencepiece
Vorlernen Word2Vec
Optimierungsmethode Adam
Trainingsdaten Dialogfehlerkorpus+Alte Bezeichnung+Gesprächsprotokoll bei Slack
Bibliothek verwendet Chainer

Wir verwenden Word2Vec, um Wortvektoren aus einem Lernkorpus zu lernen, der von Satzstück als Vorlernen markiert wurde. Der gelernte Wortvektor wurde als Anfangswert für die Worteinbettung von Codierer und Decodierer verwendet.

Unten ist der Teil __init__.

def __init__(self, vocab_size, embed_size, hidden_size, eos, w=None, ignore_label=-1):
    super(Seq2Seq, self).__init__()

    self.unk = ignore_label
    self.eos = eos

    with self.init_scope():

        # Embedding Layer
        self.x_embed = L.EmbedID(vocab_size, embed_size, initialW=w, ignore_label=ignore_label)
        self.y_embed = L.EmbedID(vocab_size, embed_size, initialW=w, ignore_label=ignore_label)
        # 4-Layer LSTM
        self.encoder = L.NStepLSTM(n_layers=4, in_size=embed_size, out_size=hidden_size, dropout=0.1)
        self.decoder = L.NStepLSTM(n_layers=4, in_size=embed_size, out_size=hidden_size, dropout=0.1)

        # Attention Layer
        self.attention = L.Linear(2*hidden_size, hidden_size)

        # Output Layer
        self.y = L.Linear(hidden_size, vocab_size)

Seq2Seq ist ein Serienkonvertierungsmodell, das Encoder-Decoder verwendet. In der Originalarbeit wurde dies in maschineller Übersetzung (englisch-französische Übersetzungsaufgabe) angekündigt, aber die Konvertierung einer Eingabezeichenfolge in eine Ausgabezeichenfolge kann auch im Dialog verwendet werden! Das ist die Anerkennung, die auch im Dialog Bot verwendet wird.

Die Trainingsdaten sind ein Satz von Eingabesätzen und Ausgabesätzen wie folgt.

Eingabeanweisung:Es macht wirklich Spaß, mit Ihnen zu sprechen. Möchten Sie ins Wohnzimmer gehen und reden?
Ausgabeanweisung:Ich habe heute etwas zu tun, also werde ich frei sein.

Die Antworten, die aus dem trainierten Modell erhalten werden, sind wie eine Frage-und-Antwort-Formel, ohne den Gesprächsfluss überhaupt zu berücksichtigen. Manchmal scheint das Gespräch fortgesetzt worden zu sein, aber es geht einfach weiter und wird überhaupt nicht als Modell angesehen.

Das Folgende ist der Teil call`.

def __call__(self, x, y):

    """

    :param x:Mini-Batch-Eingabedaten
    :param y:Mini-Batch-Ausgabe entsprechend den Eingabedaten
    :return:Fehler und Genauigkeit
    """

    batch_size = len(x)
    eos = self.xp.array([self.eos], dtype='int32')

    #EOS-Signal einbetten
    y_in = [F.concat((eos, tmp), axis=0) for tmp in y]
    y_out = [F.concat((tmp, eos), axis=0) for tmp in y]

    # Embedding Layer
    emb_x = sequence_embed(self.x_embed, x)
    emb_y = sequence_embed(self.y_embed, y_in)

    # Encoder,Eingabe in den Decoder
    h, c, a = self.encoder(None, None, emb_x)  # h => hidden, c => cell, a => output(Attention)
    _, _, dec_hs = self.decoder(h, c, emb_y)  # dec_hs=> output

    #Concat-Ausgabe des Batch-Size-Decoders
    dec_h = chainer.functions.concat(dec_hs, axis=0)
    
    #Aufmerksamkeitsberechnung
    attention = chainer.functions.concat(a, axis=0)
    o = self.global_attention_layer(dec_h, attention)

    t = chainer.functions.concat(y_out, axis=0)

    loss = F.softmax_cross_entropy(o, t)  #Fehlerberechnung
    accuracy = F.accuracy(o, t)  #Genauigkeitsberechnung

    return loss, accuracy

Die Strahlensuche wird zur Inferenz verwendet. Die Strahlbreite beträgt 3. Die maximale Wortlänge beträgt 50.

Für diese Implementierungen habe ich unten auf @ nojimas Blog verwiesen. Es war eine große Hilfe. Vielen Dank! https://nojima.hatenablog.com/entry/2017/10/10/023147

Das Lernen verwendet Google Colaboratory. https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja

Schwierigkeiten

Implementierung auf der API-Seite

Es wird von Flask + uWSGI implementiert. Bei der Arbeit mit der Ereignis-API tritt von der Slack-Seite eine "Herausforderung" auf. https://api.slack.com/events-api#subscriptions

Insbesondere wird der folgende POST am Endpunkt ausgelöst. Wenn Sie den Wert dieser "Herausforderung" so wie er ist zurückgeben, ist die Herausforderung erfolgreich. Danach ist es möglich, gemäß den festgelegten Slack-API-Einstellungen eine Verknüpfung mit Slack herzustellen. Beachten Sie, dass Slack bei einem Fehlschlagen der Challenge nicht auf den API-Endpunkt POST.


{
    "token": "Slack API Token",
    "challenge": "3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P",
    "type": "url_verification"
}

Berechtigungseinstellungen können unter "Abonnieren von Bot-Ereignissen" unter "Ereignisabonnements" festgelegt werden. Ich habe "app_mention" als Ereignis hinzugefügt. Dies ist ein Ereignis, bei dem POSTs Daten an den konfigurierten Endpunkt senden, wenn dies auf dem Kanal erwähnt wird, der den Bot eingeführt hat.

2019-12-06 23.05.48 api.slack.com 8cfe665a832f.png

Unter "Bot-Ereignisse abonnieren" befindet sich "Arbeitsbereich-Ereignisse abonnieren". Diese Einstellung wird als Ereignis für den gesamten Arbeitsbereich angewendet. Bitte beachten Sie, dass es schwierig sein wird.

API-Herausforderungen

Die Probleme auf der API-Seite sind wie folgt.

Reaktion nach der Freisetzung

Ich war froh, dass sie innerhalb der Zeiten positiv aufgenommen wurden. Aus irgendeinem Grund interagiere ich mehr als einmal pro Woche mit Bot (einschließlich mir selbst).

Manchmal höre ich Hündinnen, manchmal bekomme ich Injektionsattacken und manchmal bekomme ich "starke" Worte. Wenn ich an die Ingenieure hinter dem Chatbot denke, kann ich den Chatbot nicht mehr stark treffen. Es tut mir leid, Siri. Es tut mir leid, Cortana. Es tut mir leid, Kyle.

Es war ein Jahr, in dem mir klar wurde, dass es viele Dinge gibt, die ich zum ersten Mal verstehen kann, nachdem ich sie gemacht habe.

Am Ende

スクリーンショット 2019-12-05 15.17.11.png

:innocent:

Verknüpfung

Recommended Posts

Eine einjährige Geschichte des Betriebs eines Chatbots
Eine grobe Zusammenfassung der Geschichte des Betriebssystems
Summe der Variablen in einem mathematischen Modell
Zeichnen Sie in Python ein Diagramm einer quadratischen Funktion
Kopieren Sie die Liste in Python
Finden Sie die Anzahl der Tage in einem Monat
Umschreiben von Elementen in einer Listenschleife (Python)
Machen Sie mit Python eine Joyplot-ähnliche Handlung von R.
Lassen Sie uns einen Teil des maschinellen Lernens mit Python berühren
Aufgezeichnete Umgebung für die Datenanalyse mit Python
Ableitung der Wirkungssicherheit im A / B-Test